Rails:如何使用before_save根据另一个字段更改字段值?

cro*_*don 14 activerecord ruby-on-rails-3

我正在尝试根据另一个布尔字段的值将布尔字段设置为false.我使用ActiveRecord模型尝试了以下内容:

  before_save :reconcile_xvent

  def reconcile_xvent
    self.xvent_hood = false if !self.xvent_plenum?
  end
Run Code Online (Sandbox Code Playgroud)

但这不起作用.现在,我的许多单元测试失败了:

ActiveRecord::RecordNotSaved: ActiveRecord::RecordNotSaved
Run Code Online (Sandbox Code Playgroud)

如果xvent_plenum为false,如何将xvent_hood设置为false?

更新

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

before_validation :reconcile_xvent

def reconcile_xvent
  if self.xvent_hood?
    self.xvent_hood = false unless xvent_plenum?
  end
end
Run Code Online (Sandbox Code Playgroud)

如果没有"if self.xvent_hood",我无法让它工作.部分....

Ken*_* Li 19

before_save是只有验证通过后调用.你需要做的是向上移动而不是reconcile_xvent向上移动before_validationbefore_save

如果你保持那个方法before_save将会发生的事情是它认为xvent_hood是null,如果你有一个验证检查xvent_hood它的无效,它将在before_save被调用之前失败.这可能解释了为什么你有RecordNotSaved错误.

要记住的另一件事是,如果你有一个布尔属性,你也不能使用validate_presence_of.见http://alexanderwong.me/post/16084280769/rails-validate-presence-of-boolean-and-arrays-mongoid


lya*_*ard 18

我也遇到了这个问题,第一个代码块的问题是你将xvent_hood值赋值为false,然后由before_save方法返回.

按照

取消回调

如果before_*回调返回false,则取消所有后续回调和相关操作.如果after_*回调返回false,则取消所有后续回调.回调通常按照定义的顺序运行,但回调定义为模型上的方法(最后调用).

来自http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html

  • 要在before_save中将布尔值赋值为false,请确保在回调结束时显式返回true.例如:`def before_save(record)my_false_bool = false return true end` (2认同)