【问题标题】:Rails: three-way has_many/through relationship: prevent duplicate join items creationRails:三向has_many/through关系:防止创建重复的连接项
【发布时间】:2013-12-04 03:23:38
【问题描述】:

这是我所拥有的模型的摘录:

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 &lt;&lt; user_a) 时,ActiveRecord 会自动创建参与。 我希望在将同一用户添加到该组的子组(subgroup_1.users &lt;&lt; user_asubgroup_1 的子组 group_a 的子组)时重复使用相同的参与。

实际发生的情况是 ActiveRecord 试图创建一个新的参与记录,它与之前创建的记录冲突 (validates_uniqueness_of :group_id, :scope =&gt; [:user_id] 引发错误)。

无论如何我可以完成这项工作吗?我尝试挂钩 before_validation、before_save 和其他一些东西,但每次尝试都失败了。

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

欢迎任何帮助。

谢谢,

大卫

【问题讨论】:

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


    【解决方案1】:

    你可以通过调用来干掉你所有的代码

    class User < ActiveRecord::Base
      has_many :participations
      has_many :groups, through: :participations
      has_many :subgroups, through: :groups # HMT -> HMT
    end
    

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

    【讨论】:

    • 感谢您的回答。我不确定它会起作用,或者我不明白你的建议。每个订阅用户在订阅时被放置在一个组中,但没有子组。稍后,当该组的订阅结束时,管理员会为该组创建多个子组,然后将每个用户置于其中一个子组中。在这种情况下,恐怕我看不出has_many :subgroups, through: :groups 是如何工作的。我错过了什么吗?
    猜你喜欢
    • 1970-01-01
    • 2015-02-01
    • 2013-07-07
    • 2011-04-27
    • 2014-07-13
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 2012-09-18
    相关资源
    最近更新 更多