Rails:三向has_many / through关系:防止重复的连接项创建

时间:2013-12-04 03:23:38

标签: ruby-on-rails activerecord has-many-through

以下是我所拥有的模型的摘录:

class User < ActiveRecord::Base
  has_many :participations
  has_many :groups, through: :participations
  has_many :subgroups, through: :participations
end

class Group < ActiveRecord::Base
  has_many :participations
  has_many :users, through: :participations
  has_many :subgroups
end

class Subgroup < ActiveRecord::Base
  has_many :participations
  has_many :users, through: :participations
end

class Participation < ActiveRecord::Base
  belongs_to: :user
  belongs_to: :group
  belongs_to: :subgroup

  validates :user, presence: true
  validates :group, presence: true
  # Subgroup can be empty, as long as user as not been placed.

  # There should be only one participation per couple User:Group
  validates_uniqueness_of :group_id, :scope => [:user_id]

  # Also has a state-machine, describing the participation status.
end

说明:组在子组中拆分,用户选择他们加入的组,但不选择稍后由管理员选择的子组。 将用户添加到组(group_a.users << user_a)时,ActiveRecord会自动创建参与。 我希望在将同一用户添加到该组的子组(subgroup_1.users << user_asubgroup_1子组group_a)时重复使用相同的参与。

实际上发生的事情是ActiveRecord尝试创建新的参与记录,该记录与先前创建的参与记录冲突(validates_uniqueness_of :group_id, :scope => [:user_id]  发生错误)。

无论如何我能做到这一点吗?我尝试了挂钩before_validation,before_save和其他一些东西,但每次尝试都失败了。

也许有更好的方法来实际模拟这种关系?

欢迎任何帮助。

谢谢,

大卫

1 个答案:

答案 0 :(得分:1)

您可以通过调用

来干掉所有代码
class User < ActiveRecord::Base
  has_many :participations
  has_many :groups, through: :participations
  has_many :subgroups, through: :groups # HMT -> HMT
end

这会解决您的问题吗? 可能不会扩展,但我们稍后会担心:)。