简体   繁体   中英

Rails: How to make available parent attribute in setter method

Context:

I have a company model with many projects , having many tasks . The company also has many employees , which in turn have many tasks .

Schema:

在此输入图像描述

Problem:

I'm building a form to create a project where the user can add multiple tasks . Upon submission the form should create a single project record, one or more task records with hours and employee_id attributes and (!) check if the employee name already exists in the database or create a new one.

I've approached this by adding jquery autocomplete to the form and defining a virtual attribute with a getter and setter method in my Task model. Similar to Railscast #102 .

This succesfully sets the employee_id in tasks and creates a new employee record with employee name and task_id .

The problem is currently that the model does not save a company_id .

My code:

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

Question:

How can I make the company_id attribute of the parent model available the setter method of my Task model? Like so:

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

At the moment this yields the error:

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

EDIT:

Or, if I try project.company_id this tells me project is a NilClass:

undefined method company_id for nil:NilClass

UPDATE:

Still unsolved. Any ideas why project is nil here?

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 

also, so typical pattern with rails, for instance where you have belongs_to :project , that would add an instance method called project to Task , that instance method could then be used to get project associated with task and subsequently the associated company_id in case that may be of interest

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM