有没有办法动态地将after_add
和after_remove
个回调添加到现有的has_many
或has_and_belongs_to_many
关系中?
例如,假设我有模型User
,Thing
和加入模型UserThingRelationship
,User
模型是这样的:
class User < ActiveRecord::Base
has_many :user_thing_relationships
has_many :things, :through => :user_thing_relationships
end
我希望能够在扩展User
的模块中,将:after_add
和:after_remove
个回调添加到User.has_many(:things, ...)
关系中。即,有类似
module DoesAwesomeStuff
def does_awesome_stuff relationship, callback
# or however this can be achieved...
after_add(relationship) callback
after_remove(relationship) callback
end
end
那样
class User < ActiveRecord::Base
has_many :user_thing_relationships
has_many :things, :through => :user_thing_relationships
does_awesome_stuff :things, :my_callback
def my_callback; puts "awesome"; end
end
实际上与
相同class User < ActiveRecord::Base
has_many :user_thing_relationships
has_many :things, :through => :user_thing_relationships, :after_add => :my_callback, :after_remove => :my_callback
def my_callback; puts "awesome"; end
end
这可以非常有效地添加after_save
等回调到正在扩展的模型,因为ActiveRecord::Base#after_save
只是一个类方法。
答案 0 :(得分:11)
最简单的是
User.after_add_for_things << lambda do |user, thing|
Rails.logger.info "#{thing} added to #{user}"
end
答案 1 :(得分:7)
我可以使用ActiveRecord::Reflection:
来提出以下内容module AfterAdd
def after_add rel, callback
a = reflect_on_association(rel)
send(a.macro, rel, a.options.merge(:after_add => callback))
end
end
class User < ActiveRecord::Base
extend AfterAdd
has_many :user_thing_relationships
has_many :things, :through => :user_thing_relationships
after_add :things, :my_callback
def my_callback
puts "Hello"
end
end
我不想回答我自己的问题,所以如果其他人能在接下来的几天内找到更好的解决方案,我也不会给自己回答。