我的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
失败并出现异常。即。
# 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
关系。任何帮助将不胜感激。
答案 0 :(得分:1)
你会对这些命名惯例感到疯狂。 PrimaryPortrait
和SecondaryPortrait
应该是Portrait
的特殊情况,而不是属于Portrait
的资产。它已经破坏了你的设计,你不能建立一个。
试试这个:
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
答案 1 :(得分: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
这更紧密地遵循导轨设计模式。您必须添加一个类型列。
答案 2 :(得分: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
访问其资源。