如何避免ActiveRecord模型双省电? [英] How to avoid ActiveRecord model double saving?
问题描述
模型一
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-轨道的方式来实现两种模式,必须改变对方before_save回调?
Infinite loop will start. What would be most ruby-on-rails way to implement two models that must change each other on before_save callback?
推荐答案
在你需要做这样的希望极少数情况下,您可能需要使用禁用的 before_save
过滤器一个 attr_accessor
或将其移动到 after_save的
块,以避免循环。
On the hopefully rare occasions you need to do this, you might want to disable your before_save
filter using an attr_accessor
or move it to an after_save
block to avoid looping.
例如:
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
您想禁用它们中的至少一个触发:
You'd disable the trigger on at least one of them:
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
像这样的事情总是很难看,所以要尽量避免它,除非你能想到的任何其他方式。如果你需要它,确保你已经写了足够的单元测试,以确保它不会在某些边缘情况下锁定一个死循环。
Things like this are always very ugly, so try and avoid it unless you can think of no other way. If you need it, make sure you've written enough unit tests to ensure it won't lock into an endless loop under some edge cases.
这篇关于如何避免ActiveRecord模型双省电?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!