Rails 4 种形式,将父 ID 值保存在联接中的子记录中 table

Rails 4 form that saves parent id values in a children record in a join table

我正在 Rails 4 中使用 bootstrap rails 表单进行开发,我正在尝试制作一个将产品保存到 table 的表单。该产品有很多输入,输入可以属于许多产品。数据库是postgres。

我的主要问题是将 product_id 和 input_id 保存到我创建的名为 "productinput" 的连接 table 中。这可能是我正在努力完成的一个例子:

productinput table 每次我生成具有许多输入的新产品时生成的值示例 select 从复选框 select:

product_id: 1 input_id: 1 product_id: 1 input_id: 2 product_id: 1 input_id: 3 product_id: 1 input_id: 4

我已经完成了应用程序中的大部分配置。请看一看:

**productinput model**

class Productinput < ActiveRecord::Base
belongs_to :input, inverse_of: :productinputs
belongs_to :product, inverse_of: :productinputs

validates_presence_of :user_id
validates_presence_of :input_id
validates_presence_of :product_id
end

**product model**

class Product < ActiveRecord::Base
has_many :productinputs, inverse_of: :product, :dependent => :destroy
has_many :inputs, :through => :productinputs
accepts_nested_attributes_for :inputs
accepts_nested_attributes_for :productinputs, :allow_destroy => true

has_many :clientproducts, inverse_of: :product
has_many :worktasks, inverse_of: :product

validates_presence_of :user_id

accepts_nested_attributes_for :clientproducts, :allow_destroy => true
accepts_nested_attributes_for :worktasks
end

**input model**

class Input < ActiveRecord::Base
has_many :productinputs, inverse_of: :input, :dependent => :destroy
has_many :products, :through => :productinputs
accepts_nested_attributes_for :productinputs, :allow_destroy => true

has_many :inputproviders, inverse_of: :input

validates_presence_of :user_id

accepts_nested_attributes_for :inputproviders
end

然后我想用输入字段更新产品表单,以动态添加多个输入 select:

<%= bootstrap_form_for( @product, layout: :horizontal, label_col: "col-sm-2 hide", control_col: "col-sm-12", label_errors: true) do |f| %>
<div class="container-fluid">
  <div class="row">
    <%= f.alert_message "Please fix the errors below." %>
  </div>
  <div class="row">
    <div class="col-xs-12">
      <%= f.text_field :name, hide_label: true, placeholder: "Name", icon: "tag" %>
      <%= f.text_field :description, hide_label: true, placeholder: "Description", icon: "align-justify" %>
      <%= f.text_field :stock, hide_label: true, placeholder: "Stock", icon: "book" %>
      <%= f.text_field :price, hide_label: true, placeholder: "Price", icon: "usd" %>
    </div>
  </div>
  <div class="row text-center">
    <%= f.submit "Submit Product", :class => 'btn btn-primary' %>
    <%= link_to t('.cancel', :default => t("helpers.links.cancel")),
                products_path, :class => 'btn btn-default' %>
  </div>
</div>

我已经尝试过 cocoon、nested_form、formtastic、simple_form gems、许多教程以及更多内容,花了 2 周的时间对此进行调查,但我仍然不明白如何才能做到这一点,你能帮我一下吗?

谢谢,

这就是我如何从父表单视图设法在联接 table 中创建子记录:

型号:

class Product < ActiveRecord::Base
    has_many :productinputs, :dependent => :destroy
    has_many :inputs, through: :productinputs
    accepts_nested_attributes_for :productinputs, :allow_destroy => true

    has_many :clientproducts, inverse_of: :product
    has_many :worktasks, inverse_of: :product

    validates_presence_of :user_id
end

class Productinput < ActiveRecord::Base

    belongs_to :product
    belongs_to :input

    #validates_presence_of :user_id
    #validates_presence_of :input_id
    #validates_presence_of :product_id
end

class Input < ActiveRecord::Base
    has_many :productinputs
    has_many :products, through: :productinputs
    accepts_nested_attributes_for :productinputs, :allow_destroy => true

    has_many :inputproviders, inverse_of: :input

    validates_presence_of :user_id

    accepts_nested_attributes_for :inputproviders
end

控制器:

此处的关键,:inputs_ids[] 填充了来自 "check_box_tag "product[input_ids][]"" 的输入元素数组,格式为:

def product_params
  parameters = params.require(:product).permit(:name, :description, :stock, :price, :input_ids => [], productinputs_attributes: [:user_id, :quantity])
  parameters[:user_id] = current_user.id
  parameters
end

形式:

<%= simple_form_for @product, defaults: { input_html: { class: 'form-horizontal' } } do |f| %>
    <div class="row"> <%= f.error_notification id: 'user_error_message', class: 'form_error' %>
    </div>
    <div class="row">
      <div class="col-xs-12 col-md-6">
        <%= f.input :name, placeholder: 'Product Name', error: 'Username is mandatory, please specify one', label: false %>
        <%= f.input :description, placeholder: 'Enter Description', label: false %>
        <%= f.input :stock, placeholder: 'Stock', label: false %>
        <%= f.input :price, placeholder: 'Price', label: false %>
      </div>
      <div class="col-xs-12 col-md-6">
        <%= hidden_field_tag "product[input_ids][]", nil %>
        <% Input.where("user_id = ?", current_user.id).each do |input| %>
            <%= check_box_tag "product[input_ids][]", input.id,
                              @product.input_ids.include?(input.id), id: dom_id(input) %>
            <%= label_tag dom_id(input), input.name %><br>
        <% end %>
      </div>
    </div>
    <div class="row text-center">
      <%= f.button :submit, :class => 'btn btn-primary' %>
      <%= link_to t('.cancel', :default => t("helpers.links.cancel")),
                  products_path, :class => 'btn btn-default' %>
    </div>

<% end %>

希望这对遇到与我相同问题的任何人有所帮助。

抱歉,如果有人不明白我在找什么。

P.S:只是想让你知道,我可以通过以下简单形式简化多个复选框:

<%= hidden_field_tag "product[input_ids][]", nil %>
<% Input.where("user_id = ?", current_user.id).each do |input| %>
    <%= check_box_tag "product[input_ids][]", input.id, @product.input_ids.include?(input.id), id: dom_id(input) %>
    <%= label_tag dom_id(input), input.name %><br>
<% end %>

对此:

<%= f.association :inputs, :as => :check_boxes %>