I'm trying to create a 4 way joins 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
When I create I get 2 separate entries into the UserConfiguration Table.
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.
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 way joins introduce quite a bit of complexity as you cannot simply unlink two records by deleting a row in the join table. And ActiveRecord does not automatically keep track of the foreign key columns.
If you want to add roles to this data model there are a few ways to do it:
# join model between User and Team
class Position
enum role: [:grunt, :supervisor]
belongs_to :user
belongs_to :team
end
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.