3个模特:用户,电影,喜欢
User has_many :likes
User has_many :movies, through: :likes
此代码:
user.movies = [ m1, m2, m3 ]
为与用户和m1 / m2 / m3相关的新Like#after_create
记录调用Like
。然后,这段代码:
user.movies = [ m3, m4 ]
不会针对将用户与m1 / m2相关联的Like#after_destroy
记录调用Like
,但会针对与m4的新关系调用Like#after_create
。
movies
集合可以手动设置,也可以使用包含user[movie_ids]
个复选框的表单设置,然后
user.update_attributes(params[:user])
正如@jdoe从文档中引用的那样,在分配新集合或从集合中删除时(user.movies.delete(m1)
)无法实现。唯一的方法是在用户模型上使用before_remove
/ after_remove
回调(如果是多态关系 - 任何其他模型),使用has_many
定义:
has_many :movies, through: :likes, before_remove: :before_like_destroy, after_remove: after_like_destroy
def before_like_destroy(movie)
like = self.likes.where(movie_id: movie)
# trigger the after_destroy on like
like.trigger_before_destroy # to be implemented on like, should call what the original callbacks contained
end
def after_like_destroy(movie)
# no way to get Like object here because it was already removed, need to remember it on the before_destroy somehow
end
无法理解它背后的逻辑。它使关系模型的回调完全无用。如果在after_create
上发生了某些事情,则无法在after_destroy
中撤消,因为更好的做法是将逻辑放在一起之前和之后,而不是单独放置,这会使所有回调都无效。
想想我会写一个自动化的宝石。
答案 0 :(得分:3)
根据文件:
collection = objects
通过删除和添加对象来替换集合内容 适当。如果:through选项是连接中的真回调 模型被触发除了销毁回调,因为删除是 直接
答案 1 :(得分:0)
如果你将like :: destroy添加到like和movie关联中,它会调用after_destroy回调