2012-08-10 12 views
5

Estoy tratando de crear un formulario que me permita enviar nuevos registros para una asociación donde las entradas de asociación están agrupadas.agrupando y fields_for

class Product < AR::Base 
    has_many :properties 
    accepts_nested_attributes_for :properties 
    end 

Tenga en cuenta que en el controlador de una serie de propiedades se construyen para el producto, por lo @product.properties.empty? # => false.

El siguiente fields_for me da las entradas correctas con nombres como product[properties_attributes][0][value].

= form.fields_for :properties do |pform|                                
    = pform.input :value 

Pero tan pronto como lo intento y el grupo de la asociación ya no genera entradas con los nombres correctos:

- @product.properties.group_by(&:group_name).each do |group_name, properties| 
    %h3= group_name              
    = form.fields_for properties do |pform|                                
    = pform.input :value 

Esto crea entradas de los cuales el atributo name como product[product_property][value] cuando en realidad debería ser product[property_attributes][0][value] según el primer ejemplo.

documentación

Los rieles sugiere que puede hacer esto:

= form.fields_for :properties_attributes, properties do |pform| 

Pero esto da un error "valor método no definido para la matriz".

Respuesta

6

Es necesario configurar de esta manera:

- @product.properties.group_by(&:group_name).each do |group_name, properties| 
    %h3= group_name 
    = form.fields_for :properties, properties do |pform| 
    = pform.text_field :value 

que debería funcionar bien, ya que tiene accepts_nested_attributes_for :properties carriles de saber que se supone que debe crear campos para properties_attributes. Por otra parte es posible que desee añadir attr_accessible :properties_attributes si está utilizando uno de los nuevos carriles y si usted no lo agregue a su modelo todavía;)

Además, si usted quiere hacer algo de base para la adopción en la propiedad única que puede usar el siguiente formulario así:

- @product.properties.group_by(&:group_name).each do |group_name, properties| 
    %h3= group_name 
    - properties.each do |property| 
    = form.fields_for :properties, property do |pform| 
     = pform.text_field :value 

Ambos están muy bien descrito aquí: http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for bajo One-To-Many sección

+0

Esto parece funcionar, no sé por qué no lo probé ': properties' en lugar de ': property_attributes'. Aceptaremos en breve. – Kris

1

No conozco una solución limpia de "Rails" para este tipo de cosas, pero a menudo me ocupo de este tipo de situaciones de forma más manual. por ejemplo, buclee a través de los grupos y muestre condicionalmente solo aquellas propiedades que están en un grupo particular.

class Product < AR::Base 
    has_many :properties 
    accepts_nested_attributes_for :properties 

    def group_names 
    properties.map(&:group_name).uniq.sort 
    end 
end 

En la vista

- for group_name in product.group_names 
    = form.fields_for :properties do |pform| 
    %h3= group_name 
    - if pform.object.group_name.eql?(group_name) 
     = pform.input :value 

Puede haber una pequeña sobrecarga con esto, conseguir la lista de propiedades de producto en varias ocasiones. Puede modificar su asociación has_many: properties para recuperar las propiedades en el orden group_name; luego, puede agregar el% h3 cuando se trata de un nuevo grupo.

- previous_group_name = nil 
= form.fields_for :properties do |pform| 
    - if pform.object.group_name != previous_group_name 
    %h3= pform.object.group_name 
    = pform.input :value 
    - previous_group_name = pform.object.group_name 

Algunas ideas para usted ...

Cuestiones relacionadas