我有两个AR模型和第三个has_many :through
连接模型,如下所示:
class User < ActiveRecord::Base
has_many :ratings
has_many :movies, through: :ratings
end
class Movie < ActiveRecord::Base
has_many :ratings
has_many :users, through: :ratings
end
class Rating < ActiveRecord::Base
belongs_to :user
belongs_to :movie
after_destroy do
puts 'destroyed'
end
end
有时,用户会希望直接放下电影(而不会直接破坏分级)。但是,当我这样做时:
# puts user.movie_ids
# => [1,2,3]
user.movie_ids = [1, 2]
尽管已正确删除了联接记录,但未调用分级的
after_destroy
回调。如果我这样修改用户模型:class User < ActiveRecord::Base
has_many :ratings
has_many :movies,
through: :ratings,
before_remove: proc { |u, m| Rating.where(movie: m, user: u).destroy_all }
end
一切正常,但这确实很丑陋,Rails然后尝试第二次删除联接模型。
如何为这种关联使用
dependent: :destroy
策略,而不是dependent: :delete
?
最佳答案
回答我自己的问题,因为这对Google来说很困难,而且答案是违反直觉的(尽管我不知道理想的界面是什么)。
首先,在这里对情况进行详细描述:https://github.com/rails/rails/issues/7618。但是,特定的答案埋在页面的大约中间,问题已经解决(即使在当前的Rails版本中仍然是问题)。
您可以通过向dependent: :destroy
命令添加选项,为这些类型的联接模型破坏指定has_many :through
,如下所示:
class User < ActiveRecord::Base
has_many :ratings
has_many :movies,
through: :ratings,
dependent: :destroy
end
这是违反直觉的,因为在正常情况下,
dependent: :destroy
将破坏该特定关联的对象。例如,如果我们在此处使用
has_many :ratings, dependent: :destroy
,则当该用户被销毁时,该用户的所有评分都将被销毁。我们当然不希望破坏此处的特定电影对象,因为其他用户/分级可能正在使用它们。但是,Rails神奇地知道,在这种情况下,我们要销毁联接记录,而不是销毁关联记录。
关于ruby-on-rails - Rails没有通过join模型运行has_many的destroy回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30629680/