模特“一”
class One < ActiveRecord::Base
before_save :do_stuff
private
def do_stuff
two = Two.find(8)
two.field2 = 'Value'
two.save!
end
end
模型“两个”
class Two < ActiveRecord::Base
before_save :do_stuff
private
def do_stuff
one = One.find(7)
one.field2 = 'SomeValue'
one.save!
end
end
执行:
two = Two.find(1)
two.somefield = 'NewVal'
two.save!
无限循环将开始。什么是ruby-on-rails方式实现两个必须在before_save回调中互相改变的模型?
答案 0 :(得分:2)
在极少数情况下,您需要执行此操作,您可能希望使用before_save
停用attr_accessor
过滤器,或将其移至after_save
块以避免循环。
例如:
class One < ActiveRecord::Base
attr_accessor :not_doing_stuff
before_save :do_stuff,
:unless => :not_doing_stuff
private
def do_stuff
two = Two.find(8)
two.field2 = 'Value'
two.save!
end
end
您至少在其中一个上禁用触发器:
class Two < ActiveRecord::Base
before_save :do_stuff
private
def do_stuff
one = One.find(7)
one.not_doing_stuff = true
one.field2 = 'SomeValue'
one.save!
end
end
这样的事情总是非常难看,所以尽量避免它,除非你能想到别的办法。如果您需要它,请确保您已经编写了足够的单元测试,以确保在某些边缘情况下它不会锁定无限循环。
答案 1 :(得分:1)
不要在before_save中调用save
:它会触发无限循环。返回true或false - 如果你在before_save中输入的内容成功,则返回true,如果失败则返回false。返回false将取消保存和所有其他回调。