2011-10-08 8 views
8

estoy tratando de utilizar accepts_nested_attributes_for en un modelo de asociación has_one, y llegar a ninguna parte :-(Rails 3.1: accept_nested_attributes_for y has_one association - ¿no funcionará?

Tengo dos modelos, un usuario y una ubicación Un usuario tiene un solo lugar:.

class User < ActiveRecord::Base 
    # current location 
    has_one :location, :dependent => :destroy 
    accepts_nested_attributes_for :location 
end 

class Location < ActiveRecord::Base 
    belongs_to :user 
end 

Puedo guardar los cambios en el modelo usando User.find(1).location.current_location_text = "blah" desde la consola, entonces sé que las asociaciones están configuradas correctamente.

Tengo dos formularios en la página de usuario de edición. Uno que actualiza los atributos principales del usuario (y funciona bien y no se muestra a continuación) y luego este que permite al usuario actualizar un att ribute del modelo de ubicación, llamado "current_location_text":

<%= form_for(@user) do |f| %> 
    <%= fields_for(@user.location) do |location_fields| %> 
     <%= location_fields.label :current_location_text, 'Current Location' %> 
     <%= location_fields.text_field :current_location_text, :placeholder => 'Road, City or Postcode' %> 
    <% end %> 

    <%= f.submit "Update Current Location" %> 
<% end %> 

Esto no funciona. Estoy un poco confundido ya que los parámetros enviados por el formulario parecen incorrectos. Cuando se envía el formulario, esto es en el registro:

Started PUT "https://stackoverflow.com/users/1" for 127.0.0.1 at 2011-10-08 00:28:05 +0100 
    Processing by UsersController#update as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"YdTAsXwEvRgXIqri+jfx3dLlYG2XWQTuYkgLDsO/OJw=", "location"=>{"current_location_text"=>"E14 8JS"}, "commit"=>"Update Current Location", "id"=>"1"} 
    User Load (10.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1 
    User Load (5.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = ? LIMIT 1 [["id", "1"]] 
    SQL (4.4ms) BEGIN 
    (2.5ms) COMMIT 
Redirected to http://localhost:3000/users/1 

Dos cosas que encuentro extraño en esto:

  1. Ahí está el mensaje "COMMIT", pero con ninguna cadena actualización anterior, y No hay error. por ejemplo, si intentas asignar un atributo protegido, obtendrás el mensaje de error "no puedes asignar en masa ..." en ese momento.

  2. Los parámetros me parecen incorrectos. El bit de "localización" está anidado como me esperaba, pero yo también esperaría que esto sea un anidado dentro del "usuario" de hash, algo como esto:

    {"utf8"=>"✓", "authenticity_token"=>"YdTAsXwEvRgXIqri+jfx3dLlYG2XWQTuYkgLDsO/OJw=", "user"=>{"location"=>{"current_location_text"=>"E14 8JS"}, "commit"=>"Update Current Location", "id"=>"1"}} 
    

no creo Estoy siendo completamente estúpido aquí. ¿Me estoy perdiendo algo realmente obvio? He intentado agregar campos ocultos adicionales a mi formulario, es decir, una identificación de usuario, y luego obtengo el hash de usuario, pero al mismo nivel que el hash de "ubicación", ¡y no como padre de él como esperaba!

también si ayuda, aquí está mi actualización dentro de mi UsersController:

actualizar def @user = User.find (params [: id])

if @user.update_attributes(params[:user]) 
    redirect_to current_user, :notice => 'User was successfully updated.' 
else 
    render :action => "edit" 
end 

finales

y aquí está lo que hay en mi routes.rb (aunque no creo que sea relevante):

resources :users do 
    resource :location 
end 

Cualquier ayuda apreciada. Si no resuelvo esto, la computadora portátil se está saliendo por la ventana ... Gracias.

Respuesta

11
<%= fields_for(@user.location) do |location_fields| %> 

Ésta es su problema.Usted necesita realmente "nido" de la fields_for dentro de su forma, de esta manera:

<% f.fields_for(@user.location) do |location_fields| -%> 
+0

¿Referencia de documentación? Todo lo que puedo ver en los documentos es que '<% -%>' es para tratar con espacios en blanco al final. (http://api.rubyonrails.org/classes/ActionView/Base.html) – 0112

+0

Solo para aclarar, el problema era 'fields_for' vs' f.fields_for'. El '-%>' era solo un hábito. –

5

probar este lugar

<%= f.fields_for :location do |location_fields| %> 

En lugar de darle el objeto en sí, diga lo que los carriles asociación desee hacer que cargue para

+0

Gracias - en realidad lo que necesitaba hacer esto también, me resulta extraño que el uso de un objeto en la declaración fields_for no funciona. – DaveStephens

+0

Para cualquiera que use la gema Judge para la validación en línea: obtendrá errores con este método. Use @ user.location en lugar del símbolo porque Judge necesita hacer referencia al objeto. – bradleygriffith