I have a Rails app with the following (simplified) models:
# 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
If I try to use the .build
method on the association, the created object doesn't have the foreign key set. This causes it to fail validation, or without the validation become not be associated with the 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">
Which conflicts with the Rails Guide :
The collection.build method returns one or more new objects of the associated type. These objects will be instantiated from the passed attributes, and the link through their foreign key will be created, but the associated objects will not yet be saved.
Obviously, manually setting the member_id is a easy work around. But I'd like to avoid that. I believe this code worked correctly in previous versions of rails;the above is the behavior of Rails 3.2.3.
I had as an initializer the code in grosser's answer at: Can nested attributes be used in combination with inheritance?
Changing that to:
class ActiveRecord::Reflection::AssociationReflection
def build_association(*options, &block)
if options.first.is_a?(Hash) and options.first[:type].presence
options.first[:type].to_s.constantize.new(*options, &block)
else
klass.new(*options, &block)
end
end
end
solved the problem.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.