どうした?
Railsでアプリを作る際、ユーザー認証に便利なのがDevise gemです。
ただこのDevise、何でもかんでも言いなりに使用するとブラックボックス化してしまいます。
メソッドのようなおいしいところだけ使わさせて頂き、基本的な設計は自分の手でおこなうためにチャレンジしてみました。
Deviseを使う前に、Railsチュートリアル等で勉強して自分でユーザー認証できるようにしましょう。
Deviseもそう言ってます。
今回目指すもの
今回目指すのは、以下のようなUserモデルです。
カラム | 物理名 | 型 | 条件 |
---|---|---|---|
id | id | integer | |
名前 | name | string | 入力: 必須, 最大文字数: 50 |
Eメール | string | 入力: 必須, ユニーク制限: あり, emailのrexexpを指定 | |
パスワード | password | string | 入力: 必須, 文字数範囲: 8~20 |
手順
準備
devise gemをGemfileに追加します。
gem 'devise'
記載したらbundle install
しましょう。
ターミナルからdeviseをインストールします。
$ rails generate devise:install
通常はこの後認証用のメールサーバーを指定するのですが、今回メール認証はしないのでこの手順は飛ばします。
次に、日本語の設定をします。
詳細はこちらの記事をご覧ください。
Userモデルの作成
ターミナルにて以下のコマンドを実行します。
$ rails generate devise User
これにより、マイグレーションファイルとモデルファイルが生成されます。
これらを今回の実装に合わせて編集していきます。
マイグレーションファイル
# frozen_string_literal: true
class DeviseCreateUsers < ActiveRecord::Migration[6.1]
def change
create_table :users do |t|
## Database authenticatable
t.string :name, null: false # 追加
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
# 略
t.timestamps null: false
end
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
モデルファイル
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable, :recoverable, and :omniauthable
devise :database_authenticatable, :registerable,
:rememberable, :validatable #使用しないモジュール(:recoverable)はコメントアウト部分に移動
validates :name, presence: true,
length: { maximum: 50 }
validates :email, presence: true,
uniqueness: true
validates :password, presence: true
end
モデルファイルでは、モジュールの指定をすることができます。
各モジュールの機能については参考サイトをご覧ください。
設定が終わったらrails db:migrate
でデータベースを作成しましょう。
テーブルが正しく作成されたか確認します。
$ rails c
User.columns.map(&:name)
=> ["id", "name", "email", "encrypted_password", "remember_created_at", "created_at", "updated_at"]
指定した通りのカラムが入っていることから、無事にテーブルが作成されたことが確認できました。
続いて、バリデーションの確認をします。
コンソールでNGデータのUserを作成し、返ってきたエラーメッセージを確認します。
$ rails c
# 空データを送信
User.create!
TRANSACTION (0.4ms) BEGIN
User Exists? (1.1ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = '' LIMIT 1
TRANSACTION (0.5ms) ROLLBACK
ActiveRecord::RecordInvalid: バリエーションに失敗しました: Eメール を入力してください, パスワード を入力してください, 名前 を入力してください, Eメール を入力してください, パスワード を入力してください
(※ エラーメッセージが日本語訳されていない場合は、準備
の項で紹介した記事を元に設定してください)
エラーメッセージ中でEメールとパスワードが2回出現しています。
どうやらEメールとパスワードの必須条件はモデルファイルで指定したvalidatable
モジュールに既に入っているようです。
モデルファイルを以下のように編集します。
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable, :recoverable, and :omniauthable
devise :database_authenticatable, :registerable,
:rememberable, :validatable
validates :name, presence: true,
length: { maximum: 50 }
validates :email, uniqueness: true # 必須条件を削除
# passwordのバリデーションを削除
end
もう一度コンソールを開き、バリデーションを確認します。
$ rails c
# 必須入力の確認
User.create!
TRANSACTION (0.3ms) BEGIN
TRANSACTION (0.4ms) ROLLBACK
ActiveRecord::RecordInvalid: バリエーションに失敗しました: Eメール を入力してください, パスワード を入力してください, 名前 を入力してください
# nameの最大文字数、emailの形式、passwordの最小文字数を確認
User.create!(
name: 'a'*51,
email: 'sample',
password: 'a')
TRANSACTION (0.3ms) BEGIN
TRANSACTION (1.3ms) ROLLBACK
ActiveRecord::RecordInvalid: バリエーションに失敗しました: Eメール の形式が異なっています, パスワード は6文字以上で入力してください, 名前 は50文字以内で入力してください
先程発生していたバリデーションの重複がクリアしていますね。
また、必須入力、nameの最大文字数もクリアしていることが分かります。
emailの形式指定も指定していないのになぜかクリアしています。
パスワード文字数について、6文字以上にするように怒られてしまいました(狙いは8文字以上)。
emailの形式やパスワードの文字数については指定していないのに、なぜバリデーションにかかるのでしょうか?
それは、deviseのvaridatable
モジュールに元々組み込まれているからなのです。
config/initializers/devise.rb
を開いてみましょう。
ここには、モジュールの設定値が記載されています。
Devise.setup do |config|
# 略
config.password_length = 6..128
config.email_regexp = /\A[^@\s]+@[^@\s]+\z/
# 略
end
と記載されているのが分かります。
ここで設定されているため、我々が改めてバリデーションを指定する必要がなかったのですね。
これらの設定を変えることで、バリデーションの指定を変更することができます。
Devise.setup do |config|
# 略
config.password_length = 8..20 # 範囲を変更
config.email_regexp = /\A[^@\s]+@[^@\s]+\z/ # 変更なし
# 略
end
設定したらコンソールで確認します。
$ rails c
User.create!(
name: 'sample',
email: 'sample@example.com',
password: 'a')
TRANSACTION (1.7ms) BEGIN
TRANSACTION (0.5ms) ROLLBACK
ActiveRecord::RecordInvalid: バリエーションに失敗しました: パスワード は8文字以上で入力してください
User.create!(
name: 'sample',
email: 'sample@example.com',
password: 'a'*21)
TRANSACTION (0.4ms) BEGIN
TRANSACTION (0.2ms) ROLLBACK
ActiveRecord::RecordInvalid: バリエーションに失敗しました: パスワード は20文字以内で入力してください
パスワードの最小文字数と最大文字数についてのバリデーションが設定できていることが確認できました。
まとめ
今回の記事はここまでです。
引き続き、ルーティングの設定やコントローラの設定編をまとめていきます。
参考