Rails と devise の話はまだ続くよ。今日は devise のビューとコントローラをカスタマイズする。
やっぱりユーザー名がほしい
ユーザーアカウントに Email だけじゃなくて、やっぱりユーザー名がほしい。というわけで、migration スクリプトに2行追加。
class DeviseCreateUsers < ActiveRecord::Migration def change create_table(:users) do |t| ## Database authenticatable t.string :name, null: false, default: "" t.string :email, null: false, default: "" t.string :encrypted_password, null: false, default: "" ## Recoverable t.string :reset_password_token t.datetime :reset_password_sent_at ## Rememberable t.datetime :remember_created_at ## Trackable t.integer :sign_in_count, default: 0, null: false t.datetime :current_sign_in_at t.datetime :last_sign_in_at t.string :current_sign_in_ip t.string :last_sign_in_ip ## Confirmable t.string :confirmation_token t.datetime :confirmed_at t.datetime :confirmation_sent_at t.string :unconfirmed_email # Only if using reconfirmable ## Lockable # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts # t.string :unlock_token # Only if unlock strategy is :email or :both # t.datetime :locked_at t.timestamps end add_index :users, :name, unique: true add_index :users, :email, unique: true add_index :users, :reset_password_token, unique: true add_index :users, :confirmation_token, unique: true # add_index :users, :unlock_token, unique: true end end
そしてデータベースの作り直し。
takatoh@nightschool:~/w/lathercraft$ bundle exec rake db:drop takatoh@nightschool:~/w/lathercraft$ bundle exec rake db:migrate
devise のビューをコピーしてカスタマイズ
デフォルトでは gem のビューが使われているけど、カスタマイズするためにビューをコピーする。
takatoh@nightschool:~/w/lathercraft$ bundle exec rails generate devise:views users invoke Devise::Generators::SharedViewsGenerator create app/views/users/shared create app/views/users/shared/_links.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/reset_password_instructions.html.erb create app/views/users/mailer/unlock_instructions.html.erb
とりあえず、sign up するときの app/views/users/registrations.new.html.erb と sign in するときの app/views/users/sessions/new.html.erb にユーザー名の欄を付け加えた。
<h2>Sign up</h2> <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> <%= devise_error_messages! %> <div> <%= f.label :name %> <%= f.email_field :name, autofocus: true %> </div> <div> <%= f.label :email %> <%= f.email_field :email %> </div> <div> <%= f.label :password %> <%= f.password_field :password, autocomplete: "off" %> </div> <div> <%= f.label :password_confirmation %> <%= f.password_field :password_confirmation, autocomplete: "off" %> </div> <div> <%= f.submit "Sign up" %> </div> <% end %> <%= render "users/shared/links" %>
<h2>Sign in</h2> <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %> <div> <%= f.label :name %> <%= f.email_field :name, autofocus: true %> </div> <div> <%= f.label :email %> <%= f.email_field :email %> </div> <div> <%= f.label :password %> <%= f.password_field :password, autocomplete: "off" %> </div> <% if devise_mapping.rememberable? -%> <div> <%= f.check_box :remember_me %> <%= f.label :remember_me %> </div> <% end -%> <div> <%= f.submit "Sign in" %> </div> <% end %> <%= render "users/shared/links" %>
コントローラーのカスタマイズ
コントローラーをカスタマイズするには、Devise::SessionsController, Devise::RegistrationsController, Devise::PasswordsController を継承したクラスを作成して、各メソッドをオーバーライドすればいいようだ。どのメソッドをオーバーライドすればいいかを、bundle exec rake routes
で確認する。
takatoh@nightschool:~/w/lathercraft$ bundle exec rake routes Prefix Verb URI Pattern Controller#Action 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 user_password POST /users/password(.:format) devise/passwords#create new_user_password GET /users/password/new(.:format) devise/passwords#new edit_user_password GET /users/password/edit(.:format) devise/passwords#edit PATCH /users/password(.:format) devise/passwords#update PUT /users/password(.:format) devise/passwords#update cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel user_registration POST /users(.:format) devise/registrations#create new_user_registration GET /users/sign_up(.:format) devise/registrations#new edit_user_registration GET /users/edit(.:format) devise/registrations#edit PATCH /users(.:format) devise/registrations#update PUT /users(.:format) devise/registrations#update DELETE /users(.:format) devise/registrations#destroy user_confirmation POST /users/confirmation(.:format) devise/confirmations#create new_user_confirmation GET /users/confirmation/new(.:format) devise/confirmations#new GET /users/confirmation(.:format) devise/confirmations#show (後略)
これを見ると、とりあえずは registration#new と sessions#new かな。それぞれこうした。
class Users::RegistrationsController < Devise::RegistrationsController end
Devise::SessionsController def new super end def create super end def destroy super end end
ついでに PasswordsController も。
class Users::PasswordsController < Devise::PasswordsController end
ルーティングの設定
作ったコントローラーを使うように、ルーティングを変更する。
Rails.application.routes.draw do devise_for :users, :controllers => { :registrations => "users/registrations", :sessions => "users/sessions", :passwords => "users/passwords" } (後略)
ルーティングを確認してみよう。
takatoh@nightschool:~/w/lathercraft$ bundle exec rake routes Prefix Verb URI Pattern Controller#Action 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 user_password POST /users/password(.:format) users/passwords#create new_user_password GET /users/password/new(.:format) users/passwords#new edit_user_password GET /users/password/edit(.:format) users/passwords#edit PATCH /users/password(.:format) users/passwords#update PUT /users/password(.:format) users/passwords#update cancel_user_registration GET /users/cancel(.:format) users/registrations#cancel user_registration POST /users(.:format) users/registrations#create new_user_registration GET /users/sign_up(.:format) users/registrations#new edit_user_registration GET /users/edit(.:format) users/registrations#edit PATCH /users(.:format) users/registrations#update PUT /users(.:format) users/registrations#update DELETE /users(.:format) users/registrations#destroy user_confirmation POST /users/confirmation(.:format) devise/confirmations#create new_user_confirmation GET /users/confirmation/new(.:format) devise/confirmations#new GET /users/confirmation(.:format) devise/confirmations#show (後略)
confirmation のルーティングが devise のままだけど大丈夫かな。
試しにサインアップしてみると、無事うまく行った。