Rails:如何在 setter 方法中使父属性可用

Rails: How to make available parent attribute in setter method

上下文:

我有一个 company 模型,有很多 projects,有很多 taskscompany也有很多employees,而employees又有很多tasks.

架构:

问题:

我正在构建一个表单来创建一个项目,用户可以在其中添加多个 tasks。提交后,表单应创建一个 project 记录,一个或多个具有 hoursemployee_id 属性的 task 记录,并(!)检查 employee 名称已存在于数据库中或创建一个新的。

我通过向表单添加 jquery autocomplete 并在我的任务模型中使用 gettersetter 方法定义虚拟属性来解决这个问题。类似于 Railscast #102.

这成功地在 tasks 中设置了 employee_id 并创建了一条包含员工 nametask_id 的新 employee 记录。

目前的问题是模型没有保存 company_id

我的代码:

class Task < ActiveRecord::Base
    belongs_to :project
    belongs_to :employee

    def employee_name
      employee.try(:name)
    end

    def employee_name=(name)
      self.employee = Employee.find_or_create_by(name: name) if name.present?
    end
end

问题:

如何使父模型的 company_id 属性可用于我的 Task 模型的 setter 方法?像这样:

def shareholder_name=(name)
    self.shareholder = Shareholder.find_or_create_by(name: name, company_id: company_id) if name.present?
end

目前这会产生错误:

undefined local variable or method "company_id" for #<Task:0x98438b8>

编辑:

或者,如果我尝试 project.company_id 这告诉我 project 是一个 NilClass:

undefined method company_id for nil:NilClass

更新:

仍未解决。知道为什么 project 在这里是 nil 吗?

class Task < ActiveRecord::Base
  belongs_to :project
  belongs_to :employee

  def shareholder_name=(name)
    self.shareholder = Shareholder.find_or_create_by(name: name, company_id: project.company_id) if name.present?
  end
end 

另外,rails 的典型模式,例如您有 belongs_to :project,会添加一个名为 project 的实例方法到 Task,该实例方法然后可用于获取与任务相关联的项目,随后获取相关联的 company_id 以防可能感兴趣