はじめに
現在開発中のWebサイトで管理者画面ログイン機能をDevise
を用いて作成中です。
開発途中で仕様が変わり、Deviseの機能を一部有効化しようと思った時にどうすればいいのか困ったので備忘録として残しておきます。
やりたいこと
Deviseのパスワードリセット機能とメール認証機能を追加したい。
状況
現在、Deviseで有効化している機能は以下の通りです。
app/models/admin.rb
class Admin < ApplicationRecord
devise :database_authenticatable, :rememberable, :validatable, :trackable
end
db/migration.rb
class DeviseCreateAdmins < ActiveRecord::Migration[6.0]
def change
create_table :admins do |t|
## Database authenticatable
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.inet :current_sign_in_ip
t.inet :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 null: false
end
add_index :admins, :email, unique: true
# add_index :admins, :reset_password_token, unique: true
# add_index :admins, :confirmation_token, unique: true
# add_index :admins, :unlock_token, unique: true
end
end
schema.rb
create_table "admins", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["email"], name: "index_admins_on_email", unique: true
end
ここにパスワードリセット機能とメール認証機能を有効化させたいため、以下のモジュールを追加していきます。
recoverable
confirmable
ルーティングの確認
ちなみに現在のルーティングは以下の様になっています。
ターミナル
new_admin_session GET /admin/sign_in(.:format) admins/sessions#new
admin_session POST /admin/sign_in(.:format) admins/sessions#create
destroy_admin_session DELETE /admin/sign_out(.:format) admins/sessions#destroy
実装方法
1. まずは追加したいモジュールをモデルに追記する。
app/models/admin.rb
class Admin < ApplicationRecord
devise :database_authenticatable, :rememberable, :validatable, :trackable, :recoverable, :confirmable
end
2. カラムの追加
マイグレーションファイルのコメントアウトをインにすればいいのでは?とも思いましたが、テーブルに変更を加えないといけないため新たにマイグレーションファイルを作っていきます。
以下コマンドでカラムを追加していきましょう。
ターミナル
$ be rails g migration AddRecoverableToAdmins reset_password_token:string reset_password_sent_at:datetime
$ be rails g migration AddConfirmableToAdmins confirmation_token:string confirmed_at:datetime confirmation_sent_at:datetime unconfirmed_email:string
# 以下のコマンドで一度に追加もできます。
$ be rails g migration AddDeviseToAdmins reset_password_token:string reset_password_sent_at:datetime confirmation_token:string confirmed_at:datetime confirmation_sent_at:datetime unconfirmed_email:string
以下が作成されたファイルです。
db/migration.rb
class AddDeviseToAdmins < ActiveRecord::Migration[6.0]
def change
add_column :admins, :reset_password_token, :string
add_column :admins, :reset_password_sent_at, :datetime
add_column :admins, :confirmation_token, :string
add_column :admins, :confirmed_at, :datetime
add_column :admins, :confirmation_sent_at, :datetime
add_column :admins, :unconfirmed_email, :string
end
end
3. マイグレーションの実行
マイグレーションファイルができたのを確認したらマイグレーションを実行してテーブル追加されるのを確認。
ターミナル
$ rails db:migrate
== 20210412221727 AddDeviseToAdmins: migrating ================================
-- add_column(:admins, :reset_password_token, :string)
-> 0.0350s
-- add_column(:admins, :reset_password_sent_at, :datetime)
-> 0.0036s
-- add_column(:admins, :confirmation_token, :string)
-> 0.0039s
-- add_column(:admins, :confirmed_at, :datetime)
-> 0.0040s
-- add_column(:admins, :confirmation_sent_at, :datetime)
-> 0.0067s
-- add_column(:admins, :unconfirmed_email, :string)
-> 0.0269s
== 20210412221727 AddDeviseToAdmins: migrated (0.0809s) =======================
4. schema.rbの確認
schema.rb
create_table "admins", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "unconfirmed_email"
t.index ["email"], name: "index_admins_on_email", unique: true
end
きちんとテーブルにカラムが追加されていますね!
5. ルーティングの確認
最後にルーティングも確認しておきましょう。
new_admin_session GET /admin/sign_in(.:format) admins/sessions#new
admin_session POST /admin/sign_in(.:format) admins/sessions#create
destroy_admin_session DELETE /admin/sign_out(.:format) admins/sessions#destroy
# 以下が追記されていることを確認
new_admin_password GET /admin/password/new(.:format) devise/passwords#new
edit_admin_password GET /admin/password/edit(.:format) devise/passwords#edit
admin_password PATCH /admin/password(.:format) devise/passwords#update
PUT /admin/password(.:format) devise/passwords#update
POST /admin/password(.:format) devise/passwords#create
new_admin_confirmation GET /admin/confirmation/new(.:format) devise/confirmations#new
admin_confirmation GET /admin/confirmation(.:format) devise/confirmations#show
POST /admin/confirmation(.:format) devise/confirmations#create
おわりに
本来なら最初にきちんと仕様を決めておくべきだと思いますが、これで途中でモジュールを追加したい場合にも対応できるようになるので結果オーライです!