Formularios complejos y Ajax

Hola a todos,

Queria haceros una consulta sobre Rails, es la primera vez que lo uso,
aunque de Ruby en si se bastante. El caso es que tengo un formulario
en el que hay representado un encargo para una obra, este encargo
tiene asociado un plano, el plano tiene asociadas piezas y otros
subplanos. Ahora mismo tengo los formularios hechos como muestra este
tutorial

tengo un form_for para el trabajo entero y luego voy recursivamente
usando fields_for.

  • Mi primera pregunta es si hay alguna alternative mejor para hacer
    los fields_for recursivos que la que uso yo (uso markaby por cierto):

for subplano in plano.children do
fields_for form_plano.object_name.sub(/[]/,“[#{plano.id}]”) +
‘[plano_attrs][]’, subplano do |form_plano|
render :partial => ‘planos/plano’, :locals => { :form_plano =>
form_plano, :plano => subplano}
end
end

Esto es para que se vayan anidando en plan:

trabajo[plano_attrs][5][plano_attrs][7][pieza_attrs][11][descripcion]

  • Mi segunda pregunta es sobre Ajax. Por ahora para añadir nuevas
    piezas y planos hago una llamada al servidor para que cree una nueva
    pieza, y recargo la pagina entera. Idealmente me gustaria poder
    añadirlas con link_to_function, pero no entiendo muy bien como
    hacerlo. Lo mas parecido que he conseguido es esto

    $plano_id = plano.id
    $form_name = form_plano.object_name.sub(/[]/,“[#{plano.id}]”)
    nueva_pieza = link_to_function “Añadir Pieza” do |page|
    pieza = Pieza.new(:plano_id => $plano_id)
    pieza.tiempo = Tiempo.new
    fields_for $form_name + ‘[nueva_pieza_attr][]’, pieza do |
    form_pieza|
    page.insert_html :after, “plano_#{$plano_id}”, :partial =>
    ‘pieza_edit’, :locals => {:pieza => pieza,:form_pieza => form_pieza}
    end
    end
    text nueva_pieza

Utilizo nueva_pieza_attr, pora no mezclar las piezas nuevas con las
antiguas. Esto no acaba de funcionar bien, y aunque lo hiciera no
escalaria bien cuando añada subplanos. Yo creo que lo ideal seria que
la informacion del plano_id y del form_name los sacara directamente el
javascript del contexto del elemento del DOM, como por ejemplo del id
del contenedor del link, pero me parece un poco lio, y me imagino que
igual hay alguna manera mas standard de hacer esto.

Vereis que tengo que definir algunas cosas como globales para poder
usarlas dentro del bloque, plano y form_plano no estan accesibles ahi.

Eso es todo, si me podeis orientar un poco estare muy agradecido

Un saludo

Miguel Vazquez

2008/6/28 Miki Vz [email protected]:

form_plano, :plano => subplano}
end
end

La manipulacion del ID la veo sospechosa. Ojo en ese codigo ademas
porque form_plano no es local al bloque y sobreescribe al form_plano
que aparece en la llamada a fields_for (que esta en un bucle):

a = 1
0.upto(1) do
  puts a
  [0].each {|a|}
end
# 1
# 0

En principio lo normal seria que Rails ponga los IDs de los modelos.
Cuando invocas a fields_for para el subform de un subplano, lo normal
seria que al nombre del form padre le añadas

parent_form_name + “[subplano_attrs][]”, subplano

y ahi se pone el ID del subplano (supuesto que no sea un new_record?
que por como lo estas montando supongo que no). El control de los
nombres en los subforms puede hacerse a mano, con variables locales…
depende del montaje.

  • Mi segunda pregunta es sobre Ajax. Por ahora para añadir nuevas
    piezas y planos hago una llamada al servidor para que cree una nueva
    pieza, y recargo la pagina entera. Idealmente me gustaria poder
    añadirlas con link_to_function, pero no entiendo muy bien como
    hacerlo.

Has visto http://railscasts.com/episodes/74 ?

Has visto http://railscasts.com/episodes/74 ?

Si, he visto los 3 de complex forms. Al final me he dado cuenta de que
realmente no necesito la recursion, pongo los fields_for en plan

field_for ‘piezas[]’, pieza
field_for ‘planos[]’, plano

y luego en el controlador salvo cada cosa por separado:

if params[:planos]
  params[:planos].each{|id, attrs|
    Plano.find(id).update_attributes(attrs)
  }
end

if params[:piezas]
  params[:piezas].each{|id, attrs|
    Pieza.find(id).update_attributes(attrs)
  }
end

El unico inconveniente ahora es que para añadir nuevos planos y piezas
siempre tengo que pasar hacer una llamada al servidor para que me cree
el objeto y lo asocie a su contenedor. Pero afortunadamente uso rjs para
no tener que recargar la pagina entera, no es la mejor solucion, pero es
‘good enough’.

Gracias por tus consejos de cualquier manera.

Miguel

Igual te sirven estos dos hilos de railsforum

http://railsforum.com/viewtopic.php?id=717
http://railsforum.com/viewtopic.php?id=719

El 29/06/2008, a las 15:32, Miki Vz
escribió:

Has visto http://railscasts.com/episodes/74 ?