はじめに
deviseを使い始めたときにハマった部分があったので,記事に残しておきます。
※この記事は,deviseが導入済みであることが前提です。
導入方法については,前回の記事[【Rails】deviseの導入方法] (url)にまとめていますので参考にしてみてください。
【環境】
- macOS Catalina 10.15.7
- Vagrant 2.2.4 (CentOS 7.1)
- Ruby 2.5.7
- Rails 5.2.4.4
- devise 4.7.3
手順
全体の流れは以下のようになっています。
1. nameカラムを追加する
2. devise.rbの設定を変更する
3. コントローラーを編集する
4. Viewを編集する
1. nameカラムを追加する
マイグレーションファイルを新しく作成します。Userモデルにnameカラムを追加する場合は下記のようにコマンドを実行します。
$ rails g migration add_name_to_users name:string
以下のような画面が表示されたらOKです。
invoke active_record
create db/migrate/20201104152112_add_name_to_users.rb
マイグレーションファイルを確認すると以下のように記述されています。
class AddNameToUsers < ActiveRecord::Migration[5.2]
def change
add_column :users, :name, :string
end
end
DBに反映するため,マイグレーションを実行します。
$ rails db:migrate
以下のように表示されればOKです。
== 20201104152112 AddNameToUsers: migrating ==================================
-- add_column(:users, :name, :string)
-> 0.0042s
== 20201104152112 AddNameToUsers: migrated (0.0043s) =========================
これでUserモデルにnameカラムが追加され,DBに反映されました。
2. devise.rbの設定を変更する
emailの代わりにnameでログインするためには,devise.rbの設定を変更する必要があります。(私が以前ハマったのはこの変更をしていなかったためでした。忘れずに行いましょう!)
app/config/initializers/devise.rb の
config.authentication_keys = [:email] のコメントアウトを外し
config.authentication_keys = [:name] に変更します。
# 該当箇所は⌘Fで検索すると早いです。
# ==> Configuration for any authentication mechanism
# Configure which keys are used when authenticating a user. The default is
# just :email. You can configure it to use [:username, :subdomain], so for
# authenticating a user, both parameters are required. Remember that those
# parameters are used only when authenticating and not when retrieving from
# session. If you need permissions, you should implement that in a before filter.
# You can also supply a hash where the value is a boolean determining whether
# or not authentication should be aborted when the value is not present.
# config.authentication_keys = [:email] この行を下のように変更する
config.authentication_keys = [:name]
これで,emailの代わりにnameで認証するように設定を変更できました。
3. コントローラーを編集する
次にapplication_controller.rbを編集します。
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
end
end
before_action :configure_permitted_parameters, if: :devise_controller?
これについて簡単に説明すると,deviseを使用する際にはまず最初に configure_permitted_parameters メソッドを実行することを示しています。メソッドはその下に定義しています。
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
これは,サインアップする際にnameの値を送信することを許可することを示しています。emailやpasswordの値はデフォルトで許可されています。
つまり,deviseの処理が実行される際に,configure_permitted_parameters メソッドによって,nameの値を使えるようにしているんだな,と思っていただければ大丈夫です。
(protectedってなんぞや?と思われた方は「rails ストロングパラメータ」などで検索してみると幸せになれると思います。)
4. Viewを編集する
devise関連のviewは以下のコマンドで作成できます。
$ rails g devise:views
invoke Devise::Generators::SharedViewsGenerator
create app/views/devise/shared
create app/views/devise/shared/_error_messages.html.erb
create app/views/devise/shared/_links.html.erb
invoke form_for
create app/views/devise/confirmations
create app/views/devise/confirmations/new.html.erb
create app/views/devise/passwords
create app/views/devise/passwords/edit.html.erb
create app/views/devise/passwords/new.html.erb
create app/views/devise/registrations
create app/views/devise/registrations/edit.html.erb
create app/views/devise/registrations/new.html.erb
create app/views/devise/sessions
create app/views/devise/sessions/new.html.erb
create app/views/devise/unlocks
create app/views/devise/unlocks/new.html.erb
invoke erb
create app/views/devise/mailer
create app/views/devise/mailer/confirmation_instructions.html.erb
create app/views/devise/mailer/email_changed.html.erb
create app/views/devise/mailer/password_change.html.erb
create app/views/devise/mailer/reset_password_instructions.html.erb
create app/views/devise/mailer/unlock_instructions.html.erb
viewの作成が完了しました。
ここからの作業は2つです。
- サインアップ画面を編集して,nameを登録できるようにする。
- ログイン画面を編集して,nameでログインできるようにする。
順に見ていきます。
まず,サインアップ画面のviewは,app/views/devise/registrationsにある new.html.erb になりますので,これを編集します。
<h2>Sign up</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<%# 追加 %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name, autofocus: true, autocomplete: "name" %>
</div>
<%# ここまで %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>
#中略
サーバーを立ち上げて /users/sign_up にアクセスします。
これでサインアップ画面に名前を入力する欄ができました。
次にログイン画面のviewは,app/views/users/sessionsにある new.html.erb になりますので,これを編集してnameでログインできるようにしていきましょう。
<h2>Log in</h2>
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<div class="field">
<%# 削除 %>
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
<%# ここまで %>
<%# 追加 %>
<%= f.label :name %><br />
<%= f.text_field :name, autofocus: true, autocomplete: "name" %>
<%# ここまで %>
</div>
#中略
以上で,名前でのログインが可能になりました。
参考文献
この記事は,以下の情報を参考に執筆しました。
devise機能を使ったユーザーログインガイド&名前でログイン
deviseでnameとpasswordのみでユーザー登録とログインできるように、初心者がdeviseをカスタマイズ!〜徹底的にゆっくり解説〜
before_actionとストロングパラメーターの編集について