我有一个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_time
为whenever
,则使用条件验证来检查false
validates_presence_of :finish_time, :unless => @whenever
我对这造成的重复感到不满意。如果finish_time
为nil
,则whenever
可以是true
的唯一方式,如果您更改了一个,则通常需要更改另一个。如果使用新Event
更新finish_time
,那么whenever
也必须更改为false
。
理想情况下,我想将验证移至我的控制器。这样,通过将whenever
设置为finish_time
可以轻松指示进行直接模型访问null
,但是如果用户未指示选择,则会发送到/ events的用户被大吼。但是,我无法找到一种方法来从控制器有条件地添加或删除Event
的验证,或者即使这是最好的方法。
删除此重复的最佳方法是什么?
答案 0 :(得分:1)
您可以尝试以“Ruby方式”解决问题,而不是尝试通过验证来解决问题。
除了验证之外,您可能想要使用finish_time
和whenever
方法的变换器。
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
。然后,您可以按照与上述相同的方式修改访问者。