【问题标题】:destroy_all not calling destroy on each object for has_many throughdestroy_all 没有通过 has_many 对每个对象调用destroy
【发布时间】:2013-09-23 19:20:59
【问题描述】:

我以这种方式设置了关联。

class Program
  has_many :program_activities, dependent: :destroy
  has_many :recent_activities, through: :program_activities, source: :recent_activity
end

class RecentActivity
  has_many :program_activities, dependent: :destroy        
end

我想删除与程序对象关联的recent_activities。

program.recent_activities.destroy_all

但上面的查询实际上只是删除(请注意删除而不是销毁)program_activities 并单独留下recent_activities 对象。

我通过检查 rails 控制台查询发现了这一点,destroy_all 方法是否有问题,或者我实际上是否错误地设置了关联。

【问题讨论】:

  • 通过查看rails代码activerecord-4.2.11/lib/active_record/associations/has_many_through_association.rb#211,它调用delete方法,这意味着它直接从数据库中删除记录。如果你想触发destroy,考虑使用has_many而不使用through。在activerecord-4.2.11/lib/active_record/associations/has_many_association.rb#169中,会调用destory!方法。

标签: ruby-on-rails ruby-on-rails-3 activerecord ruby-on-rails-3.2


【解决方案1】:

对我来说没有错,在多对多关系中很正常。

如果recent_activity 与一个且仅一个program 相关,则不应有program_activities 关系模型。您只需要使用带有 belongs_to :program 的 RecentActivity 即可删除。

在您的情况下,您认为recent_activity 可能有多个programs。所以删除program 不能删除recent_activity 实体,因为根据定义,它可以属于多个程序。它只会删除关系。

【讨论】:

    【解决方案2】:

    我认为没有错。通常,您可以在销毁模型行时删除关联表。

    假设这种情况:

    1. 组 has_many group_members

    2. 成员 has_many group_members

    3. 通过 group_members 组有_many 个成员

    4. 通过 group_members 成为成员 has_many 个组

    是不是说我们销毁了一个group,相关的成员也应该被销毁?它们是独立的模型行,即使没有任何组。也许他们属于其他群体。如果被级联破坏,数据表就会乱七八糟。

    希望这个例子可以解释逻辑。

    【讨论】:

      【解决方案3】:

      最近遇到了这个问题,这就是最终为我工作的原因:

      program.program_activities.each { |activity| activity.recent_activity.destroy }
      

      不完全简洁,但由于 destroy_all 方法没有达到您的预期,这可能是最好的。它确实会触发销毁,因此在您的情况下,它将与之关联。如果您没有设置了依赖::destroy,您将获得外键违规。

      【讨论】:

        猜你喜欢
        • 2023-03-15
        • 1970-01-01
        • 1970-01-01
        • 2012-04-19
        • 1970-01-01
        • 1970-01-01
        • 2016-10-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多