我有一个与另一个模型有belongs_to
关系的Rails模型。
class Foo < ActiveRecord::Base
belongs_to :bar
end
每次bar
设置/更新foo
我想要“拦截”修改后的更改并更新foo
上的内容。
我的猜测是,我可以覆盖bar
的setter并按照我的意愿行事。但是,由于我对Ruby / Rails相对较新,我担心的是bar
可以在foo
设置的“{魔法”方式,而不是通过我的二传手(也许)使用mass-assignment,update / update_all调用等)。
确保对bar
的任何更改运行一个代码块以对此更改做出反应的最安全的方法是什么?
答案 0 :(得分:1)
根据您的需要,您可以使用条形图上的回调来执行foo上的特定代码。
您需要的所有文档都在http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
例如:
class Bar < ActiverRecord::Base
has_many :foos
before_save :do_something
private
def do_something
self.foos.each {|f| f.update_attribute('bar_has_changed', true) }
end
end
答案 1 :(得分:1)
覆盖bar
的setter并不是一个好主意。
案例:
class Foo < ActiveRecord::Base
belongs_to :bar
def bar=(value)
# do nothing
end
end
f = Foo.create
b = Bar.create
f.update_attributes(bar_id: b.id)
f.bar
# => #<Bar id: 1, ... >
虽然bar
setter已被覆盖,因此它什么都不做,但你可以很容易地绕过它。您在Foo
上实现的任何自定义更新都是如此:在这种情况下,更新关联时不会调用它。
改为使用回调。