2011-11-25 20 views
9

Tengo problemas para obtener fields_for para trabajar en un atributo Array de un modelo que no es ActiveRecord.form_for non-AR model - fields_for El atributo Array no itera

destilada abajo, tengo que siguiente:

modelos/parent.rb

class Parent 
    extend ActiveModel::Naming 
    include ActiveModel::Conversion 
    include ActiveModel::Validations 
    extend ActiveModel::Translation 

    attr_accessor :bars 
end 

controladores/parent_controller.rb

def new_parent 
    @parent = Parent.new 

    @parent.bars = ["hello", "world"] 
    render 'new_parent' 
end 

vistas/new_parent.html.haml

= form_for @parent, :url => new_parent_path do |f| 
    = f.fields_for :bars, @parent.bars do |r| 
    = r.object.inspect 

Con el código anterior, mi página contiene ["hello", "world"], es decir, el resultado de inspect llamado en la matriz asignada al bars. (Con @parent.bars omitido de la línea fields_for, acabo de mostrar nil).

¿Cómo puedo hacer que fields_for se comporte como una asociación de AR, es decir, ejecute el código en el bloque una vez para cada miembro de mi matriz bars?

+0

Gracias por esto. ¡No pensé que alguien más hubiera intentado hacer esto! ¡Gracias ... mucho! – Nitrodist

Respuesta

11

creo que la técnica correcta es:

= form_for @parent, :url => new_parent_path do |f| 
    - @parent.bars.each do |bar| 
    = f.fields_for "bars[]", bar do |r| 
     = r.object.inspect 

Muy bien por qué no se puede hacer trabajar sólo no estoy seguro, pero esto parece hacer el truco.

1

creo que puede hacerse sin la necesidad de cada uno:

= form_for @parent, :url => new_parent_path do |f| 
    = f.fields_for :bars do |r| 
    = r.object.inspect 

Es necesario configurar algunos de los métodos que se esperan en la clase padre para identificar la colección.

class Parent 
    def bars_attributes= attributes 
    end 
end 

Y también tendrá que asegurarse de que los objetos de la matriz responden a persistido (lo que no puede utilizar cadenas) :(

0

Dejé la fields_for y ha añadido múltiples: verdadera

= form_for @parent, :url => new_parent_path do |f| 
    - @parent.bars.each_with_index do |bar, i| 
    = f.text_field :bars, value: bar, multiple: true, id: "bar#{i}" 
Cuestiones relacionadas