次の(簡略化された)モデルのRailsアプリがあります。
# member.rb
class Member < ActiveRecord::Base
has_many :member_roles, :dependent => :destroy,
:autosave => true, :inverse_of => :member
end
..。
# member_role.rb
class MemberRole < ActiveRecord::Base
belongs_to :member, :inverse_of => :member_roles
validates_presence_of :member_id
end
アソシエーションでメソッドを使用しようとすると.build
、作成されたオブジェクトに外部キーが設定されていません。これにより、検証が失敗するか、検証がないとに関連付けられなくなりますMember
。
# Rails console
> m = Member.find(280)
> mr = m.member_roles.build(:role_id => Role.find_by_name("Crew Chief").id)
=> #<MemberRole id: nil, member_id: nil, role_id: 6697350, start_date: nil, \
end_date: nil, memo: nil, created_at: nil, updated_at: nil>
> mr.save!
ActiveRecord::RecordInvalid: Validation failed: Member can't be blank
> mr.save(:validate => false)
> mr
=> #<MemberRole id: 1834, member_id: nil, role_id: 6697350, start_date: nil, \
end_date: nil, memo: nil, created_at: "2012-04-11 06:37:00", \
updated_at: "2012-04-11 06:37:00">
Railsガイドと競合するもの:
collection.buildメソッドは、関連付けられたタイプの1つ以上の新しいオブジェクトを返します。これらのオブジェクトは渡された属性からインスタンス化され、それらの外部キーを介したリンクが作成されますが、関連するオブジェクトはまだ保存されていません。
明らかに、member_idを手動で設定するのは簡単な回避策です。しかし、私はそれを避けたいと思います。このコードは以前のバージョンのRailsで正しく機能したと思います。上記はRails3.2.3の動作です。