Ruby on Rails。来自field_form的嵌套表单只返回一个散列而不是散列的散列
我有一个嵌套的表单,我想将一个散列保存到field_form中,但是这只保存最后一个在params中。Ruby on Rails。来自field_form的嵌套表单只返回一个散列而不是散列的散列
这是我的控制器
def new
@inventory_products = []
@inventory = Inventory.new
@products = Product.all
@products.each do |p|
@inventory_products << p.inventory_products.build
end
end
这是形式
<%= form_for @inventory do |f| %>
<%= render 'shared/error_messages', object: f.object%>
<%= f.label :description, "Description" %>
<%= f.text_area :description, class: 'form-control' %>
<%= f.label :warehouse, "Warehouse" %>
<%= f.select :warehouse_id, options_for_select(Warehouse.all.map {
|b| [ b.name, b.id ] }),
prompt: "foobar"%>
<%= f.label :products, "Productos" %>
<table class = "table table-bordered">
<thead>
<tr>
<th>+</th>
<th>Codigo</th>
<th>Nombre</th>
<th>Cantidad a Ingresar</th>
</tr>
</thead>
<tbody>
<% @inventory_products.each_with_index do |i, index|%>
<%= f.fields_for "inventory_products[]", i do |iv|%>
<tr>
<td>
<%= iv.check_box :product_id, {class: 'add_product',checked:false},iv.object.product_id.to_s, "0" %>
</td>
<td><%= @products[index].code %></td>
<td><%= @products[index].name %></td>
<td>
<%= iv.number_field :quantity, class:"form-control quantity#{iv.object.product_id.to_s}", readonly: true %>
</td>
</tr>
<% end %>
<% end %>
库存模型
class Inventory < ApplicationRecord
has_many :inventory_products
has_many :products, through: :inventory_products
belongs_to :warehouse
accepts_nested_attributes_for :inventory_products
validates:description, presence:true, length: {maximum:150}
end
库存产品型号
class InventoryProduct < ApplicationRecord
belongs_to :product
belongs_to :inventory
accepts_nested_attributes_for :product
validates:quantity, presence:true, numericality: { greater_than: 0}
end
产品型号
class Product < ApplicationRecord
has_many :inventory_products
has_many :inventories, through: :inventory_products
end
PARAMS
<ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"xwu4sCQCCCWOwXqbJkvVl9MDs2HRmjdT8IL2eMdMi0KHbibzHuQNmIWpot7fVqohvvxDlMIAEBzlDZB0OW3DCQ==", "inventory"=>{"description"=>"", "warehouse_id"=>"", "inventory_products"=>{"product_id"=>"1", "quantity"=>""}}, "commit"=>"Agregar", "controller"=>"inventories", "action"=>"create"}
def new
@inventory = Inventory.new
@products = Product.all
@products.each do |p|
@inventory << p.inventory_products.new(product: p)
end
end
def create
@inventory = Inventory.new(inventory_params)
if @inventory.save
# ...
else
# ...
end
end
private
def inventory_params
params.require(:inventory).permit(inventory_products_attributes: [:product_id, :quantity, :_keep])
end
替代通过手动迭代记录你只需要使用fields_for
对联想和Rails会创建正确的PARAMS:
<%= form_for(@inventory) do |f| %>
<%= f.fields_for :inventory_products do |iv|%>
<tr>
<td>
<%= iv.hidden_field :product_id %>
<%= iv.check_box :_keep, { class: 'add_product', checked:false }%>
</td>
<td><%= iv.object.code %></td>
<td><%= iv.object.name %></td>
<td>
<%= iv.number_field :quantity, class:"form-control quantity#{iv.object.product_id.to_s}", readonly: true %>
</td>
</tr>
<% end %>
<% end %>
我们还引入一个名为_keep
而不是使用复选框的产品ID的虚拟属性 - 这似乎是一个非常过于复杂和哈克建立。
class InventoryProduct < ApplicationRecord
belongs_to :product
belongs_to :inventory
attr_reader :_keep
accepts_nested_attributes_for :product, reject_if: :not_acceptable?
validates :quantity,
presence: true,
numericality: { greater_than: 0 }
def _keep=(value)
@_keep = typecast_to_boolean(value)
end
def not_acceptable?(attributes)
!typecast_to_boolean(attributes[:_keep])
end
private
def typecast_to_boolean(value)
ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value)
end
end
感谢您的答案,但如果更改新的方法,我得到的错误未定义的方法'
我想制作一个数组inventory_products_attributes –
抱歉复制粘贴错误。您不需要使用'fields_for'手动创建数组。如果你在一对多或多对多关联中使用'fields_for',它将遍历记录并为每个相关项创建输入。 http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for – max
您可以包括有问题的模型以及期望的结果是什么?你在做什么看起来像是应该如何使用'fields_for'和'accep_nested_attributes'的黑客版本,但它很难看到你实际上想要完成什么。 – max
你应该添加到这个问题的是一个高层次的描述“当创建一个订单时,用户应该能够...然后...” – max
我更新模型@max并更改问题的标题, params后,inventory_products fields_for只返回一个散列而不是数组散列 –