2013-04-08 13 views
6

Mam następujący model danych w moich Rails 2.3 aplikacjaSzyny has_one: through. Budynek związany obiekt

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 

Chcę zbudować powiązane modele proxy przy użyciu Rails, ale staramy się budować primary_portrait niepowodzeniem z wyjątek. To znaczy.

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

Nie jestem pewien, co robię źle. Przeglądając przewodnik po Railsach, wygląda na to, że powinno to być możliwe z relacją has_one. Każda pomoc będzie wielce ceniona.

+1

jesteś pewien, że można budować ': skojarzenia through'? Jeśli tak, proszę podać link – Zippie

Odpowiedz

0

Dlaczego nie wykonać następujących czynności.

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 

Wynika wzorców projektowych szyny bliżej. Będziesz jednak musiał dodać kolumnę typu.

0

Sugeruję podzielenia tego na dwa stowarzyszenia:

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 

Następnie można użyć subject.build_primary_portrait stworzyć model portret, a dostęp do jego aktywów przez subject.primary_portrait_asset.

1

Będziesz szaleć z tymi konwencjami nazewnictwa. A PrimaryPortrait i SecondaryPortrait powinny być wyjątkowymi przypadkami, gdy nie są to aktywa należące do Portrait. To już łamie twój projekt, że nie możesz go zbudować.

Spróbuj tego:

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 

następnie, jeśli trzeba zbudować primary_portait_asset napisać metodę instancji

def build_primary_portrait_asset 
    primary_portrait || build_primary_portrait 
    primary_portrait.asset || primary_portrait.build_asset 
end 
Powiązane problemy