has_many :通过多个连接 table
has_many :through multiple joins table
我正在尝试创建 4 路连接 table。
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
创建时,我在 UserConfiguration Table 中获得了 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
我不知道尝试这样的事情是否是个好习惯任何建议都会很有帮助谢谢。每次搜索都会尝试执行 sql 连接以查询数据。
编辑:决定不这样做,并将尝试找出不同的方法。
我会用间接关系来设置它:
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
虽然您可能会使用单一的 3 路连接模型,但这违反了单一职责原则并且不能很好地映射域。
3 种方式的连接引入了相当多的复杂性,因为您不能简单地通过删除连接中的一行来解除两个记录的链接 table。并且 ActiveRecord 不会自动跟踪外键列。
如果您想将角色添加到此数据模型,可以通过以下几种方法实现:
1 添加一个 enum 到联接 table:
# join model between User and Team
class Position
enum role: [:grunt, :supervisor]
belongs_to :user
belongs_to :team
end
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
这是一个非常灵活的系统,可让您将角色附加到任何事物 - 公司、团队等。并让您构建角色甚至可以由最终用户定义的系统。查看 rolify gem 以获得完整示例。
我正在尝试创建 4 路连接 table。
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
创建时,我在 UserConfiguration Table 中获得了 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
我不知道尝试这样的事情是否是个好习惯任何建议都会很有帮助谢谢。每次搜索都会尝试执行 sql 连接以查询数据。
编辑:决定不这样做,并将尝试找出不同的方法。
我会用间接关系来设置它:
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
虽然您可能会使用单一的 3 路连接模型,但这违反了单一职责原则并且不能很好地映射域。
3 种方式的连接引入了相当多的复杂性,因为您不能简单地通过删除连接中的一行来解除两个记录的链接 table。并且 ActiveRecord 不会自动跟踪外键列。
如果您想将角色添加到此数据模型,可以通过以下几种方法实现:
1 添加一个 enum 到联接 table:
# join model between User and Team
class Position
enum role: [:grunt, :supervisor]
belongs_to :user
belongs_to :team
end
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
这是一个非常灵活的系统,可让您将角色附加到任何事物 - 公司、团队等。并让您构建角色甚至可以由最终用户定义的系统。查看 rolify gem 以获得完整示例。