Rails - 3列关联表?

时间:2012-08-07 14:40:53

标签: ruby-on-rails ruby-on-rails-3 activerecord model

我目前正在尝试在Rails中创建一个相当简单的关联,但事实证明它比我想象的要困难。

我有3个型号,用户,经销商和角色。用户/经销商是多对多的。用户可以拥有多个角色,但他们应该专注于经销商 - 即用户可以在一个经销商处拥有角色经理和主管,在另一个经销商处拥有经理,在另一个经销商中担任主席。

我正在寻找的结果是,我将能够user.dealer.roles和(例如,对于第一个经销商)它将返回经理和主管。如果我做dealer.user.roles.

.


My classes look as follows:

class User  :dealer_users
  has_many :dealer_user_roles, :through => :dealer_users
  has_many :roles, :through => :dealer_user_roles
end

class Dealer  :dealer_users
  has_many :dealer_user_roles, :through => :dealer_users
  has_many :roles, :through => :dealer_user_roles
end

class Role  :dealer_user_roles
  has_many :users, :through => :dealer_users
end

The tables look like (green tables):

Model diagram

I am trying to seed the database using the following code:

,也会发生同样的情况

这会导致错误,即:“无法修改关联'用户#角色',因为它会经历多个其他关联。”

任何人都可以通过告诉我哪里出错了,以及我怎么能把它弄错了?

1 个答案:

答案 0 :(得分:4)

在我的头顶,我会把它建模为:

# Table name: users
#  id          :integer  not null, primary key
#  name        :string
class User
  has_many :employments
  has_many :dealers, :through => :employments
  has_many :roles, :through => :employments
end

# Table name: dealers
#  id          :integer  not null, primary key
#  name        :string
class Dealer
  has_many :employments
  has_many :users, :through => :employments
  has_many :roles, :through => :employments
end

# Table name: employments
#  id          :integer  not null, primary key
#  user_id     :integer  not null
#  dealer_id   :integer  not null
class Employment
 belongs_to :dealer, :inverse_of => :employments
 belongs_to :user,   :inverse_of => :employments
 has_many :roles
 scope :for_user,   lambda{ |user| where(:user_id => user.id) }
 scope :for_dealer, lambda{ |dealer| where(:dealer_id => dealer.id) }
end

# Table name: roles
#  id             :integer   not null, primary key
#  employment_id  :integer   not null
#  name           :string    not null
class Role
  belongs_to :employment
  scope :at_dealership, lambda{ |dealer| joins(:employment).where(:dealer_id => dealer.id) }
  scope :for_employee,  lambda{ |employee| joins(:employment).where(:user_id => employee.id) }
  # alternately:
  # scope :at_dealership, lambda{ |dealer| joins(:employment).where('employments.dealer_id = ?', dealer.id) }
  # scope :for_employee,  lambda{ |employee| joins(:employment).where('employments.user_id = ?',employee.id) }
end

这使我们更容易处理,并将角色放在他们实际所属的位置 - 与我称之为就业的用户/经销商的组合。

然后你可以说

dealer.users.first.roles 
# or
user.dealers.where('some condition').roles

编辑:使用范围所有这些应该做你想要的。

user = User.first
dealer = user.dealers.first

user.roles.at_dealership(dealer)

dealer.roles.for_employee(user)

dealer.employments.for_user(user).roles

user.employments.for_dealer(dealer).roles