Статьи

Изучение разработки, часть 2

В первой части руководства мы узнали, как установить Devise и настроить его в нашем приложении Rails. В этой части мы рассмотрим, как интегрировать DeviseInvitable.

DeviseInvitable — это расширение, которое работает с Devise. С 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 необходимо передать некоторые параметры при отправке приглашения. Чтобы это работало, нам нужно внести в белый список необходимый параметр, который будет использоваться. Используя ваш текстовый редактор, перейдите в 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 => «[email protected]»)

Он должен произвести вывод, который выглядит так, как у меня ниже, хотя будут различия.

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», «[email protected]»], [«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 [email protected] (74.3ms)
Date: Fri, 07 Oct 2016 08:41:51 +0100
Message-ID: <[email protected]>
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
 
 
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 [email protected]</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: «[email protected]»,
 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 позволяет просматривать сообщения электронной почты в браузере по умолчанию. При этом вам не нужно настраивать систему доставки почты при работе в среде разработки.

Откройте свой 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, чтобы узнать больше. Спасибо, что остаетесь со мной.