Formularios complejos y has_one

Hola lista,
tengo un pequeño problema que no se darle solución, resulta que tengo un
modelo User que tiene una dirección:

class User < ActiveRecord::Base

has_one :location, :as => :localizable, :dependent => :destroy

Cuando se crea un usuario por primera vez, se inicializa con una
dirección en blanco:

def after_create
l = Location.new
l.localizable = self
l.save!
end

Luego cuando hago el edit del usuario, tengo:

<% fields_for “user[location]”, @user.location do |location_form| %>

....

Y en el modelo:

after_update :save_location

def save_location
location.save(false)
end

Pero no me guarda nada. ¿Alguna idea por favor? ¿Donde estoy metiendo la
pata?
Muchas gracias a todos.

Address: <%= location_form.text_field :address %>
City: <%= location_form.text_field :city %>

Hola, muchas gracias por tu respuesta,
te pego el código de la vista:

Nombre: ...
  <tr>
<th>Calle:</th>
<td><input id="location_address" name="location[address]" size="30" 

type=“text” />

Ciudad: ...

En los modelos:

user.rb

has_one :location, :as => :localizable, :dependent => :destroy

location.rb

belongs_to :localizable, :polymorphic => true

def after_create
# más limpio así, gracias =)
create_location
end

after_update :save_location

def save_location
location.save(false)
end

Y en el controlador de user_controller.rb:

def update
respond_to do |format|
if current_user.update_attributes(params[:user])

Pero al hacer el submit, me sigue son guardar la dirección.
Gracias.

Un saludo.

2008/8/18 Mario S. [email protected]:

type="text" /> ...

Si miras atentamente los atributos name de los input verás el
problema: los pertenecientes directamente al usuario son
“user[first_name]”, mientras que los de la localización son
“location[city]”. Eso llegará al controlador en dos hashes en param,
param[:user] y param[:location], y tú haces
update_attributes(param[:user]), con lo que los cambios en
params[:location] no van a ser salvados.

Como te he escrito en el anterior correo deberías utilizar “fields_for
@user.location” en vez de lo que tú utilizas, y debería funcionarte.

after_update :save_location

def save_location
location.save(false)
end

De nuevo, esta parte no es necesaria, cuando modifiques la vista y
hagas el current_user.update_attributes(params[:user]) seguido de
current_user.save se salvará a su vez el modelo asociado (sin
necesidad de ese código).

Suerte.

2008/8/18 Mario S. [email protected]:

dirección en blanco:

def after_create
l = Location.new
l.localizable = self
l.save!
end

Lo primero, ese after_create queda mucho más claro utilizando Rails:

def after_create
create_location # Crea un Location vacio, se lo asigna a la
instancia actual y lo guarda (se le pueden pasar parámetros)
end

Como siempre, hay que conocer las asociaciones y los métodos que
crean:
http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_one

<%= location_form.text_field :city %> ....

Si estás dentro de un “form_for @user” con “fields_for @user.location
debería bastar.
http://apidock.com/rails/ActionView/Helpers/FormHelper/fields_for

Muchas gracias a todos.
Eso no debería ser necesario, cuando el modelo “padre” es salvado el
modelo asociado es salvado.

Tengo la impresión que lo que falla es tu código de la vista, que
desconozco que HTML generará, y como Rails lo interpretará. Lo ideal
sería conocer los parámetros que recibe Rails después de hacer el
submit del formulario. Suponiendo que el controlador sea el estándar
de Rails y que los parámetros lleguen correctamente todo debería
funcionar.

Suerte.

Como te he escrito en el anterior correo deberías utilizar “fields_for
@user.location” en vez de lo que tú utilizas, y debería funcionarte.

Hola Daniel,
estoy utilizando como me comentaste en tu primera respuesta “fields_for
@user.location

after_update :save_location

def save_location
location.save(false)
end

Esto lo dejé porque sigue sin funcionarme, no lo entiendo.

2008/8/18 Mario S. [email protected]:

Como te he escrito en el anterior correo deberías utilizar “fields_for
@user.location” en vez de lo que tú utilizas, y debería funcionarte.

Hola Daniel,
estoy utilizando como me comentaste en tu primera respuesta “fields_for
@user.location

Jo, lo siento, eso funciona en Edge, pero no en el 2.1 (eso me pasa
por hablar sin comprobar las cosas).

Ahora mismo a tu controlador llegan los dos hash que te he comentado
antes (params[:user] y params[:location]). Lo que tendrías que hacer
es un:

User.transaction do
current_user.update_attributes!(params[:user])
current_user.location.update_attributes!(params[:location])
end

Y recuerda hacer los rescue pertinentes.

Suerte.

Muchísimas gracias Daniel, con esto a la primera
un saludo.

Mario S. wrote:

Buenos días a todos,
por favor, siguiendo con este hilo tengo una pregunta, un poco tonta
creo, pero ahora mismo no me sale:
Si un usuario tiene un ‘location’ como hemos visto arriba, ¿como podría
buscar todos los usuarios de una misma ciudad?

Muchas gracias.

¿Alguna idea por favor?

2008/8/30 Mario S. [email protected]:

Mario S. wrote:

Buenos días a todos,
por favor, siguiendo con este hilo tengo una pregunta, un poco tonta
creo, pero ahora mismo no me sale:
Si un usuario tiene un ‘location’ como hemos visto arriba, ¿como podría
buscar todos los usuarios de una misma ciudad?

Muchas gracias.

¿Alguna idea por favor?

Sin comprobar:

User.find(:all, :include => :location, :conditions => [“locations.city
LIKE ?”, search_city])

Todo lo podrías haber encontrado en… atención… la documentación:
http://apidock.com/rails/ActiveRecord/Base/find/class

2008/8/30 Mario S. [email protected]

¿Qué artículos y referencias sobre el tema has encontrado en estos tres
días? ¿No te han servido? ¿Qué código has probado? ¿No te funciona? ¿Por
qué?

Son las cosas que solemos preguntar en estos casos :slight_smile:

Buenos días a todos,
por favor, siguiendo con este hilo tengo una pregunta, un poco tonta
creo, pero ahora mismo no me sale:
Si un usuario tiene un ‘location’ como hemos visto arriba, ¿como podría
buscar todos los usuarios de una misma ciudad?

Muchas gracias.