如何通过集合表达 :has_one assocation :,并带有 :条件来构造/选择"the one"?



我有一些像这样的模型(Rails 3.2),A->B->C,用来为一个覆盖许多区域(B)的Manager(A)建模,每个区域都有许多地址(C)。其中一个地址是经理的主要地址。我想不出将经理与他的主要地址联系起来的最佳方式。

class AreaManager < ActiveRecord::Base
  has_many :areas, :dependent=>:destroy
  has_many :addresses, :through=>:areas
  ...
  def primary_address
    self.addresses.where(:primary=>true).first 
      # in fact, there can be only one
  end
end
class Area < ActiveRecord::Base
  belongs_to :area_manager
  has_many :addresses,:dependent=>:destroy
end
class Address < ActiveRecord::Base
  belongs_to :area
  attr_accessible :primary 
    # this is the manager's primary address (not the area's)
end

这让我可以说,例如:

a = AreaManager.find(123)
a.primary_address # => her primary address

但我真正想要的是一个构造函数/设置器以及一个getter:

a = AreaManager.new
a.build_primary_address ...

我可以添加到区域:

has_one :primary_address, 
  :class_name=>'Address', 
  :conditions => {:primary=>true}

这让我可以做

a1 = Area.new
a1.build_primary_address ... # instantiates an Address with primary = true

但当我尝试做一些类似于AreaManager的事情时,通过添加

has_one :primary_address, 
  :through=>:areas, 
  :source=>:address, 
  :conditions=>{:primary=>true}

然后说:

a = AreaManager.new
a.build_primary_address ... 
  # instead of creating an area and an address, it croaks

我得到一个ActiveRecord::HasOneThroughCantAssociateThroughCollection异常。我不知道什么是正确的咒语(或者是否有)。有Railsy的方法吗?

由于rails都是关于以下约定和许多选项中的正确chocie,我建议:

  • 不将条件应用于关联

  • 查找以使用命名的scope

  • 请使用.where(rails3)而不是conditions(rails2)。有关更多信息,请参阅ActiveRecord api应用所有这些可能会稍微改变你的代码,你会得到不同的结果。

最新更新