检查父记录是否在将来有任何带有start_date的子记录,然后停止更新

时间:2019-06-12 04:58:24

标签: ruby-on-rails ruby

我有一个名为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

1 个答案:

答案 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属性是否不是truenilfalse)。 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

代码未经过测试,但应关闭。