Ruby on rails Rails有一个:直通。建筑关联对象

Ruby on rails Rails有一个:直通。建筑关联对象,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,我的Rails 2.3应用程序中有以下数据模型 class PortraitSubject has_many :portraits has_one :primary_portrait, :through => :portraits, :source => :asset, :conditions => ['portraits.primary = ?', true] has_many :supplementary_portraits, :throug

我的Rails 2.3应用程序中有以下数据模型

class PortraitSubject
  has_many    :portraits
  has_one     :primary_portrait, :through => :portraits, :source => :asset, :conditions => ['portraits.primary = ?', true]
  has_many    :supplementary_portraits, :through => :portraits, :source => :asset, :conditions => ['portraits.primary = ?', false]

  ...
end

class Portrait
  belongs_to :portrait_subject
  belongs_to :asset

  ...
end
我想使用Rails构建关联的代理模型,但尝试构建
primary\u-grait
失败,出现异常。即

# This works
subject = PortraitSubject.new
subject.supplementary_portraits.build
subject.save

# This doesn't
subject = PortraitSubject.new
subject.build_primary_portrait
# => NoMethodError: undefined method `build_primary_portrait' for #<PortraitSubject:0x007ff16fe38948>
#这很有效
subject=subject.new
主题。辅助肖像。建筑
subject.save
#这并不重要
subject=subject.new
subject.build\u primary\u肖像
#=>NoMethodError:未定义的方法“构建主肖像”#

我不确定我做错了什么。从导轨看,这似乎是可能的,因为
有一个关系。任何帮助都将不胜感激。

为什么不做以下事情呢

class Portrait
  belongs_to :portrait_subject
  belongs_to :asset

  ...
end
-


这更接近rails设计模式。不过,您必须添加一个类型列。

我建议将其分为两个关联:

class PortraitSubject
  has_many    :portraits
  has_one     :primary_portrait, :class_name => "Portrait", :conditions => ['portraits.primary = ?', true]
  has_one     :primary_portrait_asset, :through => :primary_portrait, :source => :asset

  has_many    :supplementary_portraits, :class_name => "Portrait", :conditions => ['portraits.primary = ?', false]
  has_many     :supplementary_portrait_assets, :through => :supplementary_portraits, :source => :asset

  ...
end

然后,您可以使用
subject.build\u primary\u patrait
来创建肖像模型,并通过
subject.primary\u patrait\u asset
访问其资产。这些命名约定会让您发疯的。
主要肖像
次要肖像
应该是
肖像
的特例,而不是属于
肖像
的资产。它已经打破了你的设计,你不能建立一个

试试这个:

class PortraitSubject
  has_many    :portraits
  has_one     :primary_portrait, :conditions => {:primary => true}
  has_many    :supplementary_portraits, :conditions => {:primary => false}

  has_many    :portrait_assests, :through => :portraits
  has_one     :primary_portrait_asset, :through => :primary_portrait
  has_many    :supplementary_portrait_assets, :through => :supplementary_portraits

end
然后,如果您需要构建一个
primary\u portait\u资产
,请编写一个实例方法

def build_primary_portrait_asset
  primary_portrait || build_primary_portrait
  primary_portrait.asset || primary_portrait.build_asset
end

您确定可以通过关联构建
:吗?如果你是,请提供一个链接
class PortraitSubject
  has_many    :portraits
  has_one     :primary_portrait, :class_name => "Portrait", :conditions => ['portraits.primary = ?', true]
  has_one     :primary_portrait_asset, :through => :primary_portrait, :source => :asset

  has_many    :supplementary_portraits, :class_name => "Portrait", :conditions => ['portraits.primary = ?', false]
  has_many     :supplementary_portrait_assets, :through => :supplementary_portraits, :source => :asset

  ...
end
class PortraitSubject
  has_many    :portraits
  has_one     :primary_portrait, :conditions => {:primary => true}
  has_many    :supplementary_portraits, :conditions => {:primary => false}

  has_many    :portrait_assests, :through => :portraits
  has_one     :primary_portrait_asset, :through => :primary_portrait
  has_many    :supplementary_portrait_assets, :through => :supplementary_portraits

end
def build_primary_portrait_asset
  primary_portrait || build_primary_portrait
  primary_portrait.asset || primary_portrait.build_asset
end