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