Rails多对多:通过关联:在销毁关联对象后不会更新关联对象

时间:2012-10-14 12:12:03

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

由于我是Rails的新手,可能会有一个简单的解决方案。但我甚至无法在某个地方找到这个问题。其他帖子涉及destroy vs. delete(我尝试了两个相同的结果)或者只是没有提到关联对象的行为。

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

我的例子:

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

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

3 个答案:

答案 0 :(得分:2)

你应该做:dependent => :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

答案 1 :(得分:1)

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

dependent: destroy

将在相关对象上调用destroy

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

答案 2 :(得分:0)

我猜问题可能是这样的。在您的示例中,

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查看是否存在任何差异。