Devise gem で email もしくは 他の項目 を使って sign in をする方法(sign in 以外もいくつか)
今回は ドキュメントに倣って項目を username にする
分類: 準備
Devise 用設定ファイルの作成
$ rails g devise:install =============================================================================== 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: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. If you are deploying on Heroku with Rails 3.2 only, you may want to set: config.assets.initialize_on_precompile = false On config/application.rb forcing your application to not access the DB or load models when precompiling your assets. 5. You can copy Devise views (for customization) to your app by running: rails g devise:views ===============================================================================
デバイス用モデルの作成
$ rails g devise user invoke active_record create db/migrate/20131225152844_devise_create_users.rb create app/models/user.rb invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml insert app/models/user.rb route devise_for :users
デバイス用モデルのテーブルを変更。email もしくは別に入力させたい カラムを指定
$ rails g migration add_username_to_users username:string invoke active_record create db/migrate/20131225152848_add_username_to_users.rb
マイグレート
$ rake db:migrate == DeviseCreateUsers: migrating ============================================== -- create_table(:users) -> 0.0082s -- add_index(:users, :email, {:unique=>true}) -> 0.0007s -- add_index(:users, :reset_password_token, {:unique=>true}) -> 0.0006s == DeviseCreateUsers: migrated (0.0098s) ===================================== == AddUsernameToUsers: migrating ============================================= -- add_column(:users, :username, :string) -> 0.0022s == AddUsernameToUsers: migrated (0.0024s) ====================================
分類: Controller の設定
ストロングパラメータの定義
class ApplicationController < ActionController::Base before_filter :configure_permitted_parameters, if: :devise_controller? # フィルターを定義 protect_from_forgery with: :exception protected # このメソッドを定義 def configure_permitted_parameters devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :password, :password_confirmation, :remember_me) } devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :email, :password, :remember_me) } devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:username, :email, :password, :password_confirmation, :current_password) } end end
Model の設定
User Model のアトリビュートを作成。email と username に紐づくらしい
app/model/user.rb class User < ActiveRecord::Base devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable attr_accessor :login # アトリビュートを定義 end
Devise に :login を authentication_keys に割り当てる設定
config/initializers/devise.rb config.authentication_keys = [ :login ]
(多重モデルを使っていたら下の書き方が良いらしい(書いたことはない)
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :authentication_keys => [:login]
first_by_auth_conditions を定義しなければいけない。
本来やるべきことはfind_first_by_auth_conditions をオーバーライドする
こと(ややこしいが新の意味ではfind_for_database_authentication
を弄らないといけないが)
first_by_auth_conditions を弄れば find_for... を弄ったことになるらしい
validation もかけておく。
app/models/user.rb class User < ActiveRecord::Base devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable attr_accessor :login validates :username, :uniqueness => { :sensitive => false } def self.find_first_by_auth_conditions(warden_conditions) conditions = warden_conditions.dup if login = conditions.delete(:login) where(conditions).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first else where(conditions).first end end end
View の設定(時々config)
sign_in 時の view を変更する
app/views/devise/session/new.html.erb <%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %> <%= devise_error_messages! %> <div><%= f.label :login %><br /> <!-- 追加 --> <%= f.text_field :login %></div> <!-- 追加 --> <div><%= f.label :email %><br /> <!-- 削除 --> <%= f.email_field :email, :autofocus => true %></div> <!-- 削除 -->
sign_up 時の view を変更する
app/views/devise/registrations/new.html.erb <%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %> <%= devise_error_messages! %> <div><%= f.label :username %><br /> <!-- 追加 --> <%= f.text_field :username %></div> <!-- 追加 --> <div><%= f.label :email %><br /> <%= f.email_field :email, :autofocus => true %></div>
app/views/devise/registrations/edit.html.erb <%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %> <%= devise_error_messages! %> <div><%= f.label :username %><br /> <!-- 追加 --> <%= f.text_field :username %></div> <!-- 追加 --> <div><%= f.label :email %><br /> <%= f.email_field :email, :autofocus => true %></div>
Devise に login を パスワードリセットおよびパスワード確認のキーとして設定する
config/initializers/devise.rb config.reset_password_keys = [ :login ] config.confirmation_keys = [ :login ]
パスワード忘れましたかビューを変更する
app/views/devise/passwords/new.html.erb <h2>Forgot your password?</h2> <%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f| %> <%= devise_error_messages! %> <div><%= f.label :login %><br /> <!-- 追加 --> <%= f.text_field :login %></div> <!-- 追加 --> <div><%= f.label :email %><br /> <!-- 削除 --> <%= f.email_field :email, :autofocus => true %></div> <!-- 削除 -->
パスワード再送ビューを変更する
app/views/confirmations/new.html.erb <h2>Resend confirmation instructions</h2> <%= form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f| %> <%= devise_error_messages! %> <div><%= f.label :login %><br /> <!-- 追加 --> <%= f.text_field :loin %></div> <!-- 追加 --> <div><%= f.label :email %><br /> <!-- 削除 --> <%= f.email_field :email, :autofocus => true %></div> <!-- 削除 -->
自由には代償がある
引用元