ruby on rails - tag - Obteniendo fields_for y accept_nested_attributes_for para trabajar con una relaciĆ³n belongs_to
nested form rails (4)
Parece que no puedo obtener una forma anidada para generar en una vista de rieles para una relaciónnet_to usando el nuevo accepts_nested_attributes_for
facilidad de Rails 2.3. Verifiqué muchos de los recursos disponibles y parece que mi código debería estar funcionando, pero fields_for
me explota, y sospecho que tiene algo que ver con la forma en que tengo configurados los modelos anidados.
El error que golpeo es uno común que puede tener muchas causas:
''@account[owner]'' is not allowed as an instance variable name
Aquí están los dos modelos involucrados:
class Account < ActiveRecord::Base
# Relationships
belongs_to :owner, :class_name => ''User'', :foreign_key => ''owner_id''
accepts_nested_attributes_for :owner
has_many :users
end
class User < ActiveRecord::Base
belongs_to :account
end
Quizás sea aquí donde lo estoy haciendo ''rong'', ya que una Cuenta puede tener un ''propietario'' y puede ser ''usuarios'', pero un usuario solo tiene una ''cuenta'', basada en la clave account_id del modelo de usuario.
Este es el código de vista en new.html.haml que explota en mí:
- form_for :account, :url => account_path do |account|
= account.text_field :name
- account.fields_for :owner do |owner|
= owner.text_field :name
Y este es el código del controlador para la nueva acción:
class AccountsController < ApplicationController
# GET /account/new
def new
@account = Account.new
end
end
Cuando intento cargar / cuenta / nuevo obtengo la siguiente excepción:
NameError in Accounts#new
Showing app/views/accounts/new.html.haml where line #63 raised:
@account[owner] is not allowed as an instance variable name
Si trato de usar el misterioso método de "compilación", simplemente bombardea el controlador, tal vez porque la compilación es solo para relaciones de múltiples registros:
class AccountsController < ApplicationController
# GET /account/new
def new
@account = Account.new
@account.owner.build
end
end
You have a nil object when you didn''t expect it!
The error occurred while evaluating nil.build
Si trato de configurar esto usando @ account.owner_attributes = {} en el controlador, o @ account.owner = User.new, estoy de regreso al error original, "@account [owner] no está permitido como una instancia nombre de la variable".
¿Alguien más tiene el nuevo método accept_ested_attributes_for que trabaja con una relación belongs_to? ¿Hay algo especial o diferente que tienes que hacer? Todos los ejemplos oficiales y el código de muestra (como las grandes cosas de Ryans Recortes ) se refieren a asociaciones de registros múltiples.
Creo que tus accepts_nested_attributes
están en el lado equivocado de la relación. Tal vez algo como esto podría funcionar?
class Account < ActiveRecord::Base
belongs_to :owner, :class_name => ''User'', :foreign_key => ''owner_id''
has_many :users
end
class User < ActiveRecord::Base
belongs_to :account
has_one :account, :foreign_key => :owner_id
accepts_nested_attributes_for :account
end
Para construir la cuenta que desea utilizar build_account.
Puedes ver más ejemplos en la documentación .
Estoy usando Rails 2.3.5 y noté lo mismo. Verificando la fuente para active_record''s anested_attributes.rb, parece que pertenece a que debería funcionar bien. Por lo que parece que podría ser un error de "formularios anidados".
Tengo una forma anidada exactamente igual a la suya, con el User belongs_to :address
, y la Address
es independiente del usuario.
Luego, en el formulario, acabo de hacer <% f.fields_for :address_attributes do |address_form| %>
<% f.fields_for :address_attributes do |address_form| %>
lugar de <% f.fields_for :address do |address_form| %>
<% f.fields_for :address do |address_form| %>
. Hack temporal hasta que haya una mejor manera, pero esto funciona. El método accepts_nested_attributes_for
está esperando que los parámetros incluyan algo como:
{user=>{address_attributes=>{attr1=>''one'',attr2=>''two''}, name=>''myname''}
... pero fields_for
está produciendo:
{user=>{address=>{attr1=>''one'',attr2=>''two''}, name=>''myname''}
De esta manera, no tiene que agregar esa has_one :account
a su código, que no funciona en mi caso.
Actualización: Encontré una mejor respuesta:
Aquí está la esencia del código que estoy usando para hacer este trabajo correcto:
Formas anidadas de rieles con belongs_to Gist
Espero que ayude.
Llegué unos meses demasiado tarde, pero estaba tratando de resolver este error y mi situación era que no podía cambiar la relación para "enfrentarme de otra manera".
La respuesta es bastante simple, debes hacer esto en tu nueva acción:
@account.build_owner
La razón por la que el formulario no se mostraba mediante fields_for era porque no tenía un objeto válido. Tenías la idea correcta allá arriba con:
@account.owner.build
Sin embargo, esta no es la forma de trabajo. Este método solo se genera con has_many
y has_and_belongs_to_many
.
Referencia: http://guides.rubyonrails.org/association_basics.html#belongs-to-association-reference
class Account < ActiveRecord::Base
belongs_to :owner :class_name => ''User'', :foreign_key => ''owner_id''
end
Esto funciona para mi. : foreign_key => ''owner_id'' fue el problema clave en mi caso.