我有一个带有以下(简化)模型的 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冲突:
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.
显然,手动设置 member_id 很容易解决。但我想避免这种情况。我相信这段代码在以前版本的 rails 中工作正常;以上是 Rails 3.2.3 的行为。
最佳答案
我在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
解决了这个问题。
关于ruby-on-rails - ActiveRecord 未使用 .build 在 has_many 关联上设置外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10101228/