我有一个名为items的表,并且在items_controller.rb中有一个名为archive的方法,如果该方法被调用,它会将项目的活动字段设置为false。问题是我还有另一个表,称为保留,表上的字段名为start_date,因此我希望在将项目的活动字段更新为false之前,我想检查它们是否将来有start_date字段。如果没有,则不要更新项目上的活动字段,并给用户一条错误消息。
这是item.rb
class Item < ApplicationRecord
has_many :reservations
before_save :check_for_reservations
def check_for_reservations
if reservations.count > 0
reservations.each do |reservation|
if reservation.start_date > Date.today
return false
end
end
end
end
end
这是items.controller.rb
def archive
@item = Item.find(params[:id])
@item.active = false
if @item.save
flash[:notice] = "Item been archived..."
else
flash[:alert] = "Something went wrong..."
end
redirect_back(fallback_location: request.referer)
end
不起作用,其更新项目记录活动的等于= false
答案 0 :(得分:2)
我认为使用自定义验证方法是合理的,您可以在guide中进行了解。它可能看起来像这样:
class Item < ApplicationRecord
has_many :reservations
before_save :check_for_reservations
validate :okay_to_archive
def okay_to_archive
if !item.active && reservations.where("start_date >= ?", Date.today).any?
errors.add(:active, "can't be set to false when there are future reservations")
end
end
end
!item.active
检查active
属性是否不是true
(nil
或false
)。 reservations.where("start_date >= ?", Date.today).any?
会检查是否有任何关联的reservations
带有start_date
之后的日期。因此,一起:
if !item.active && reservations.where("start_date >= ?", Date.today).any?
...
end
他们检查item
是否对以后的预订无效。如果是这样,则会将错误写入errors
:
errors.add(:active, "can't be set to false when there are future reservations")
,当您尝试执行@item.save
时,会收到验证错误。
def archive
@item = Item.find(params[:id])
@item.active = false
if @item.save
flash[:notice] = "Item been archived..."
else
flash[:alert] = "Something went wrong..."
end
redirect_back(fallback_location: request.referer)
end
代码未经过测试,但应关闭。