【问题标题】:Rails combine multiple polymorphic has_many associationsRails 结合了多个多态的 has_many 关联
【发布时间】:2021-04-15 23:00:08
【问题描述】:

我有一个名为 Organization 的模型,它有很多 teams 和很多 collaborations。一个Collaboration 也有很多teams。所以团队模型与OrganizationCollaboration 具有多态关联。

我想做的是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_idcollaboration_id

所以新表应该是这样的:

*teams*
id
organization_id
collaboration_id
title
...

【问题讨论】:

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


    【解决方案1】:

    我会使用两个单独的外键:

    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
      )
    )
    

    我认为这实际上不能写成一个关联,因为它的结构过于复杂。

    【讨论】:

      猜你喜欢
      • 2016-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多