【问题标题】:Ruby on Rails: two has_many same_models :through => different_modelRuby on Rails:两个 has_many same_models :through => different_model
【发布时间】:2026-02-23 17:45:01
【问题描述】:

我想在同一个模型上创建 2 个 has_many,但它通过不同的模型(这是一个连接表)

代码如下:

class Content
  belongs_to :dis
  belongs_to :fac

  has_many :dis_representations, :through => :dis
  has_many :fac_representations, :through => :fac
end

class Fac
  has_many :fac_representations
  has_many :contents
end

class Dis
  has_many :dis_representations
  has_many :contents
end

class DisRepresentation
  belongs_to :user, :foreign_key => "e_user_id"
  belongs_to :dis
end

class FacRepresentation
  belongs_to :user, :foreign_key => "e_user_id"
  belongs_to :fac
end

class User
  has_many :dis_representations, :foreign_key => "e_user_id"
  has_many :fac_representations, :foreign_key => "e_user_id"
  has_many :dises, :through => :dis_representations
  has_many :facs, :through => :fac_representations
  has_many :contents, :through => :dises, :source => :contents
  has_many :contents, :through => :facs :source => :contents
end

现在我想这样做:

User.first.contents

如果我这样做,它几乎可以工作。唯一的问题是只有第二个 has_many :contents 被调用。

现在我可以通过创建这样的方法来解决它:

def contents
    (dises + facs).map(&:contents).flatten
end

但是,如果我执行上述操作,我会失去所有内容范围,因为内容会变成一个简单的数组。

有没有办法解决这个问题?也许我使用了完全错误的方法。还有其他方法吗?

谢谢

【问题讨论】:

  • 乍一看,您似乎有很多模型。你真的需要那么多吗?我假设您希望能够拉出第一个 :content ,无论它是 dis 内容还是 fac 内容。
  • 我希望我可以使用更少的模型 :P 无论如何,你是对的,我想获得内容而不考虑 dis 和 fac。它是同一个类,但 dis 和 fac 是不同类型的内容所有者。

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


【解决方案1】:

如果 dis 和 fac 模型没有显着差异,那么您可以将它们折叠成一组模型并引入一个“type”属性,让您可以区分这些不同类型的内容。然后你在尝试查询它时不会有问题(它只会在你想编写更复杂的查询时变得更糟),并且当你想添加更多内容类型时它会扩展。

【讨论】:

  • 好建议,但是,尽管 Dis 和 Fac 具有相同的架构,但它们包含完全不同的数据,并且这些数据必须链接到相同的内容。内容必须始终同时具有 fac 和 dis ,我不需要扩展,因为我只使用这两个属性之一来确定用户的所有权。我还需要知道哪一个适用于用户(如果不是两者都适用),所以我不能以这种方式更改我的架构。
【解决方案2】:

我会为内容关联使用两个不同的名称,例如 dis_contents 和 fac_contents。

如果您想通过单个关联检索所有 Content 对象,您应该更改关联并使用多态连接表。

也许这个例子会有所帮助

has_many :through + polymorphic relationships

【讨论】: