【问题标题】:Rails isn't running destroy callbacks for has_many through join modelRails 没有通过连接模型为 has_many 运行销毁回调
【发布时间】:2015-08-18 05:29:36
【问题描述】:

我有两个 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

【问题讨论】:

  • from doco 如果与:through选项一起使用,连接模型上的关联必须是belongs_to,并且被删除的记录是连接记录,而不是比关联的记录

标签: ruby-on-rails ruby-on-rails-4 rails-activerecord


【解决方案1】:

回答我自己的问题,因为这对 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 神奇地知道我们要销毁的是连接记录,而不是关联记录。

【讨论】:

  • 投票赞成清楚地解释意图......谁知道这是意图。但我同意你的想法!
  • 非常感谢,你拯救了我的一天,
猜你喜欢
  • 1970-01-01
  • 2010-11-20
  • 2015-06-01
  • 2012-05-16
  • 2014-07-25
  • 1970-01-01
  • 2017-02-21
  • 2015-09-28
  • 2017-11-05
相关资源
最近更新 更多