我有一个创建公司的USER,并在此过程中成为一名雇员。 employees表格有:user_id
和:company_id
。
class User
has_many :employees
has_many :companies, :through => :employees
class Employee
belongs_to :user
belongs_to :company
attr_accessible :active
class Company
has_many :employees
has_many :users, :through => employees
非常基本。但事实上,资源EMPLOYEE具有除外键之外的其他属性,例如布尔值:active
。我想使用attr_accessible
,但这会导致一些问题。属性:user_id
设置正确,但:company_id
为零。
@user.companies << Company.new(...)
Employee id:1 user_id:1 company_id:nil
所以我的问题是:如果:user_id
设置正确,尽管它不是attr_accessible
,为什么:company_id
设置不正确?它不应该是attr_accessible
。
我正在使用Rails 3.0.8,并且还使用3.0.7进行了测试。
答案 0 :(得分:2)
这里有很多比特在一起工作。
您肯定希望在所有型号上使用attr_accessible。 (Google“hack rails mass assignment”并阅读Rails Guide on mass assignment。)
将attr_accessible添加到模型后,将禁用散列(质量分配)中的所有分配,但明确允许的除外。但是,您仍然可以直接分配值,一次一个。
外键似乎是从质量分配中排除的好东西,所以不要在attr_accessible中列出它们。
.create和.build方法没有使用质量赋值,因此可以设置一个外键关联的值。如果有多个关联,我可以告诉你,你必须分别设置除第一个以外的所有关联。
最后,外键的实际ID是由数据库创建的,而不是由ActiveRecord创建的。因此,您必须同时创建父记录和子记录,或者您必须先保存子项,然后才能在父项中分配外键。否则,没有可用于分配的ID。
从您的示例中我不清楚Employee是如何实例化的。但由于员工属于用户和公司,我认为这样的事情可能有用,假设@user已经存在:
company = @user.companies.create(..) # fills in company.user_id and saves to DB
employee = @user.employees.build(..) # fills in employee.user_id but does NOT save yet
employee.company = company # fills in employee.company_id
employee.save # now save to DB
答案 1 :(得分:0)
company_id仅仅是因为公司尚未保存到数据库中 - 公司.new只是在内存中创建对象而不保存它。
如果你这样做:
@user.companies << Company.create(..)
或
@user.companies << Company.first
他们都应该工作。甚至还有一种更短的方法我认为也应该起作用:
@user.companies.create(..)
这一切都取决于你想要保存关联的点。在某些情况下,最好不要立即保存员工和公司模型,而是等待保存父模型(用户)。在这种情况下,您可以使用:
@user.companies.build(..)
(类似于您示例中的代码)。
就Employee模型上的active
布尔属性而言,如果这是数据库中的列,则不需要为其明确声明attr_accessible
- 它可以通过默认值。