Rails: How to have a nested form save to different nested models?

别来无恙 提交于 2019-12-14 02:43:17

问题


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:

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?


回答1:


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.



来源:https://stackoverflow.com/questions/35469738/rails-how-to-have-a-nested-form-save-to-different-nested-models

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!