0

Context:

I have a Company model that has many projects. Each project has many tasks. The company has many employees.

The Employee model is associated with Company and not with projects or tasks. The Task model does have a employee_name attribute, since it is one employee per task (but more task per employee). An employee will have only one task per project.

Schema:

My question:

I'm trying to create an array that for each employee stores the projects it has a task in.

I currently have the following code working, but I am wondering if I could do this in a better way. Should I change my model associations, or is this the way to go?

        @employee = Employee.find(1)
        @employee_tasks = Task.where(employee: @employee.name)

        @employee_project = {}
        i = 0

        @employee_tasks .each do |f|
            i += 1
            @employee_project[i] = Project.where(id: f.project_id)              
        end
Matthias
  • 1,884
  • 2
  • 18
  • 35
  • 3
    Why can't you replace the `employee_name` on task with a `belongs_to :employee`? For me it'd be cleaner and to display the employee's name you can delegate to the employee. Then you can have a `has_many :projects, through: :tasks` on employee – j-dexx Feb 17 '16 at 15:41
  • It's not clear what you're trying to do so it's hard to suggest a refactor, but "@employee.company.projects" will give you the projects associated with an employee. – Max Williams Feb 17 '16 at 15:43
  • @MaxWilliams that gives all projects that the employee's company has. I think he's wanting all projects where the employee has a task – j-dexx Feb 17 '16 at 15:46
  • @MaxWilliams, @j-dexx, indeed I am looking for an array that contains all projects in which the employee has a task. You are right the above example begs the question if I have set up my model associations the right way. Are you saying I should simply make `Task` belong to both `Project` and `Employee`? – Matthias Feb 17 '16 at 16:04
  • @MatthiasHavenaar Yes, you should associate it. – j-dexx Feb 17 '16 at 16:06
  • @MaxWilliams, thanks for your comment and my apologies for my ignorance. In this case, could I associate it directly, or do I have to do this `through` the Project and Company models – Matthias Feb 17 '16 at 16:14
  • Would it make sense to associate my model as company > project > task > employee (unidirectional), or should I make it company > project > task < employee < company (circular) – Matthias Feb 20 '16 at 17:10

1 Answers1

1
class Project
  has_many :tasks
end

class Task
  belongs_to :project
  belongs_to :employee

  delegate :name, to: :employee, prefix: true
end

class Employee
  has_many :tasks
  has_many :projects, through: :tasks
end

I assume in your view you currently have this for a task

<%= task.employee_name %>

By using the prefix option on the delegate method this will still work if you associate your models in this way.

So now in your controller you could do

@employee = Employee.find(1)
@employee_tasks = @employee.tasks

Then say later on you wanted to find the employee's on a project and list them somewhere. Then you simply add to project

class Project
  has_many :tasks
  has_many :employees, through: :tasks
end

@project = Project.find(1)
@project_tasks = @project.tasks

Associating tasks to employees properly makes this much simpler. Another benefit is what happens if an employee changes their name? Currently you'd need to go through all the tasks to change the employee name on the task too (or write code to do it if an employee changed their name). By using the association you'd just change the employees name and it'd just work.

j-dexx
  • 10,286
  • 3
  • 23
  • 36
  • I have assumed that employee has a `name` method here though. – j-dexx Feb 17 '16 at 16:20
  • Thanks a lot. This probably is the answer. I'll accept it once I have figured out how to refactor my code and manage to implement your suggestion. Cheers! – Matthias Feb 17 '16 at 22:25
  • In case you feel helpful ;-) Follow up question following your answer: http://stackoverflow.com/questions/35469738/rails-how-to-have-a-nested-form-save-to-different-nested-models – Matthias Feb 17 '16 at 23:33