Webアプリケーションにおいて簡単にログイン認証などを実装できる Devise の導入方法です。最初に必要そうな部分をまとめてます。
Deviseの導入
実行環境は以下の通りです。
- Rails 5.1.1
- Ruby 2.4.1
Gemfile に以下を追加してbundle install
を実行してください。
gem 'devise'
Devise の設定ファイルを生成します。
$ ./bin/rails generate devise:install Running via Spring preloader in process 55270 create config/initializers/devise.rb create config/locales/devise.en.yml =============================================================================== Some setup you must do manually if you haven't yet: 1. Ensure you have defined default url options in your environments files. Here is an example of default_url_options appropriate for a development environment in config/environments/development.rb: config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } In production, :host should be set to the actual host of your application. 2. Ensure you have defined root_url to *something* in your config/routes.rb. For example: root to: "home#index" 3. Ensure you have flash messages in app/views/layouts/application.html.erb. For example: <p class="notice"><%= notice %></p> <p class="alert"><%= alert %></p> 4. You can copy Devise views (for customization) to your app by running: rails g devise:views ===============================================================================
1 はメールに記載されるURLのホストを指定します。config/environments/development.rb
に以下を追加してください。
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
2 はroot_url
を設定してない場合は追加してください。
3 はエラーメッセージ用のタグです。app/views/layouts/application.html.haml
に追加してください。haml を使用してます。
%p.notice= notice %p.alert= alert
4 は View のパートで説明します。
Getting started | plataformatec/devise · GitHub
モデルの作成
Devise 用のモデルを作成します。作成されたモデルには Devise モジュールで構成され、Devise のコントローラを指すようにルーティングが追加されます。
$ ./bin/rails g devise User Running via Spring preloader in process 55534 invoke active_record create db/migrate/20170617153827_devise_create_users.rb create app/models/user.rb invoke rspec create spec/models/user_spec.rb invoke factory_girl create spec/factories/users.rb insert app/models/user.rb route devise_for :users
作成された User モデルを確認して必要なモジュールを追加してください。:omniauthable
以外は追加しました。
class User < ApplicationRecord devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :lockable, :confirmable, :timeoutable end
マイグレートファイルを確認して追加したモジュールのコメントを外してください。以上の準備ができたらテーブルを作成します。
$ ./bin/rails db:create db:migrate Created database 'example_development' Created database 'example_test' == 20170617153827 DeviseCreateUsers: migrating ================================ -- create_table(:users) -> 0.0304s -- add_index(:users, :email, {:unique=>true}) -> 0.0219s -- add_index(:users, :reset_password_token, {:unique=>true}) -> 0.0327s -- add_index(:users, :confirmation_token, {:unique=>true}) -> 0.0092s -- add_index(:users, :unlock_token, {:unique=>true}) -> 0.0093s == 20170617153827 DeviseCreateUsers: migrated (0.1042s) =======================
Viewの設定
Devise の全ての View は Gem の中にパッケージングされてます。カスタマイズしたい場合はrails g devise:views
を実行すると全ての View がapp/views/devise
配下にコピーされます。
しかし、User モデルを作成しているのに対応する View がapp/views/devise
にあると分かり辛いです。その場合は、以下のようにモデルのスコープを指定して作成してください。
$ ./bin/rails g devise:views users Running via Spring preloader in process 59595 Expected boolean default value for '--markerb'; got :erb (string) invoke Devise::Generators::SharedViewsGenerator create app/views/users/shared create app/views/users/shared/_links.html.erb invoke form_for create app/views/users/confirmations create app/views/users/confirmations/new.html.erb create app/views/users/passwords create app/views/users/passwords/edit.html.erb create app/views/users/passwords/new.html.erb create app/views/users/registrations create app/views/users/registrations/edit.html.erb create app/views/users/registrations/new.html.erb create app/views/users/sessions create app/views/users/sessions/new.html.erb create app/views/users/unlocks create app/views/users/unlocks/new.html.erb invoke erb create app/views/users/mailer create app/views/users/mailer/confirmation_instructions.html.erb create app/views/users/mailer/email_changed.html.erb create app/views/users/mailer/password_change.html.erb create app/views/users/mailer/reset_password_instructions.html.erb create app/views/users/mailer/unlock_instructions.html.erb
これでapp/views/users
配下に Devise の View がコピーされましたが、このままではこの View が呼び出されることはありません。/users/sign_in
にアクセスすると Gem にパッケージングされてる View を呼び出してます。これはデフォルトのスコープがapp/view/devise
配下を探しにいってるためです。
tarted GET "/users/sign_in" for 127.0.0.1 at 2017-06-18 15:27:36 +0900 Processing by Devise::SessionsController#new as HTML Rendering vendor/bundle/ruby/2.4.0/gems/devise-4.3.0/app/views/devise/sessions/new.html.erb within layouts/application
解決するにはvi config/initializers/devise.rb
で以下の箇所のコメントアウトを外してtrue
に変更してください。
config.scoped_views = true
この変更によってapp/views/users
が優先されるようになります。
Started GET "/users/sign_in" for 127.0.0.1 at 2017-06-18 15:28:12 +0900 Processing by Devise::SessionsController#new as HTML Rendering users/sessions/new.html.erb within layouts/application
Admin など復数の Devise モデルがある場合も同様です。
View は erb で作成されているので haml を使ってるならgem 'haml-rails'
の Rake タスクで変換できます。
$ ./bin/rake haml:erb2haml
Configuring views | plataformatec/devise · GitHub
How To: Create Haml and Slim Views · plataformatec/devise Wiki · GitHub
Controllerの設定
Controller をカスタマイズしたい場合rails generate devise:controllers [scope]
を実行すると、指定したスコープで Devise コントローラを継承したカスタムコントローラが作成されます。
$ ./bin/rails generate devise:controllers users Running via Spring preloader in process 63136 create app/controllers/users/confirmations_controller.rb create app/controllers/users/passwords_controller.rb create app/controllers/users/registrations_controller.rb create app/controllers/users/sessions_controller.rb create app/controllers/users/unlocks_controller.rb create app/controllers/users/omniauth_callbacks_controller.rb
作成されたコントローラを見ると Devise を継承してるだけで何も書かれていません。
class Users::SessionsController < Devise::SessionsController end
カスタマイズしたい場合は単純にメソッドをオーバーライドするか、Devise のメソッドはブロックを受け取れるようになってるので以下のように新しい処理を追加しましょう。
def create super do |resource| # custom code end end
また、カスタムコントローラを使用するにはルーティングの変更が必要です。
Configuring controllers | plataformatec/devise · GitHub
ルーティングの変更
config/routes.rb
を確認するとdevise_for :users
が追加されていると思います。この状態でのルーティングは以下のようになっています。
new_user_session GET /users/sign_in(.:format) devise/sessions#new user_session POST /users/sign_in(.:format) devise/sessions#create destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy ...
このままだと作成したカスタムコントローラを向いてないため以下のようにUsers
を module に指定してください。
Rails.application.routes.draw do devise_for :users, module: :users end
これで Users モジュールのコントローラにルーティングされました。
new_user_session GET /users/sign_in(.:format) users/sessions#new user_session POST /users/sign_in(.:format) users/sessions#create destroy_user_session DELETE /users/sign_out(.:format) users/sessions#destroy
Configuring routes | plataformatec/devise · GitHub
devise_for — Documentation for plataformatec/devise (master)
日本語化
Gemfile に以下を追加してbundle install
を実行してください。
gem 'devise-i18n'
config/application.rb
にデフォルト locale の指定を追加してください。
config.i18n.default_locale = :ja
rails g devise:views
で作成される View は I18n に対応していなかったため、devise-i18n
で作成し直します。
$ ./bin/rails g devise:i18n:views users invoke Devise::I18n::SharedViewsGenerator exist app/views/users/shared create app/views/users/shared/_links.html.erb invoke Devise::I18n::MailerViewsGenerator ... $ ./bin/rake haml:erb2haml
rails g devise:i18n:locale
で locale ファイルを作成します。View のスコープを User に変更してる場合はファイル内のdevise
という記述をusers
に変更しましょう。
$ ./bin/rails g devise:i18n:locale ja create config/locales/devise.views.ja.yml $ ./bin/rails g devise:i18n:locale en create config/locales/devise.views.en.yml
始めに作成されていた locale ファイルは削除してください。
$ rm config/locales/devise.en.yml
I18n | plataformatec/devise · GitHub
I18n · plataformatec/devise Wiki · GitHub
GitHub - tigrish/devise-i18n: Translations for the devise gem