Rails 组合多个多态 has_many 关联
Rails combine multiple polymorphic has_many associations
我有一个名为 Organization
的模型,它有许多 teams
和许多 collaborations
。一个Collaboration
也有很多teams
。因此团队模型与 Organization
和 Collaboration
.
具有多态关联
我想做的是 organization.teams
并反映组织中的所有团队和组织中协作的所有团队。
表格
*organizations*
id
user_id
title
...
*collaborations*
id
organization_id
title
...
*teams*
id
teamable_id
teamable_type
title
...
型号
class Organization < ApplicationRecord
has_many :orgaization_teams, as: :teamable, class_name: "Team"
has_many :collaboration_teams, through: :collaborations, source: :teams, class_name: "Team"
end
class Collaboration < ApplicationRecord
belongs_to :organization
has_many :teams, as: :teamable
end
class Team < ApplicationRecord
belongs_to :teamable, polymorphic: true
belongs_to :organization, -> { joins(:teams).where(teams: {teamable_type: 'Organization'}) }, foreign_key: 'teamable_id'
belongs_to :collaboration, -> { joins(:teams).where(teams: {teamable_type: 'Collaboration'}) }, foreign_key: 'teamable_id'
end
尝试次数
尝试 #1
class Organization < ApplicationRecord
has_many :teams, -> { joins(:organization, :collaboration) }, source: :teamable
end
结果:
SystemStackError(堆栈级别太深)
尝试 #2
class Organization < ApplicationRecord
def teams
orgaization_teams.or(collaboration_teams)
end
end
结果:
ArgumentError(传递给#or 的关系必须在结构上兼容。不兼容的值:[:joins])
可能的解决方案
我正在考虑将 Team 上的多态关联分离到 organization_id
和 collaboration_id
所以新的 table 看起来像这样:
*teams*
id
organization_id
collaboration_id
title
...
我会使用两个单独的外键:
class Organization < ApplicationRecord
has_many :teams
has_many :collaborations
has_many :collaboration_teams,
through: :collaborations,
source: :team
end
class Collaboration < ApplicationRecord
belongs_to :organization
has_many :teams
end
class Team < ApplicationRecord
belongs_to :team, optional: true
belongs_to :organization, optional: true
end
如果您想获得直接属于您想要的组织或其协作的团队:
Team.where(
organization_id: org.id
).or(
Team.where(
collaboration_id: org.collaborations
)
)
我认为这实际上不能写成关联,因为它的结构太复杂了。
我有一个名为 Organization
的模型,它有许多 teams
和许多 collaborations
。一个Collaboration
也有很多teams
。因此团队模型与 Organization
和 Collaboration
.
我想做的是 organization.teams
并反映组织中的所有团队和组织中协作的所有团队。
表格
*organizations*
id
user_id
title
...
*collaborations*
id
organization_id
title
...
*teams*
id
teamable_id
teamable_type
title
...
型号
class Organization < ApplicationRecord
has_many :orgaization_teams, as: :teamable, class_name: "Team"
has_many :collaboration_teams, through: :collaborations, source: :teams, class_name: "Team"
end
class Collaboration < ApplicationRecord
belongs_to :organization
has_many :teams, as: :teamable
end
class Team < ApplicationRecord
belongs_to :teamable, polymorphic: true
belongs_to :organization, -> { joins(:teams).where(teams: {teamable_type: 'Organization'}) }, foreign_key: 'teamable_id'
belongs_to :collaboration, -> { joins(:teams).where(teams: {teamable_type: 'Collaboration'}) }, foreign_key: 'teamable_id'
end
尝试次数
尝试 #1
class Organization < ApplicationRecord
has_many :teams, -> { joins(:organization, :collaboration) }, source: :teamable
end
结果: SystemStackError(堆栈级别太深)
尝试 #2
class Organization < ApplicationRecord
def teams
orgaization_teams.or(collaboration_teams)
end
end
结果: ArgumentError(传递给#or 的关系必须在结构上兼容。不兼容的值:[:joins])
可能的解决方案
我正在考虑将 Team 上的多态关联分离到 organization_id
和 collaboration_id
所以新的 table 看起来像这样:
*teams*
id
organization_id
collaboration_id
title
...
我会使用两个单独的外键:
class Organization < ApplicationRecord
has_many :teams
has_many :collaborations
has_many :collaboration_teams,
through: :collaborations,
source: :team
end
class Collaboration < ApplicationRecord
belongs_to :organization
has_many :teams
end
class Team < ApplicationRecord
belongs_to :team, optional: true
belongs_to :organization, optional: true
end
如果您想获得直接属于您想要的组织或其协作的团队:
Team.where(
organization_id: org.id
).or(
Team.where(
collaboration_id: org.collaborations
)
)
我认为这实际上不能写成关联,因为它的结构太复杂了。