Help us understand the problem. What is going on with this article?

【Rails備忘録】deviseまとめ

More than 3 years have passed since last update.

この記事について

deviseはRailsでユーザー認証を扱うときに非常に便利なgemです
初めて自分でDevise使ってユーザー認証周りを作ったので、その際に調べたこと・試したことなどを備忘録的に残しておきます
今回の使用したdeviseのバージョンはv4.2.0です

gemのインストール

Gemfileに以下を追記してbundle installを実行

gem 'devise'

設定ファイルなどの生成

rails g devise:installで設定ファイルやViewで用いられるlocaleファイルが生成されます

以下は生成されたファイル

  • config/initializers/devise.rb (設定ファイル)
    • パッと見変更しそうなものは2つぐらい
    • config.mailer_sender(送信元のアドレス)
    • config.password_length(パスワードの長さ, デフォルトは6文字以上128文字以下)
  • config/locales/devise.en.yml (localeファイル)
    • 日本語のlocaleファイルの追加方法は後ほど詳述
  • config/environments/development.rb (登録周りで飛ぶメールのホスト指定が追記される)
    • config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }が追記される

ユーザーモデルの生成

rails g devise Modelでモデルやマイグレーションが生成されます
Modelの部分にはUserやAdminなどが入るものと思ってください
以下はrails g devise Userで生成されたファイル

  • app/models/user.rb
  • config/routes.rb
  • db/migrate/20170211042541_devise_create_users.rb
  • test/fixtures/users.yml
  • test/models/user_test.rb

generateコマンドで生成された段階ではモデルは以下のようになっています

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
end

見て分かる通りデフォルトでは以下の機能が有効となっています

module 機能
database_authenticatable DBに保存するパスワードの暗号化(必須)
registerable サインアップ処理
recoverable パスワードリセット
rememberable クッキーにログイン情報を保持
trackable サインイン回数・時刻・IPアドレスを保存
validatable メールアドレスとパスワードのバリデーション

また、コメントにある通り以下の機能を利用したい場合はモジュール名の追記が必要となります
その場合、マイグレーションにも対応するコメントアウトがあるのでそちらもコメントインしましょう
特にconfirmableあたりはよく使うことになると思うので注意が必要です

module 機能
confirmable メール送信による登録確認
lockable 一定回数ログインに失敗した際のアカウントロック
timeoutable 一定時間でセッションを削除する
omniauthable OmniAuthサポート

モジュール追加の編集が終わったらrake db:migrateし、/users/sign_upにアクセスすればデフォルトの登録画面が表示されます

WPCS2.png

View/Controllerのカスタマイズ

Viewの生成

ここまでで認証自体は可能になりましたが、実際の開発で利用するにあたってはViewのカスタマイズが必要になると思います
rails g devise:views ModelでModelに対応するViewが生成されます
以下は生成されたファイルです
これらのファイルをカスタマイズすればOKです

  • app/views/users/confirmations/new.html.erb
  • app/views/users/mailer/confirmation_instructions.html.erb
  • app/views/users/mailer/password_change.html.erb
  • app/views/users/mailer/reset_password_instructions.html.erb
  • app/views/users/mailer/unlock_instructions.html.erb
  • app/views/users/passwords/edit.html.erb
  • app/views/users/passwords/new.html.erb
  • app/views/users/registrations/edit.html.erb
  • app/views/users/registrations/new.html.erb
  • app/views/users/sessions/new.html.erb
  • app/views/users/shared/_links.html.erb
  • app/views/users/unlocks/new.html.erb

Controllerの生成

コントローラーで行う処理を変更したい場合はrails g devise:controllers ModelでControllerを生成することができます
以下は生成されたファイルです

  • app/controllers/users/confirmations_controller.rb
  • app/controllers/users/omniauth_callbacks_controller.rb
  • app/controllers/users/passwords_controller.rb
  • app/controllers/users/registrations_controller.rb
  • app/controllers/users/sessions_controller.rb
  • app/controllers/users/unlocks_controller.rb

この場合、生成されたControllerはDevise::RegistrationControllerなどのコントローラーを継承する形になっており、デフォルトではすべてのメソッドが親クラスのメソッドを呼び出した状態でコメントアウトされています

class Users::RegistrationsController < Devise::RegistrationsController
# before_action :configure_sign_up_params, only: [:create]
# before_action :configure_account_update_params, only: [:update]

  # GET /resource/sign_up
  # def new
  #   super
  # end

  # ...

さらに、ルーティングを変更する必要があります
この例ではunlockとomniauthは利用してないのでルーティング変更してません

devise_for :users, controllers: {
  confirmations: 'users/confirmations',
  passwords:     'users/passwords',
  registrations: 'users/registrations',
  sessions:      'users/sessions',
}

これで、特定の条件下でのみconfirmationをスキップする、confirmation時に追加のユーザー情報を登録させるなどの細かな挙動のカスタマイズが可能になると思います(まだ試してないけど)

(参考)
deviseでconfirmable設定をした際の確認メールをスキップさせる skip_confirmation! は、対象のオブジェクトをsaveする前に書く - Qiita

deviseのStrongParameterまわり

TODO: 余裕があれば後で書く

deviseのi18n対応

今回作ったサイトでは日本語と英語に対応してほしいとの要望があったので、deviseのi18n対応についても簡単に調べてみました

deviseのWikiに各言語のロケールファイルの一覧が載っているのでこの中からおめあてのものを探しましょう
I18n · plataformatec/devise Wiki

DLしたらconfig/locale/devise.Lang.ymlにロケールファイルを置いてあげましょう
日本語の場合ならconfig/locale/devise.ja.ymlです

すでにデフォルトのロケールが日本語になっていれば問題ないですが、そうでなければconfig/application.rbの中でデフォルトのロケールを変更してあげましょう

module WPCS2
  class Application < Rails::Application
    # ...

    # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
    config.i18n.default_locale = :ja 

    # ...
  end
end

これでエラーメッセージなどが日本語化されます
(一部、追加しないとtranslationに失敗する部分もあるようですが)

=== 2017/02/20追記 ===

ビューについてはdevise-i18nというgemがあるのでそちらを使いましょう
tigrish/devise-i18n: Translations for the devise gem

まずはGemfileに gem devise-i18n を追記してインストール
そして、viewを rails g devise:i18n:views で生成できます
生成されたビューはapp/views/devise に置かれるので app/views/users などにリネームしましょう
これだけだとビューに書かれたパーシャルの描画指定などが矛盾してしまうので、 render "devise/..."と成っている部分のdeviseをusersに書き換えます
最後に rails g devise:i18n:locale ja などとしてロケールファイルを生成します
ロケールファイルの中を開いて、deviseとなっているところをusersに変えましょう

また、これだけだと一部のエラーメッセージなどがtranslation missingになってしまう場合があります
rails-i18nというリポジトリに汎用的に使えるロケールファイルのテンプレートがあるのでダウンロードして config/locale/ja.yml に配置しましょう
(まぁ、これはdeviseに限らずi18n対応するなら一番最初にやっておくべきことなのですが)
svenfuchs/rails-i18n: Repository for collecting Locale data for Ruby on Rails I18n as well as other interesting, Rails related I18n stuff

=== 追記終わり ===

まとめ

deviseを使うことで非常に簡単にユーザー認証機能を作成できます
今回は試してないですが、OmniAuthまわりもサポートがあるようなので、TwitterやFacebookなどのアカウントでログインといった機能も簡単に実装できるようです(あんまりよくわかってないけど)
できれば、中でどんな処理を行っているのかも簡単に把握しておくといざというときも対処ができてよいかもしれません

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした