Rails: 更新時に「すでに取得されています」エラーが発生する
概要
アプリは属性を検索または初期化します。
booking = Booking.where(deal_id: params["id"]).first_or_initialize
次に、いくつかの追加の属性を更新します
if booking.update!(
guests: guests,
names: names,
time: time)
このコードではエラーが発生します
Validation failed: Deal has already been taken
検証コードは
validates_uniqueness_of :deal_id, allow_blank: true, scope: [:experience_id, :time], unless: -> {deal_id.zero? }
最初に first_or_initialize を実行すると、「すでに取得されています」というエラーが発生するのはなぜですか?
ありがとう
解決策
これは、experience_id、time の範囲内に同じ deal_id で予約がすでにあることを意味します
これは、この一意性検証をモデルに追加したときにデータベースにすでにレコードがあった場合に発生する可能性があります。
しかし、これはまったく必要ありません。 deal_id だけを使用した first_or_initialize では、deal_id、experience_id、time の組み合わせは妨げられません
さらに、競合状態から保護することはできません
更新する前に、デバッグでそのようなレコード数を確認できます。
Booking.where(
deal_id: booking.deal_id,
experience_id: booking.experience_id,
time: time,
).count