2

我有一个创建公司并在此过程中成为员工的用户。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 除了外键之外还有其他属性,比如 boolean :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 进行了测试。

4

2 回答 2

2

这里有很多位一起工作。

您肯定想在所有模型上使用 attr_accessible。(谷歌“hack rails mass assignment”并阅读Rails Guide on mass assignment。)

将 attr_accessible 添加到模型后,除您明确允许的那些之外,来自散列的所有分配(质量分配)都将被禁用。但是,您仍然可以直接分配值,一次一个。

从批量分配中排除外键似乎是一件好事,所以不要在 attr_accessible 中列出它们。

.create 和 .build 方法不使用批量分配,因此它们可以设置一个外键关联的值。如果有多个关联,据我所知,您必须单独设置除第一个之外的所有关联。

最后,外键的实际 ID 是由数据库而不是 ActiveRecord 创建的。因此,您要么必须同时创建父记录和子记录,要么必须先保存子记录,然后才能在父记录中分配外键。否则,没有可用于分配的 ID。

从您的示例中我不清楚 Employee 是如何被实例化的。但是由于 Employee 属于 User 和 Company,我认为这样的事情可能会起作用,假设 @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
于 2012-03-28T23:25:39.093 回答
0

company_id 为 nil 仅仅是因为 Company 尚未保存到数据库中 - Company.new 只是在内存中创建对象而不保存它。

如果你这样做:

@user.companies << Company.create(..)

或者

@user.companies << Company.first

他们都应该工作。甚至还有一种更短的方法,我认为它也应该起作用:

@user.companies.create(..)

这完全取决于您要保存关联的时间点。在某些情况下,最好不要立即保存员工和公司模型,而是等待父模型(用户)保存时。在这种情况下,您可以使用:

@user.companies.build(..) 

(类似于您示例中的代码)。

activeEmployee 模型上的布尔属性而言,如果这是数据库中的一列,则无需显式声明attr_accessible它 - 默认情况下可以访问它。

于 2011-06-22T09:59:00.440 回答