1

Context:

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

Employee belongs to Company and has many tasks. It is one employee per task and an employee will have only one task per project.

Schema:

enter image description here

Problem:

I'm building a form to create a project where the user can add multiple tasks. Each task has an amount of hours specified and the employee performing the task. 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'm struggling with how to have the form save the employee_id rather than the employee_name.

Code:

My form is as follows:

<%= simple_nested_form_for @project do |f| %>
    <%= f.input :project_details %>
    <%= f.simple_fields_for :tasks do |task| %>
        <%= task.input :employee_name, input_html: { data: { autocomplete_source: @queried_employee_names.to_json } } %>
        <%= task.input :hours %>
    <% end %>
    <%= f.link_to_add "Add +", :tasks %>
    <%= f.button :submit %>
<% end %>

My controller:

class TransactionsController < ApplicationController

  def new
    @project = current_company.projects.build
  end

  def create
    @project = current_company.projects.new(project_params)
    if @project.save
        employee_save
        redirect_to success_url
    else
        @project = current_company.projects.build
        render :new
    end
  end


    # save the employees not yet in the database
    def employee_save
      @project.tasks.each do |task|
            if current_company.employees.where(name: task.employee_name).empty?
              current_company.employees.new(name: task.employee_name).save 
            end
        end
    end

  def project_params
    params.require(:project).permit(:project_details, tasks_attributes: [:id, :employee_name, :hours, :_destroy])
  end
end

Question:

Unfortunately, this would save to the tasks table the employee_name rather than employee_id (plus writing a new employee_name to the employees table). Of course, the tasks table should only contain the employee_ids and the employee table the names.

Any suggestions on how to approach this?

Matthias
  • 1,884
  • 2
  • 18
  • 35
  • Hi if my answer was useful, please consider select it as accepted answer, that's how the community works... – svelandiag Mar 02 '16 at 19:25
  • Hi SsouLlesS, thanks for the answer and your time. Quite frankly the answer (comment) by j-dexx was most useful here. You mentioned the use of a hidden field, which in the end I did not use. Perhaps if you would summarise the comments mentioned below I will accept. Currently it is not 'the' solution. Cheers, M – Matthias Mar 02 '16 at 22:20
  • Yes I know it was not the full answer, but it may be useful for others looking for this same topic, not because it was not useful only for you means it is not an useful answer. Regards – svelandiag Mar 03 '16 at 00:00

1 Answers1

0

I would add a hidden field in the form like:

<%= simple_nested_form_for @project do |f| %>
    <%= f.input :project_details %>
    <%= f.simple_fields_for :tasks do |task| %>
        <%= task.input :employee_name, input_html: { data: { autocomplete_source: @queried_employee_names.to_json } } %>
        <%= task.hidden_field :employee_id, '' %>
        <%= task.input :hours %>
    <% end %>
    <%= f.link_to_add "Add +", :tasks %>
    <%= f.button :submit %>
<% end %>

This field must be filled through Ajax. I see you have an autocomplete source in your :employee_name input field, well you can add an event there when you select the employee, and get the id through Ajax and fill the hidden field with the id of the selected employee, that way you can easily save that data in your create action.

svelandiag
  • 4,231
  • 1
  • 36
  • 72
  • thanks. That indeed sounds like a solution. Do you also have a suggestion how to deal with this on the controller side? – Matthias Feb 18 '16 at 08:30
  • 1
    It's an old episode but [this](http://railscasts.com/episodes/57-create-model-through-text-field) would work for you – j-dexx Feb 18 '16 at 09:10
  • Good suggestion to watch the Railscast. I actually found a more recent one [#102](http://railscasts.com/episodes/102-auto-complete-association) that even better describes this issue. There is one remaining issue however, how to link the new `employee` record to `company` this way. I've described this [here](http://stackoverflow.com/questions/35494349/rails-how-to-make-available-parent-attribute-in-setter-method). Thanks again! – Matthias Feb 18 '16 at 23:20