简体   繁体   English

has_many :通过多个连接表

[英]has_many :through multiple joins table

I'm trying to create a 4 way joins table.我正在尝试创建一个 4 路连接表。

class User < ApplicationRecord
  has_many :user_configurations
  has_many :teams, through: :user_configurations
  has_many :companies, through: :user_configurations

  scope :supervisors, -> { joins(:user_configurations).where(user_configurations: { supervisor: true }) }
  scope :agents, -> { joins(:user_configurations).where(user_configurations: { supervisor: false }) }
end

class Team < ApplicationRecord
  has_many :user_configurations
  has_many :users, through: :user_configurations
  belongs_to :company_unit
end

class CompanyUnit < ApplicationRecord
  has_many :user_configurations
  has_many :users, through: :user_configurations
  has_many :teams
  belongs_to :company
end

class Company < ApplicationRecord
  has_many :user_configurations
  has_many :users, through: :user_configurations
  has_many :company_units
  has_many :teams, through: :company_units
end

class UserConfiguration < ApplicationRecord
  belongs_to :user, optional: true
  belongs_to :team, optional: true
  belongs_to :company, optional: true
  #supervisor:boolean in this table
end

When I create I get 2 separate entries into the UserConfiguration Table.当我创建时,我在 UserConfiguration 表中获得了 2 个单独的条目。

Company.first.users.create(team_ids: [1])

id: 1, user_id: 1, team_id: nil, company_id: 1

id: 2, user_id: 1, team_id: 1, company_id: nil

I don't know if it's good practice to attempt something like this any suggestions will be really helpful thanks.我不知道尝试这样的事情是否是一种好习惯,任何建议都会非常有帮助,谢谢。 Every search results in trying to do a sql join to query data.每个搜索都会导致尝试执行 sql 连接来查询数据。

EDIT: Decided not to do this and will try and figure out a different approach.编辑:决定不这样做,并会尝试找出不同的方法。

I would set it up with indirect relationships instead:我会用间接关系来设置它:

class User
  has_many :employments
  has_many :companies, through: :employments
  has_many :positions
  has_many :teams, through: :positions
end

class Company
  has_many :employments
  has_many :users, through: :employments
  has_many :teams, through: :users
end

class Team
  has_many :positions
  has_many :users, through: :positions
  has_many :companies, through: :users
end

# join model between User and Company
class Employment
  belongs_to :user
  belongs_to :company
end

# join model between User and Team
class Position
  belongs_to :user
  belongs_to :team
end

While you could potentially use a single 3 way join model this violates the Single Responsibility Principle and does not map the domain very well.虽然您可能会使用单一的 3 路连接模型,但这违反了单一职责原则并且不能很好地映射域。

3 way joins introduce quite a bit of complexity as you cannot simply unlink two records by deleting a row in the join table. 3 路连接引入了相当多的复杂性,因为您不能通过删除连接表中的一行来简单地取消两条记录的链接。 And ActiveRecord does not automatically keep track of the foreign key columns.并且 ActiveRecord 不会自动跟踪外键列。

If you want to add roles to this data model there are a few ways to do it:如果你想向这个数据模型添加角色,有几种方法可以做到:

1 add an enum to the join table: 1 向连接表添加一个枚举

# join model between User and Team
class Position
  enum role: [:grunt, :supervisor]
  belongs_to :user
  belongs_to :team
end

2 create a reusable role system. 2 创建可重用的角色系统。

class User
  has_many :user_roles
  has_many :roles, through: :user_roles

  def has_role?(name, resource = nil)
    roles.exists?(name: name, resource: resource)
  end
end

class Role
  belongs_to :resource, polymorpic: true, optional: true
  has_many :user_roles
end

class UserRole
  belongs_to :user
  belongs_to :role
end

This is a really flexible system lets you attach roles to anything - companies, teams etc. And lets you build systems where the roles can even by defined by end users.这是一个非常灵活的系统,可以让您将角色附加到任何东西 - 公司、团队等。并且可以让您构建系统,其中角色甚至可以由最终用户定义。 Check out the rolify gem for a full example.查看rolify gem以获取完整示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM