Ruby on rails 3 Rails:如何在保存前根据另一个字段更改字段值?

Ruby on rails 3 Rails:如何在保存前根据另一个字段更改字段值?,ruby-on-rails-3,activerecord,Ruby On Rails 3,Activerecord,我试图根据另一个布尔字段的值将布尔字段设置为false。我使用ActiveRecord模型尝试了以下操作: before_save :reconcile_xvent def reconcile_xvent self.xvent_hood = false if !self.xvent_plenum? end 但这不起作用。现在,我的许多单元测试都失败了: ActiveRecord::RecordNotSaved: ActiveRecord::RecordNotSaved

我试图根据另一个布尔字段的值将布尔字段设置为false。我使用ActiveRecord模型尝试了以下操作:

  before_save :reconcile_xvent

  def reconcile_xvent
    self.xvent_hood = false if !self.xvent_plenum?
  end
但这不起作用。现在,我的许多单元测试都失败了:

ActiveRecord::RecordNotSaved: ActiveRecord::RecordNotSaved
如果xvent_静压箱为假,如何将xvent_发动机罩设置为假

更新

以下是有效的方法(其中一些来自下面的评论/答案):


如果没有“if self.xvent_hood?”部分,我想不出如何使它工作……

在保存之前
仅在验证通过后调用。您需要做的是将
协调\u xvent
移动到验证之前的
,而不是保存之前的

如果您在保存之前将该方法保留在
中,那么将发生的情况是它认为
xvent\u hood
为空,如果您有一个验证来检查
xvent\u hood
的空值,它将在调用保存之前的
失败。这可能解释了为什么会出现
RecordNotSaved
错误


要记住的另一件事是,如果您有一个布尔属性,那么也不能使用
validate\u presence\u。请参见

我刚才也提到了这个问题,第一个代码块的问题是您将
xvent\u hood
值指定为false,然后由before\u save方法返回

依照

取消回调

如果before_*回调返回false,则所有后面的回调和 关联的操作被取消。如果after_*回调返回false, 所有随后的回调都将被取消。回调通常在中运行 它们被定义的顺序,除了定义为 模型上的方法,这些方法最后调用


中,如果
xvent\u hood
需要相等
xvent\u plunum
,也许你应该做一个
xvent\u hood=xvent\u plunum
。但它们并不总是相等的。xvent_静压箱应为真,xvent_罩应为假。请尝试使用
,除非
self.xvend\u hood=false,除非self.xvent\u plenum
。这似乎可行,但为什么在保存之前认为xvent\u hood为null?并不是在保存之前认为xvent\u hood为null,我相信发生的事情是,在调用保存之前,它没有通过验证。(假设您有适当的验证,也就是说,这是您的记录未保存的原因)在此处看到指向“保存前”文档的链接会很酷。这是正确答案,但您如何解决此问题?如何在before_save回调中将布尔值指定为false?要在before_save回调中将布尔值指定为false,请确保在回调结束时显式返回true。例如:
def before\u save(record)my\u false\u bool=false return true end
这是我第一次看到ruby表现出令人讨厌的行为,因为它忽略了诸如return之类的常规关键字。OMFG,这是令人沮丧的。
before_validation :reconcile_xvent

def reconcile_xvent
  if self.xvent_hood?
    self.xvent_hood = false unless xvent_plenum?
  end
end