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

nka*_*sis 9 activerecord ruby-on-rails 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
Run Code Online (Sandbox Code Playgroud)

这是我的用户模型:

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
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

EmF*_*mFi 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
Run Code Online (Sandbox Code Playgroud)

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

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


Fra*_*eil 5

has_one是语法糖:

has_many :whatevers, :limit => 1
Run Code Online (Sandbox Code Playgroud)

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

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