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

时间:2012-08-02 17:46:07

标签: 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

如果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

如果没有“if self.xvent_hood”,我无法让它发挥作用?部分....

2 个答案:

答案 0 :(得分:18)

验证通过后,

before_save 被调用。您需要做的是将reconcile_xvent移至before_validation而不是before_save

如果你将该方法保留在before_save中会发生什么,它认为xvent_hood为空,如果你有一个检查xvent_hood的无效的验证,它将在before_save被调用。这可能解释了为什么出现RecordNotSaved错误。

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

答案 1 :(得分:18)

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

按照

  

取消回调

     

如果before_ *回调返回false,则所有后来的回调和   相关操作已取消。如果after_ *回调返回false,   所有后来的回调都被取消了。回调通常在运行   它们的定义顺序,但定义为的回调除外   模型上的方法,最后称为。

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