Rails: 如何将嵌套表单保存到不同的嵌套模型中?

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

上下文:

我有一个 Company 模型,其中有很多 projects。每个 project 有许多 taskscompany 有很多 employees

Employee属于Company,有很多tasks。每个任务是一名员工,一名员工每个 project.

将只有一名 task

架构:

问题:

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

我正在努力解决如何让表单保存 employee_id 而不是 employee_name

代码:

我的表格如下:

<%= 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 %>

我的控制器:

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

问题:

不幸的是,这会将 tasks table 保存到 employee_name 而不是 employee_id(加上将新的 employee_name 写入 employees table).当然,tasks table 应该只包含 employee_idsemployee table names.

关于如何解决这个问题有什么建议吗?

我会在如下表单中添加一个隐藏字段:

<%= 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 %>

此字段必须通过 Ajax 填写。我看到您的 :employee_name 输入字段中有一个自动完成源,那么当您 select 员工时,您可以在那里添加一个事件,并通过 Ajax 获取 ID 并填充隐藏字段selected 员工的 ID,这样您就可以轻松地在 create 操作中保存该数据。