株式会社TECH LUCKという会社で代表兼エンジニアをしている齊藤です。
ユーザー管理機能の作成のためにdeviseを導入しましたが、カスタマイズする際に苦労することが多くあります。
その際の、カスタマイズ方法になります。
基本的なdeviseのインストール
Gemのインストール
gem 'devise'
bundle install
deviseの関連ファイルをインストールする。
rails g devise:install
Userモデルの作成とマイグレーション
rails g devise user
bundle exec rails db:migrate
カスタマイズ
ここからが本題。
複数のモデルにdeviseを導入する場合
UserやCompanyでdeviseを複数のモデルで使いたい場合を想定します。
この場合には、UserはUser専用のコントローラー(Devise::~~~Controller
を継承したコントローラー)とビュー、CompanyはCompany専用のコントローラー(Devise::~~~Controller
を継承したコントローラー)とビューを作成するようにします。
# Userモデルの作成と、User専用のコントローラーとビューの作成
rails g devise user
bundle exec rails db:migrate
rails g devise:controllers users
rails g devise:views users
# Comapnyモデルの作成と、Company専用のコントローラーとビューの作成
rails g devise company
bundle exec rails db:migrate
rails g devise:controllers companies
rails g devise:views companies
ルーティングをカスタマイズする
ログインの画面は/login
, 新規登録の画面は/signup
のようなURLにしたい場合は、以下のようにroutes.rb
を編集するいいです。
# skip: :allでdeviseで作成されたusersに関するすべてのルーティングを無効にすることができる
devise_for :users, skip: :all
# users専用のコントローラーを作成していない場合は、以下のようにdevise配下のコントローラーへルーティングを設定する
devise_scope :user do
get 'login' => 'devise/sessions#new', as: :new_user_session
post 'login' => 'devise/sessions#create', as: :user_session
delete 'logout' => 'devise/sessions#destroy', as: :destroy_user_session
get 'signup' => 'devise/registrations#new', as: :new_user_registration
post 'signup' => 'devise/registrations#create', as: :user_registration
end
# users専用のコントローラーを作成した場合は、以下のようにusers配下のコントローラーへルーティングを設定する
devise_scope :user do
get 'login' => 'users/sessions#new', as: :new_user_session
post 'login' => 'users/sessions#create', as: :user_session
delete 'logout' => 'users/sessions#destroy', as: :destroy_user_session
get 'signup' => 'users/registrations#new', as: :new_user_registration
post 'signup' => 'users/registrations#create', as: :user_registration
end
日本語対応する。
deviseはデフォルトでは英語になっているので、日本語に対応させます。
i18n対応のためのGemをインストール
gem 'devise-i18n'
gem 'devise-i18n-views'
bundle install
deviseを日本語化対応するためのdevise.views.ja.yml
ファイルの作成。
rails g devise:views:locale ja
deviseを日本語化対応するためのビューファイルの作成。
rails g devise:i18n:views user
ここで注意が必要なのが、上記のコマンドはuser専用のビューファイルが作成されることになることです。
これで作成した場合には、さきほどdevise.views.ja.yml
の中で以下のようになっていますが、devise
となっている箇所をusersと変更しないと適用されないので注意しましょう。
ja:
devise:
confirmations:
new:
resend_confirmation_instructions: "アカウント確認メール再送"
以下の記述を、config/application.rb
に追加する。
config.i18n.default_locale = :ja
これでサーバーを再起動させれば、日本語化対応となります。
新規登録の際に他のカラムも保存する
configure_permitted_parameters
をapp/controllers/application_controller.rb
でオーバーライドする方法もありますが、複数のモデルに対応するために、それぞれのregistrations_controller.rb
で対応しましょう。
registrations_controller.rb
のconfigure_sign_up_params
とconfigure_account_update_params
に追加するキーを設定し、 before_action :configure_sign_up_params, only: [:create]
とbefore_action :configure_account_update_params, only: [:update]
を設定する。
これらはコメントアウトされているので、コメントアウトを外して利用できるようにして追加で設定を行なっていきましょう。
また、parameterなどをさらにカスタマイズしたい場合には以下ようにも書くことができます。
devise_parameter_sanitizer.permit(:sign_up) do |user_params|
user_params.permit(:last_name,
:first_name)
.merge(registration_date: Date.today)
# devise_parameter_sanitizerにはmergeメソッドは使えないので、このようにする
end
メールアドレスを認証する際に新規登録とメールアドレス変更時で送信するメールを分ける
ほぼ以下の記事と同じです。
deviseではテンプレートを分けるための拡張ポイント
Devise::Models::Confirmable#send_on_create_confirmation_instructions
を用意している。
とのことです。
user.rbに以下のメソッドを定義します。
def send_on_create_confirmation_instructions
generate_confirmation_token! unless @raw_confirmation_token
send_devise_notification(:confirmation_on_create_instructions, @raw_confirmation_token, {})
end
そうすると新規作成の際には、confirmation_on_create_instructions.html.erb
をActionMailerで送信されるようになります。
app/mailers/user_mailer.rb
を作成します。
ここで、Devise::Mailer
を継承したクラスを作るのと、deviseで読み込むMailer
のファイルを変更します。
class UserMailer < Devise::Mailer
def confirmation_on_create_instructions(record, token, opts = {})
@token = token
devise_mail(record, :confirmation_on_create_instructions, opts)
end
end
Devise.setup do |config|
# 省略
config.mailer = 'Users::Mailer'
# 省略
end
users/mailer/confirmation_on_create_instructions.html.erb
には、新規作成時のメール送信の文面を記載することになります。
users/mailer/confirmation_instructions.html.erb
には、メールアドレスの変更の際に送信されるメールの文面を記載することになります。
メールアドレスの認証後に完了画面を表示する
confirmations_controller.rb
のafter_confirmation_path_for
に中に任意のパスを指定すれば、認証完了画面を表示することができます。
# The path used after confirmation.
def after_confirmation_path_for(_resource_name, _resource)
confirmation_complete_path # ここのControllerとViewは作成が必要。
end
メールアドレス認証の際に再送信をした後に再送信完了の画面を表示する
confirmations_controller.rb
のafter_resending_confirmation_instructions_path_for
に中に任意のパスを指定すれば、メールアドレス認証の際にメールを再送信後に認証完了画面を表示することができます。
# The path used after resending confirmation instructions.
def after_resending_confirmation_instructions_path_for(_resource_name)
confirmation_resend_path #ここのパスの先にあるControllerとViewは作成が必要
end
ログイン画面でのエラーメッセージの表示
以下の記事を参考にすればフラッシュメッセージを表示することができるようになります。
参考にした記事(圧倒的感謝)