6

我的 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_portrait失败并出现异常。IE

# 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>

我不确定我做错了什么。浏览 Rails 指南,看起来这应该可以通过has_one关系实现。任何帮助将不胜感激。

4

3 回答 3

1

你会为这些命名约定而发疯。APrimaryPortrait和 a应该是不属于 a 的资产的SecondaryPortrait特例。它已经破坏了您无法构建的设计。PortraitPortrait

尝试这个:

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_portait_asset写一个实例方法

def build_primary_portrait_asset
  primary_portrait || build_primary_portrait
  primary_portrait.asset || primary_portrait.build_asset
end
于 2013-08-05T17:17:09.327 回答
0

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

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_primary_portrait来创建肖像模型,并通过subject.primary_portrait_asset.

于 2013-05-15T13:20:07.037 回答
0

为什么不执行以下操作。

class Portrait
  belongs_to :portrait_subject
  belongs_to :asset

  ...
end

-

class PrimaryPortrait < Portrait
  ...
end

-

class SupplementaryPortraits < Portrait
  ...
end

-

class PortraitSubject
  has_one     :primary_portrait
  has_many    :supplementary_portraits
  ...
end

这更接近于 Rails 设计模式。不过,您将不得不添加一个类型列。

于 2013-04-08T19:45:22.337 回答