【问题标题】:Rails many-to-many :through association: associated object is not updated after destroying the association objectRails 多对多:通过关联:销毁关联对象后关联对象不更新
【发布时间】:2012-10-14 12:12:03
【问题描述】:

由于我是 Rails 新手,可能有一个简单的解决方案。但我什至无法在某个地方找到这个确切的问题。其他帖子涉及销毁与删除(我都尝试了相同的结果),或者只是不提及关联对象的行为方式。

我的问题:我想通过 :through 创建一个多对多关联。当我删除一个关联(即关系对象,而不是相关对象)时,我希望在关联对象的所有模型实例中删除(更新)该关联。但这并没有完全发生。

我的例子:

Meeting < ActiveRecord::Base
  has_many :participations
  has_many :users, :through => :participations

User < ActiveRecord::Base
  has_many :participations
  has_many :meetings, :through => :participations

Participation < ActiveRecord::Base
  belongs_to :meeting, :foreign_key => :meeting_id
  belongs_to :user, :foreign_key => :user_id

当我创建一个新的关联时,关联的对象会相应地更新:

u = User.find(...)
m = Meeting.find(...)
m.users<< u

以这种方式创建关联时相同:

m.participations.create(:user_id => u.id)  # this requires to make the user_id attribute accessible

当我现在查看关联的用户模型实例时,它已按预期更新:

u.meetings >> contains the newly created association to the meeting m

当我销毁(而不是删除!)这个关联时,关联的对象并没有像我预期的那样更新:

m.users.find_by_user_id(u.id).destroy
m.users >> []
u.meetings >> still contains the destroyed association to meeting m

我预计 u.meetings 已更新且为空 ([])。添加验证无助于解决这个问题:

Meeting < ActiveRecord::Base
  validates_associated :contacts
or
Participation < ActiveRecord::Base
  validates_presence_of :contact, :interview

我做错了什么或者我在这里错过了什么?

我正在使用 Rails 3.2.8

感谢所有愿意帮助我的人。

【问题讨论】:

    标签: ruby-on-rails models has-many


    【解决方案1】:

    你应该做:dependent =&gt; :destroy

    Meeting < ActiveRecord::Base
      has_many :participations, :dependent => :destroy
      has_many :users, :through => :participations
    
    User < ActiveRecord::Base
      has_many :participations, :dependent => :destroy
      has_many :meetings, :through => :participations
    
    Participation < ActiveRecord::Base
      belongs_to :meeting, :foreign_key => :meeting_id
      belongs_to :user, :foreign_key => :user_id
    

    如果关联的用户或会议被销毁,这将确保销毁participation

    【讨论】:

    • 对不起,我没有提到。但我也试过了。我还检查了所有回调和参与。before_destroy 和参与。after_destroy 被触发。但是,如果我打电话给 u.meetings 它并不像预期的那样为空。它仍然包含刚刚销毁的关联。它在 db 中被删除,但不会从 u 实例的会议枚举中删除。
    • 我认为您正在查看缓存的数据。尝试做u.reload,然后尝试u.meetings
    • 好的,非常感谢。两种方法u.reloadu.meetings(true) 都按预期工作并刷新(先前实例化的)用户对象u。只是为了了解 Rails:为什么 u 实例在创建关联后更新,但在销毁后没有更新。有什么有意义的理由吗?这样,我总是必须刷新实例以确保不显示过时的信息。
    【解决方案2】:

    您应该使用以下关系选项更新您的model

    dependent: destroy
    

    它将在关联对象上调用destroy

    参考:http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#label-Deleting+from+associations

    【讨论】:

      【解决方案3】:

      我想问题可能是这样的。在你的例子中,

      m.users.find_by_user_id(u.id).destroy
      m.users >> []
      u.meetings >> still contains the destroyed association to meeting m
      

      uu.meetings 已在 m.users.find_by_user_id(u.id).destroy 之前加载。然后u.meetings输出缓存的数据。

      你可以试试u.meetings(true)或者u.reload; u.meetings看看有没有区别。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-10
        • 2014-01-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多