2013-04-08 32 views
6

tôi có mô hình dữ liệu sau trong Rails của tôi 2.3 ứng dụngRails has_one: thông qua. Xây dựng liên quan đến đối tượng

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 

Tôi muốn xây dựng các mô hình ủy quyền liên quan đến sử dụng Rails nhưng cố gắng xây dựng primary_portrait không thành công với một ngoại lệ. I E.

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

Tôi không chắc mình đang làm gì sai. Nhìn qua các hướng dẫn Rails, có vẻ như điều này có thể xảy ra với mối quan hệ has_one. Mọi sự trợ giúp sẽ rất được trân trọng.

+1

bạn có chắc bạn có thể xây dựng ': hiệp hội through'? Nếu bạn vui lòng cung cấp liên kết – Zippie

Trả lời

0

Tại sao không làm như sau.

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 

này sau mẫu thiết kế đường ray chặt chẽ hơn. Bạn sẽ phải thêm một cột kiểu mặc dù.

0

tôi muốn đề nghị tách thành hai hiệp hội:

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 

Sau đó, bạn có thể sử dụng subject.build_primary_portrait để tạo ra các mô hình chân dung, và truy cập vào tài sản của mình thông qua subject.primary_portrait_asset.

1

Bạn sẽ phát điên với các quy ước đặt tên đó. A PrimaryPortraitSecondaryPortrait phải là trường hợp đặc biệt của Portrait không phải là nội dung thuộc về một số Portrait. Nó đã phá vỡ thiết kế của bạn mà bạn không thể xây dựng một.

Hãy thử điều này:

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 

sau đó, nếu bạn cần phải xây dựng một primary_portait_asset viết một phương pháp dụ

def build_primary_portrait_asset 
    primary_portrait || build_primary_portrait 
    primary_portrait.asset || primary_portrait.build_asset 
end 
Các vấn đề liên quan