Nested Forms rails 2.3
Wednesday, 18 February , 2009
En el proyecto en el que estoy actualemente estamos usando Rails 2.3, uno de los motivos de usar rails 2.3 es que nos venía muy bien la nueva feature “Nested Forms”, resultaque estuve dando vueltas con algunos problemas hasta que finalmente los saque funcionando bien.
Les cuento yo tengo un formulario para crear un user, el modelo de user es el siguiente:
class User < ActiveRecord::Base has_one :person, :as => :personable, :dependent => :destroy accepts_nested_attributes_for :person .... end
Es decir que un user tiene datos de contacto a travez de has_one :person (suena raro creo que se podría cambiar por has_one :contact_info, :class_name => “Person”) , y entonces el form era el siguiente:
<% form_for(:user, :url => users_path) do |f| -%> <p><%= label_tag 'login' %><br/> <%= f.text_field :login %></p> <p><%= label_tag 'password' %><br/> <%= f.password_field :password %></p> <p><%= label_tag 'password_confirmation', 'Confirm Password' %><br/> <%= f.password_field :password_confirmation %></p> <% f.fields_for(:person) do |person_fields| %> <p><%= person_fields.label :email %><br/> <%= person_fields.text_field :email %></p> <p><%= person_fields.label :first_name, 'First Name:' %><br/> <%= person_fields.text_field :first_name %></p> <% end %> <p><%= submit_tag 'Create User' %></p> <% end -%>
Resulta que esto no me funcionó y me daba el siguiente error:
ActiveRecord::AssociationTypeMismatch (Person(#-619527948) expected, got HashWithIndifferentAccess(#-607513158)):
El problema puntual era que no generaba bien el form y en vez de generar esto:
<input id="user_person_attributes_first_name" name="user[person_attributes][first_name]" size="30" type="text" />
generaba esto:
<input id="user_person_first_name" name="user[person][first_name]" size="30" type="text" />
Y entonces daba el error por que ActiveRecord (Nested model) genera un método person_attributes= en modelo dónde declaramos el accepts_nested_attributes_for (user en este caso) y por eso el form anterior no funciona como era de esperar.
En el controller tenía lo siguiente:
class UsersController < ApplicationController
def new
@user = User.new(:person => Person.new)
end
def create
@user = User.new(params[:user])
@user.save
end
.....
end
La solución fue modificar el form y hacer así:
<% form_for @user do |f| -%> <p><%= label_tag 'login' %><br/> <%= f.text_field :login %></p> <p><%= label_tag 'password' %><br/> <%= f.password_field :password %></p> <p><%= label_tag 'password_confirmation', 'Confirm Password' %><br/> <%= f.password_field :password_confirmation %></p> <% f.fields_for(:person) do |person_fields| %> <p><%= person_fields.label :email %><br/> <%= person_fields.text_field :email %></p> <p><%= person_fields.label :first_name, 'First Name:' %><br/> <%= person_fields.text_field :first_name %></p> <% end %> <p><%= submit_tag 'Create User' %></p> <% end -%>
cambié el
<% form_for(:user, :url => users_path) do |f| -%>
por
<% form_for @user do |f| -%>
El form para editar un user quedó prácticamente igual y funciona con los attributes de person y todo sin hacer nada del lado del controller. Ahora la pregunta es: Esta bien que nested_forms solamente funcione con la forma?:
<% form_for @user do |f| -%>
Si alguien tiene la respuesta que comente!
Saludos



Tuesday, 24 February , 2009 at 8:44 pm
[...] Link al post original (via Codear, pero te lleva al original en la mayoria de los casos) Tomado del Feed de Codear [...]
Friday, 20 March , 2009 at 1:27 pm
[...] Nested Forms rails 2.3: “ [...]
Friday, 17 April , 2009 at 3:08 pm
Muchas gracias por esto, tenía el mismo error y sólo aquí encontré publicada la solución.
Aún no me explico por que no jala con las rutas rest y por qué no hay mas posts al respecto. Quisiera saber la razón de este problema.
Una vez más gracias!.
Saturday, 17 October , 2009 at 7:07 pm
Es imposible hace esto en Rails 2.2?
o se hace de diferente forma?
Saturday, 17 October , 2009 at 11:50 pm
Nested forms es una feature que aparece en rails 2.3, vos estás 2.2. es relativamente sencillo migrarte a 2.3.
saludos