ActiveRecordはネストされた属性を持つ既存のレコードのパラメータセットを受け取ると、ネストされた新しいレコードを作成できます。既存のレコードです。 (関係ツリー:Existing -> New -> Existing
)AcitveRecordはネストされた既存のレコードを持つ新しい関連レコードを受け入れません。
これはバグですか、それとも不足していますか?
簡単な例を示しましょう。ここで
は私のモデルです:
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
私は各テーブルに1つのレコードを作って、それに応じて関連するので、各テーブルには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,
: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 >
それがグループを見つけることができないと考えて(既知のIDを持つ)、新しい投稿に関連しています。 group_attributes
からIDを削除すると機能します(ただし、新しいグループレコードが作成されます)。 私はposts_attributes
にIDを与え、group_attributes
からIDを削除して(そして再び新しいグループを作成すると)動作します。 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",
:created_at => nil,
:updated_at => nil
}
]
User
作成中posts_attributes
とgroup_attributes
を使用する際にすべてのレコードが新規であればそれはまた完全に動作します。
最初の例ではまだ動作しませんか? ActiveRecordはこれを理解するのに十分スマートでなければなりません...!
ユーザモデルに 'has_many:comments'がありません。 – jordanpg
おっと、問題は依然として立っています。私はこの例を単純化します。 – wulftone
長い質問ですが、新しいレコードにはどのように既存の関連がありますか? – pjammer