使用参数来控制Rails验证

时间:2009-12-21 02:06:50

标签: ruby-on-rails refactoring controller dry

我有一个Event模型,其中包含finish_time字段和一个名为whenever的表单复选框。选中whenever后,我想将finish_time设置为nil,无论其参数值如何,如果未选中whenever,我想确保finish_time是我保存在数据库中之前的有效日期。


目前,我正在使用事件的whenever attr_accessor实现此目的:

params[:event][:finish_time] = nil if whenever = params[:event].delete(:whenever)
@event = Event.new(params[:event])
@event.whenever = whenever

如果finish_timewhenever,则使用条件验证来检查false

validates_presence_of :finish_time, :unless => @whenever

我对这造成的重复感到不满意。如果finish_timenil,则whenever可以是true的唯一方式,如果您更改了一个,则通常需要更改另一个。如果使用新Event更新finish_time,那么whenever也必须更改为false

理想情况下,我想将验证移至我的控制器。这样,通过将whenever设置为finish_time可以轻松指示进行直接模型访问null,但是如果用户未指示选择,则会发送到/ events的用户被大吼。但是,我无法找到一种方法来从控制器有条件地添加或删除Event的验证,或者即使这是最好的方法。

删除此重复的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

您可以尝试以“Ruby方式”解决问题,而不是尝试通过验证来解决问题。

除了验证之外,您可能想要使用finish_timewhenever方法的变换器。

class Event < ActiveRecord::Base
  # Validate presence
  validates_presence_of :finish_time, :unless => @whenever

  def whenever=(yes)
    write_attribute(:whenever, yes)
    write_attribute(:finish_time, nil) if yes?
  end
  def finish_time=(time)
    write_attribute(:whenever, false)
    write_attribute(:finish_time, time)
  end
end

然后你可以尝试(但是,我不确定它是否有效):

@event = Event.new(params[:event])

编辑但是,这会使得结果字段依赖于订单分配发生,因此如果分配顺序发生更改,相同参数集的结果可能会有所不同。这不太可能你想要的。所以你必须按照你想要的方式调整你的运算符。

而且你也应该明白,除非你的要求是干的,否则你将无法将你的代码干掉。

编辑#2:如果finish_time设置为true,我认为您应该考虑将nil的要求降为whenever。然后,您可以按照与上述相同的方式修改访问者。