Вступление
В первой части руководства мы узнали, как установить Devise и настроить его в нашем приложении Rails. В этой части мы рассмотрим, как интегрировать DeviseInvitable.
DeviseInvitable — это расширение, которое работает с Devise. С DeviseInvitable в вашем приложении ваши пользователи могут приглашать своих друзей по электронной почте. Это отличная возможность для включения в ваше приложение, если вы создаете приложение для совместной работы.
Настройка DeviseInvitable
Откройте свой Gemfile и добавьте его:
|
1
2
3
|
#Gemfile
…
gem ‘devise_invitable’
|
Запустите команду для установки bundle install .
Запустите команду генератора, чтобы добавить опцию конфигурации DeviseInvitable в файл конфигурации Devise.
|
1
|
rails generate devise_invitable:install
|
Вы можете увидеть новые изменения, проверив config/initializers/devise.rb вашем текстовом редакторе.
Далее, давайте добавим DeviseInvitable к нашей модели User .
|
1
|
rails generate devise_invitable User
|
Это добавит флаг :invitable к вашей модели, поэтому ваша модель User будет выглядеть так:
|
1
2
3
4
5
6
7
8
|
#app/models/user.rb
class User < ActiveRecord::Base
# Include default devise modules.
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :invitable, :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
|
Выполнение вышеуказанной команды также сгенерировало файл миграции, который выглядит так, как показано ниже:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
class DeviseInvitableAddToUsers < ActiveRecord::Migration
def up
change_table :users do |t|
t.string :invitation_token
t.datetime :invitation_created_at
t.datetime :invitation_sent_at
t.datetime :invitation_accepted_at
t.integer :invitation_limit
t.references :invited_by, polymorphic: true
t.integer :invitations_count, default: 0
t.index :invitations_count
t.index :invitation_token, unique: true # for invitable
t.index :invited_by_id
end
end
def down
change_table :users do |t|
t.remove_references :invited_by, polymorphic: true
t.remove :invitations_count, :invitation_limit, :invitation_sent_at, :invitation_accepted_at, :invitation_token, :invitation_created_at
end
end
end
|
Теперь перенесите вашу базу данных, запустив rake db:migrate .
Конфигурирование контроллера для DeviseInvitable
DeviseInvitable необходимо передать некоторые параметры при отправке приглашения. Чтобы это работало, нам нужно внести в белый список необходимый параметр, который будет использоваться. Используя ваш текстовый редактор, перейдите в app/controllers/application_controller.rb и сделайте так, как показано ниже:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
added_attrs = [:username, :email, :password, :password_confirmation, :remember_me]
devise_parameter_sanitizer.permit :sign_up, keys: added_attrs
devise_parameter_sanitizer.permit :account_update, keys: added_attrs
devise_parameter_sanitizer.permit :accept_invitation, keys: [:email]
end
end
|
Из вышесказанного видно, что :email была добавлена в белый список для DeviseInvitable.
Теперь давайте посмотрим, что мы имеем через нашу консоль. На вашем терминале запустите rails console и введите то, что у вас ниже.
|
1
|
[1] pry(main)> User.invite!(:email => «johndoe@example.com»)
|
Он должен произвести вывод, который выглядит так, как у меня ниже, хотя будут различия.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
[2] pry(main)> User Load (78.3ms) SELECT «users».* FROM «users» WHERE «users».»email» = ?
User Load (0.2ms) SELECT «users».* FROM «users» WHERE «users».»invitation_token» = ?
(0.1ms) begin transaction
SQL (67.8ms) INSERT INTO «users» («email», «encrypted_password», «invitation_token», «invitation_created_at», «invitation_sent_at», «created_at», «updated_at») VALUES (?, ?, ?, ?, ?, ?, ?) [[«email», «johndoe@example.com»], [«encrypted_password», «$2a$11$0sLfqvfFDsebcmcQTUXzlOuqNIooL5z8niXeza8OUwNK3gZY/iRum»], [«invitation_token», «658da470d5fcbb2275f30bc1fb66f5771b889cec2f1e56f536319d2fd1ef4a92»], [«invitation_created_at», «2016-10-07 07:41:51.254047»], [«invitation_sent_at», «2016-10-07 07:41:51.254047»], [«created_at», «2016-10-07 07:41:51.255700»], [«updated_at», «2016-10-07 07:41:51.255700»]]
(220.5ms) commit transaction
Rendered /home/kinsomicrote/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/devise_invitable-1.7.0/app/views/devise/mailer/invitation_instructions.html.erb (2.5ms)
Rendered /home/kinsomicrote/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/devise_invitable-1.7.0/app/views/devise/mailer/invitation_instructions.text.erb (88.0ms)
Devise::Mailer#invitation_instructions: processed outbound mail in 247.1ms
Sent mail to johndoe@example.com (74.3ms)
Date: Fri, 07 Oct 2016 08:41:51 +0100
From: please-change-me-at-config-initializers-devise@example.com
Reply-To: please-change-me-at-config-initializers-devise@example.com
To: johndoe@example.com
Message-ID: <57f751bfce8d6_18022ac6c272b12840661@kinsomicrote-X553MA.mail>
Subject: Invitation instructions
Mime-Version: 1.0
Content-Type: multipart/alternative;
boundary=»—==_mimepart_57f751bfcc725_18022ac6c272b12840524″;
charset=UTF-8
Content-Transfer-Encoding: 7bit
—-==_mimepart_57f751bfcc725_18022ac6c272b12840524
Content-Type: text/plain;
charset=UTF-8
Content-Transfer-Encoding: 7bit
Hello johndoe@example.com
Someone has invited you to https://localhost:3000/, you can accept it through the link below.
http://localhost:3000/users/invitation/accept?invitation_token=xmW9uRfyafptmeFMmFBy
If you don’t want to accept the invitation, please ignore this email.
Your account won’t be created until you access the link above and set your password.
—-==_mimepart_57f751bfcc725_18022ac6c272b12840524
Content-Type: text/html;
charset=UTF-8
Content-Transfer-Encoding: 7bit
<p>Hello johndoe@example.com</p>
<p>Someone has invited you to http://localhost:3000/, you can accept it through the link below.</p>
<p><a href=»http://localhost:3000/users/invitation/accept?invitation_token=xmW9uRfyafptmeFMmFBy»>Accept invitation</a></p>
<p>If you don’t want to accept the invitation, please ignore this email.<br />
Your account won’t be created until you access the link above and set your password.</p>
—-==_mimepart_57f751bfcc725_18022ac6c272b12840524—
=> #<User:0x00558d875fa798
id: 4,
email: «johndoe@example.com»,
encrypted_password: «$2a$11$0sLfqvfFDsebcmcQTUXzlOuqNIooL5z8niXeza8OUwNK3gZY/iRum»,
reset_password_token: nil,
reset_password_sent_at: nil,
remember_created_at: nil,
sign_in_count: 0,
current_sign_in_at: nil,
last_sign_in_at: nil,
current_sign_in_ip: nil,
last_sign_in_ip: nil,
created_at: Fri, 07 Oct 2016 07:41:51 UTC +00:00,
updated_at: Fri, 07 Oct 2016 07:41:51 UTC +00:00,
username: nil,
invitation_token: «658da470d5fcbb2275f30bc1fb66f5771b889cec2f1e56f536319d2fd1ef4a92»,
invitation_created_at: Fri, 07 Oct 2016 07:41:51 UTC +00:00,
invitation_sent_at: Fri, 07 Oct 2016 07:41:51 UTC +00:00,
invitation_accepted_at: nil,
invitation_limit: nil,
invited_by_id: nil,
invited_by_type: nil,
invitations_count: 0>
[3] pry(main)>
|
Это сработало, как и планировалось.
Вы не хотите, чтобы наши пользователи отправляли приглашения через командную строку, поэтому важно, чтобы мы настроили DeviseInvitable для работы с интерфейсом. Делать это очень просто; выполните команду генератора, чтобы сгенерировать представления для DeviseInvitable.
rails generate devise_invitable:views users
Вам также необходимо добавить ссылку где-нибудь в вашем приложении, которая указывает на страницу для отправки приглашений ( app/views/users/invitations/new.html.erb ).
Для этого приложения вы можете пойти дальше и добавить ссылку на ваш файл навигации. Вот как я это сделал:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#app/views/shared/_navigation.html.erb
<nav class=»navbar navbar-inverse»>
<div class=»container»>
<div class=»navbar-header»>
<%= link_to ‘Tutsplus Devise’, root_path, class: ‘navbar-brand’ %>
</div>
<div id=»navbar»>
<ul class=»nav navbar-nav»>
<li><%= link_to ‘Home’, root_path %></li>
</ul>
<ul class=»nav navbar-nav pull-right»>
<% if user_signed_in?
<li class=»dropdown»>
<a class=»dropdown-toggle» data-toggle=»dropdown» href=»#»>
<%= current_user.username %>
<span class=»caret»>
</a>
<ul class=»dropdown-menu» role=»menu»>
<li><%= link_to ‘Invite’, new_user_invitation_path %></li>
<li><%= link_to ‘Profile’, edit_user_registration_path %></li>
<li><%= link_to ‘Log out’, destroy_user_session_path, method: :delete %></li>
</ul>
</li>
<% else %>
<li><%= link_to ‘Log In’, new_user_session_path %></li>
<li><%= link_to ‘Sign Up’, new_user_registration_path %></li>
<% end %>
</ul>
</div>
</div>
</nav>
|
Чтобы увидеть маршруты, предоставляемые DeviseInvitable, выполните команду rake routes | invit route rake routes | invit rake routes | invit Вот как будет выглядеть вывод.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
cancel_user_registration GET /users/cancel(.:format) devise_invitable/registrations#cancel
user_registration POST /users(.:format) devise_invitable/registrations#create
new_user_registration GET /users/sign_up(.:format) devise_invitable/registrations#new
edit_user_registration GET /users/edit(.:format) devise_invitable/registrations#edit
PATCH /users(.:format) devise_invitable/registrations#update
PUT /users(.:format) devise_invitable/registrations#update
DELETE /users(.:format) devise_invitable/registrations#destroy
accept_user_invitation GET /users/invitation/accept(.:format) devise/invitations#edit
remove_user_invitation GET /users/invitation/remove(.:format) devise/invitations#destroy
user_invitation POST /users/invitation(.:format) devise/invitations#create
new_user_invitation GET /users/invitation/new(.:format) devise/invitations#new
PATCH /users/invitation(.:format) devise/invitations#update
PUT /users/invitation(.:format) devise/invitations#update
|
Давайте посмотрим, что мы имеем в данный момент. Запустите команду для запуска вашего сервера; rails server .
Укажите в браузере http://localhost:3000/users/invitation/new . Введите адрес электронной почты в показанной форме и нажмите на кнопку. Это должно работать! Если вы зайдете в журналы вашего сервера, вы должны увидеть выходные данные, которые были созданы при отправке приглашения. В выводе вы увидите ссылку для принятия приглашения.
Вы согласитесь со мной, что будет лучше, если вы сможете просмотреть письмо, отправленное в вашем браузере. Давайте посмотрим, как заставить это работать.
Интеграция Letter_Opener
Letter Opener позволяет просматривать сообщения электронной почты в браузере по умолчанию. При этом вам не нужно настраивать систему доставки почты при работе в среде разработки.
Откройте свой Gemfile и добавьте камень ниже:
gem 'letter_opener'
Запустите bundle install .
Используя ваш текстовый редактор, перейдите к config/environments/development.rb и добавьте строку ниже.
|
1
2
3
4
|
#config/environments/development.rb
…
config.action_mailer.delivery_method = :letter_opener
end
|
Перезагрузите сервер rails. Теперь укажите вашему браузеру http://localhost:3000/users/invitation/new . Заполните и отправьте форму, отображаемую. На этот раз всплывает новая страница с приглашением.
Изменить маршруты входа и выхода по умолчанию
По умолчанию маршруты sign_in и sign_out при использовании Devise выглядят так:
sign_in: http://localhost:3000/users/sign_in
sign_out: http://localhost:3000/users/sign_out
Чтобы изменить его, перейдите в config/routes.rb и добавьте следующее:
|
1
2
3
4
5
6
|
#config/routes.rb
as :user do
get ‘signin’ => ‘devise/sessions#new’
post ‘signin’ => ‘devise/sessions#create’
delete ‘signout’ => ‘devise/sessions#destroy’
end
|
Вы можете указать свой браузер на http://localhost:3000/signin .
Вывод
Теперь вы знаете, как использовать DeviseInvitable. Вы также узнали о самоцвете letter_opener . Есть много вещей, которые вы можете сделать с Devise, так что загляните в Wiki, чтобы узнать больше. Спасибо, что остаетесь со мной.