我有一个带有以下(简化)模型的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 Guide冲突:
collection.build方法返回一个或多个相关类型的新对象。这些对象将从传递的属性中实例化,并且将创建通过其外键的链接,但是尚未保存关联的对象。
显然,手动设置member_id是一件容易的事。但我想避免这种情况。我相信这段代码在以前版本的rails中正常工作;上面是Rails 3.2.3的行为。
答案 0 :(得分:0)
我作为初始化程序在grosser的答案中使用了代码:Can nested attributes be used in combination with inheritance?
将其更改为:
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
解决了这个问题。