仕様
- Producer (製造者) は token という String の属性を持つ。
- token は必須属性で、Producer の新規作成時に、ユニークかつランダムな英数字を自動的にセットしたい。
コード
app/models/producer.rb
require 'securerandom'
class Producer < ApplicationRecord
validates :token, uniqueness: true
# before_create :set_token # 駄目なパターン
before_validation :set_token, on: :create
def set_token
self.token = SecureRandom.alphanumeric(24)
self.set_token unless self.valid?
end
end
before_create
で set_token を呼び出そうとした場合は、先に validation が走るので、 token の uniquenss 制約でエラーが発生する場合がある。
最初から全てのレコードに token が設定されていれば問題ないが、途中から導入した場合、set_token が呼び出される前の validation で nil が重複することになってしまう。
教訓
コールバック周りで想定と違う挙動が発生した場合は、心を落ち着けて Rails ガイドを見直すこと。