Rails:更新时出现“已被占用”错误

问题描述 投票:0回答:3

应用程序通过属性查找或初始化:

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时会给出“已被采取”错误?

谢谢

ruby-on-rails ruby validation rails-activerecord
3个回答
1
投票

这意味着您在

Booking
deal_id
 范围内已经拥有 
experience_id
 和相同的 
time

如果您在将此唯一性验证添加到模型时数据库中已有记录,则可能会发生这种情况

但这根本没有必要。您的

first_or_initialize
仅带有
deal_id
不会妨碍组合
deal_id
experience_id
和时间

此外,它不能保护您免受竞争状况影响

您可以在更新之前通过调试检查此类记录计数:

Booking.where(
  deal_id: booking.deal_id,
  experience_id: booking.experience_id,
  time: time,
).count

0
投票

尝试在没有

update
的情况下运行没有
!
的方法来查看验证失败的地方

result = booking.update(
        guests: guests,
        names: names,
        time: time)
result.errors # <= see related errors here

-1
投票
# This implies the first record
booking = Booking.find_by(deal_id: params["id"])

if booking.nil?
  booking = Booking.new(
    #... your attributes
  )
else
  # Update the attributes you want
  booking.anything = anything
  ...
end

# This will create / update the record in the database

booking.save!
© www.soinside.com 2019 - 2024. All rights reserved.