2017-02-19 10 views
0

У меня есть вложенная форма, и я хочу сохранить хэш в поле field_form, но этот только сохраняет последнее значение в параметрах.Рубин на рельсах. Вложенная форма из 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 %> 

Inventory модель

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 

Inventory Модель продукта

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"} 
+1

Можете ли вы включить модели, о которых идет речь, и каков желаемый результат? То, что вы делаете, выглядит как взломанная версия того, как следует использовать 'fields_for' и' accepts_nested_attributes', но трудно понять, чего вы на самом деле пытаетесь выполнить. – max

+0

Что нужно добавить к вопросу - это описание высокого уровня «При создании заказа aa пользователь должен иметь возможность ... и затем ...» – max

+0

Я обновляю модель @max и изменяю заголовок вопроса, также ставит params post, inventory_products для fields_for возвращают только хеш вместо хеша массива –

ответ

0
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 

Вместо того, чтобы вручную итерацию через RECO выстр вы просто использовать fields_for на ассоциации и рельсы будут созданы соответствующие 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 вместо флажка с идентификатором продукта - что кажется очень усложненной и Hacky установки ,

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 
+0

спасибо за ответ, но если изменить новый метод, я получаю ошибку undefined method '<< 'для Inventory, –

+0

Я хочу создать массив для inventory_products_attributes –

+0

Извините, скопируйте ошибку патча. Вам не нужно вручную создавать массив с 'fields_for'. Если вы используете 'fields_for' с ассоциацией« один-ко-многим »или« многие-многие », он будет перебирать записи и создавать входы для каждого связанного элемента. http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for – max

 Смежные вопросы

  • Нет связанных вопросов^_^