ActiveRecord no parece entender que, dado un conjunto de parámetros para un registro existente con atributos anidados, puede crear un nuevo registro anidado que tiene un anidado registro existente. (Árbol de relaciones: Existing -> New -> Existing
)AcitveRecord no acepta attributes_nested_attributes_for nuevos registros asociados con registros existentes anidados
¿Esto es un error o me falta algo?
Déjame mostrarte un ejemplo simple.
Éstos son mis modelos:
class User < ActiveRecord::Base
has_many :posts
attr_accessible :name, :posts_attributes
accepts_nested_attributes_for :posts
end
class Post < ActiveRecord::Base
belongs_to :group
belongs_to :user
attr_accessible :content, :title, :group_attributes
accepts_nested_attributes_for :group
end
class Group < ActiveRecord::Base
has_many :posts
attr_accessible :name
end
que he realizado un registro en cada mesa, y los relacionados con la consecuencia, por lo que cada tabla tiene un registro en ella con un id=1
--Este es conocido. Ahora, si tengo un usuario existente, un nuevo mensaje, y un grupo existente, y trato de actualizar ese registro utilizando accepts_nested_attributes_for
, que no le gusta:
1.9.3-p125 :044 > params
{
:id => 1,
:name => "Billy",
:posts_attributes => [
[0] {
:title => "Title",
:content => "Some magnificent content for you!",
:group_attributes => {
:id => 1,
:name => "Group 1"
}
}
]
}
1.9.3-p125 :045 > u
#<User:0x00000002f7f380> {
:id => 1,
:name => "Billy",
:created_at => Fri, 03 Aug 2012 20:21:37 UTC +00:00,
:updated_at => Fri, 03 Aug 2012 20:21:37 UTC +00:00
}
1.9.3-p125 :046 > u.update_attributes params
(0.1ms) begin transaction
(0.1ms) rollback transaction
ActiveRecord::RecordNotFound: Couldn't find Group with ID=1 for Post with ID=
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/nested_attributes.rb:462:in `raise_nested_attributes_record_not_found'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/nested_attributes.rb:332:in `assign_nested_attributes_for_one_to_one_association'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/nested_attributes.rb:288:in `group_attributes='
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/attribute_assignment.rb:94:in `block in assign_attributes'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/attribute_assignment.rb:93:in `each'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/attribute_assignment.rb:93:in `assign_attributes'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/base.rb:498:in `initialize'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/reflection.rb:183:in `new'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/reflection.rb:183:in `build_association'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/associations/association.rb:233:in `build_record'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/associations/collection_association.rb:112:in `build'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/nested_attributes.rb:405:in `block in assign_nested_attributes_for_collection_association'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/nested_attributes.rb:400:in `each'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/nested_attributes.rb:400:in `assign_nested_attributes_for_collection_association'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/nested_attributes.rb:288:in `posts_attributes='
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/attribute_assignment.rb:85:in `block in assign_attributes'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/attribute_assignment.rb:78:in `each'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/attribute_assignment.rb:78:in `assign_attributes'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/persistence.rb:216:in `block in update_attributes'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/transactions.rb:295:in `block in with_transaction_returning_status'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/transactions.rb:208:in `transaction'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/transactions.rb:293:in `with_transaction_returning_status'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/persistence.rb:215:in `update_attributes'
from (irb):15
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.7/lib/rails/commands/console.rb:47:in `start'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.7/lib/rails/commands/console.rb:8:in `start'
from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.7/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'1.9.3-p125 :047 >
Se piensa que no puede encontrar un grupo (con un ID conocido), relacionado con un nuevo mensaje. Funciona cuando elimino el ID del group_attributes
(pero crea un nuevo registro de grupo). Funciona cuando doy una ID al posts_attributes
y elimino la identificación del group_attributes
(y de nuevo crea un nuevo grupo). También funciona cuando todos tienen ID.
La relación está funcionando:
1.9.3-p125 :059 > p = Post.new({ group_attributes: { name: 'Testing' } })
#<Post:0x00000004212380> {
:id => nil,
:title => nil,
:content => nil,
:group_id => nil,
:user_id => nil,
:created_at => nil,
:updated_at => nil
}
1.9.3-p125 :060 > p.group
[
[0] #<Group:0x00000004211868> {
:id => nil,
:name => "Testing",
:created_at => nil,
:updated_at => nil
}
]
También funciona por completo cuando se utiliza posts_attributes
y group_attributes
durante User
creación, si todos los registros son nuevos.
¿No debería funcionar todavía en el primer ejemplo? ActiveRecord debe ser lo suficientemente inteligente como para resolver esto ...!
Falta un 'has_many: comments' en el modelo de Usuario. – jordanpg
oops, bueno, el problema sigue en pie. :) Simplificaré el ejemplo. – wulftone
pregunta larga, pero ¿cómo un nuevo registro tiene una asociación existente? – pjammer