ruby-on-rails – AcitveRecord不会使用嵌套的现有记录来接受新
ActiveRecord似乎并不理解,给定具有嵌套属性的现有记录的一组参数,它可以创建一个新的嵌套记录,该记录本身具有嵌套的现有记录. (关系树:现有 – >新 – >现有)
这是一个错误,还是我错过了什么? 让我举个简单的例子. 这是我的模特: 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 我在每个表中都创建了一条记录,并相应地将它们相关联,因此每个表中都有一条id = 1的记录 – 这是已知的.现在,如果我有一个现有用户,一个新帖子和一个现有组,并尝试使用accepts_nested_attributes_for更新该记录,它不喜欢它: 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,: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 > 它认为它无法找到与新??帖子相关的组(具有已知ID). 这种关系正在起作用: 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",:updated_at => nil } ] 如果所有记录都是新记录,则在用户创建期间使用posts_attributes和group_attributes时,它也完全有效. 它不应该仍然在第一个例子中工作吗? ActiveRecord应该足够聪明才能弄明白……! 解决方法
以下是我认为正在发生的事情:您正在传递一个组的ID,向ActiveRecord指示该组存在. ActiveRecord正试图找到该组以使用group_attributes中的其他数据更新它.由于您在post_attributes中执行此操作,因此ActiveRecord尝试通过帖子和组之间的关联来查找该组.也就是说,ActiveRecord首先查找关联的组 – 其中id = post.group_id – 然后从该结果中查找ID = 1的那个.对于父关系,这可能看起来有点奇怪和笨拙,就像你的情况一样,但是我确信你可以看到这是另一个方向的有用行为,其中嵌套属性代表一个或多个潜在的多个孩子.
但是,根据post_attributes中的数据创建的post对象尚未与组关联 – post.group_id为nil.因此,当ActiveRecord执行首次搜索以获取关联组时,它将显示为空.相应地,它没有在(空)结果中找到ID = 1的组.从技术上讲,记录就在那里,但在与帖子的关联方面并不存在. 你可以通过包括group_id =>证明这一点. 1在post_attributes中.我相信,如果你这样做,ActiveRecord将通过关联找到该组,然后在结果中成功地从ID = 1中选择该组,然后使用group_attributes中的附加数据更新该组. 另请注意,如果您允许用户在创建新帖子的同时更新组名称,那么在帖子中包含组内嵌组属性的唯一原因就是您要这样做.如果您要做的只是将新帖子链接到现有组,那么您只需要在post_attributes中包含group_id,就可以摆脱group_attributes. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |