has_one和has_many在同一个模型中。 rails如何跟踪它们?

时间:2009-09-26 07:02:35

标签: ruby-on-rails activerecord rails-models

即使它正常工作,我对这项工作有点困惑。我有一个与同一个其他模型有两个关联的模型。

公司拥有一个所有者和公司拥有许多类用户的员工。

这是我公司的模特:

class Company < ActiveRecord::Base
  validates_presence_of :name

  has_many :employee, :class_name => 'User'
  has_one :owner, :class_name => 'User'
  accepts_nested_attributes_for :owner, :allow_destroy => true
end

这是我的用户模型:

class User < ActiveRecord::Base
  include Clearance::User
  attr_accessible :lastname, :firstname #other attr are whitelisted in clearance gem
  validates_presence_of :lastname, :firstname
  belongs_to :company
end

现在假设我有这家公司的3名员工,包括业主。当我第一次创建公司时,我将所有者设置为id为1的员工,另外两个(2,3)通过设置他们的company_id(user.company = company)添加到员工列表中。这三个人都将他们的company_id设置为公司ID,我们可以假设为1

当我要求company.owner时,我得到了正确的用户,当我做公司工作时,我得到了所有三个。

如果我将所有者更改为用户2,则会通过将用户1的company_id设置为nil来自动从员工中删除用户1。这很好,如果我把他作为一个简单的员工加回来,一切都还不错。

如何确定哪个轨道知道哪个是哪个?我的意思是,它是如何知道员工是所有者而不仅仅是员工?架构中没有任何内容定义此内容。

我有一种感觉我应该扭转所有者协会并让公司属于用户。

3 个答案:

答案 0 :(得分:12)

正如您现在所知,没有什么可以区分所有者和员工。这意味着一旦您开始删除人员或尝试更改所有权,您就会遇到问题。

正如弗朗索瓦指出的那样,你只是幸运,因为所有者是属于ID最低的公司的用户。

要解决这个问题,我会让我的模型与以下方法有关。

class Company < ActiveRecord::Base
  belongs_to :owner, :class_name => "user"
  has_many :employees, :class_name => "user"
  validates_presence_of :name
  accepts_nested_attributes_for :owner, :allow_destroy => true
end

class User < ActiveRecord::Base
  include Clearance::User
  attr_accessible :lastname, :firstname #other attr are whitelisted in clearance gem
  validates_presence_of :lastname, :firstname
  belongs_to :company
  has_one :company, :foreign_key => :owner_id
end

您必须在Companies表中添加另一个名为owner_id的列,但这更清楚地定义了您的关系。并且将避免与更换所有者相关的任何麻烦。请注意,如果您使用此路由并设置数据库以使users.company_id和companies.owner_id都不能为空,则可能存在周期性依赖关系。

我不太确定accepts_nested_attributes_for与belongs_to关系有多好。

答案 1 :(得分:5)

has_one是语法糖:

has_many :whatevers, :limit => 1

有一个添加:limit => 1位,从而确保只返回1条记录。在您有一个声明中,请确保您有一个:order子句,以便在所有情况下返回正确的记录。在这种情况下,我会在Employee上放置一个标志来表示谁是所有者,并按此列排序以获得正确的记录。

关于Rails如何知道这一点的问题是因为大多数数据库都会以主键顺序返回记录。因此,第一个添加的员工的ID为1,因此将返回第1个。

答案 2 :(得分:0)

您可以拥有一个名为所有权的模型 -

ownership belongs_to company   
ownership belongs_to user

user has_many ownerships
company has_one ownership