※model名をuserと定義した前提で進めます。
存在性の検証
./models/user.rbに以下を記述
class User < ApplicationRecord
validates :name, presence: true
validates :email, presence: true
end
次に文字数制限
先程のコードに追加。
class User < ApplicationRecord
validates :name, presence: true, length: { maximum: 50 }
validates :email, presence: true, length: { maximum: 255 }
end
メールアドレスのフォーマットの制限
class User < ApplicationRecord
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX }
end
VALID_EMAIL_REGEXとformatを追加する。
これをしないと、例えば"foo@bar,com"や、"bazbaz@gmail-111などの無効なメールアドレスもvalidation通過してしまう。
また、上記だと"foo@bar..comといったアドレスだと通ってしまうことになるので、より完璧にvalidationするには、VALID_EMAIL_REGEXは以下にすると良い。
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
一意性の検証
また、メールアドレスは重複してしまうとまずいので、一意性を検証する必要がある。
class User < ApplicationRecord
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: true
end
uniquenessを追加。
ただこのままだと、大文字小文字の区別がされないのでデータベースに保存する直前で全て小文字に変換する処理をします。
class User < ApplicationRecord
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: true
end
before_saveによって、保存する直前にアドレスを小文字に変換することができるようになりました。
また、データベースレベルでは一意性を保証できていないので、データベース上のemailカラムにインデックスを追加します。
$ rails g migration add_index_to_users_email
このコマンドによって新たにmigrationファイルが作成される。
(db/migrate/[timestanp]_add_index_to_users_email.rb)
class AddIndexToUsersEmail < ActiveRecord::Migration[7.0]
def change
add_index :users, :email, unique: true
end
end
db:migrateは忘れずに!
$ rails db:migrate
また現時点でfixtureファイルに手を加えていない場合、おかしなことになる場合があるので中身はカラにしておきましょう。