2013-10-24 198 views
3

我需要幫助實現或將其分解爲單表繼承(STI)。我已經閱讀過有關這方面的內容,但如果我以正確的方式開展工作,我還不太確定。如果你們有建議來實施它。或者,即使它與我現在有很大不同,請諮詢。STI幫助。需要幫助重構我現有的代碼

所以,通常我有以下類(所有模型)。

class Article < ActiveRecord::Base 
    has_many :attachments 

    has_many :medias 
    has_one :banner 

    accepts_nested_attributes :medias 
    ... 
end 

class Attachment < ActiveRecord::Base 
    belongs_to :article 
end 

class Media < Attachment 
    default_scope { where(attachment_type: 'media') } 

    def audio?; media_type == 'audio'; end 
    def video?; media_type == 'video'; end 

    validate :embed_url, presence: true if :video? 

    def path 
    if audio? 
     # Different audio path 
    elsif video? 
     # Different video path 
    end 
    end 

    after_commit :process_audio_file 
    def process_audio_file; ...; end 

    after_commit :process_video_file 
    def process_video_file; ...; end 
end 

class Banner < Attachment 
    default_scope { where(attachment_type: 'banner') } 
    ... 
end 

,通常它會正常工作太..

article = Article.first 
first_media = article.medias.first 
banner = article.banner 

但後來我發現,Media可能會是臃腫,有不同的東西太多不同的邏輯不同的media_types做。所以我試圖通過這樣做來區分它們:

class Article < ActiveRecord::Base 
    has_many :attachments 

    has_many :medias 
    has_one :banner 

    accepts_nested_attributes_for :medias 
end 

class Attachment < ActiveRecord::Base 
    belongs_to :article 
end 

class Media < Attachment 
    default_scope { where(attachment_type: 'media') } 
end 

class AudioMedia < Media 
    default_scope { where(media_type: 'audio') } 

    def path 
    # Audio path 
    end 

    after_commit :process_audio_file 
    def process_audio_file; ...; end 
end 

class VideoMedia < Media 
    default_scope { where(media_type: 'video') } 

    validate :embed_url, presence: true 

    def path 
    # Video path 
    end 

    after_commit :process_video_file 
    def process_video_file; ...; end 
end 

現在我在這裏將邏輯彼此分開。大!但現在它帶來像幾個問題:

article = Article.first 
first_media = article.medias.first 

在這樣做,我只是我在Media類......爲了讓說AudioMedia類,我要做的是:

"#{first_media.media_type}Media".constantize.find(first_media.id) 

此外,爲了使我的nested_attributes能夠正常工作,我必須定義

accepts_nested_attributes_for :audio_medias 
accepts_nested_attributes_for :video_medias 

使其工作正確嗎?然後我不得不定義他們的關係,就像:

has_many :medias 
has_many :audio_medias 
has_many :video_medias 

有什麼建議嗎?謝謝,歡呼!

編輯

添加相關的表和字段

articles 
    id 
    [some_other_fields] 

attachments 
    id 
    article_id 
    attachment_type # media, banner, etc... 
    media_type # audio, video, etc... 
    [some_other_fields] 
+1

附件表中是否有'type'列? STI需要這個來確定單個記錄的類別 –

+0

@MarkMeeus類型是什麼意思?我爲「文章」和「附件」添加了表格和字段。 – index

+0

我在下面發佈了一個答案... –

回答

0

,你可以請添加您的遷移?

通常情況下,我希望是這樣的:

article.medias.first.class == AudioMedia #true 

,並有一個原因把媒體類的地方嗎?只是爲了進行默認範圍,這不是必需的,因爲您有一個分開的Class AudioMedia或VideoMedia,它位於類型爲AudioMedia或VideoMedia的附件中。你可以很容易地通過他們的類名訪問它們。

順便說一句,你應該看看paperclip或carrier_wave。

+0

是的。通常它會像'article.medias.first'那樣在最上面提到,它通常是'Media'。但我想根據STI的建議分開它們的邏輯。 「媒體」也用於包含任何媒體的常用方法和其他方法。 – index

0

看起來你錯過了一些與STI相關的重要信息。 當你創建一個新的AR實例並且你的表有一個名爲'type'的列時,AR會在你的列中存儲你的對象的類名。 稍後選擇記錄時,AR將使用類型列中的值來檢測要構造它的類。

它看起來像你在某種程度上通過使用這些示波器和音頻實現類似的東西?視頻?方法。

所以第一

rails g migration add_type_to_attachments type:string 
rake db:migrate 

然後讓你的代碼看起來是這樣的:

class Article < ActiveRecord::Base 
    has_many :attachments  
    accepts_nested_attributes_for :attachments 
end 

class Attachment < ActiveRecord::Base 
    belongs_to :article 
end 

class Media < Attachment 

end 

class AudioMedia < Media 

    def path 
    # Audio path 
    end 

    after_commit :process_audio_file 
    def process_audio_file; ...; end 
end 

class VideoMedia < Media   
    validate :embed_url, presence: true 

    def path 
    # Video path 
    end 

    after_commit :process_video_file 
    def process_video_file; ...; end 
end  

現在所有的附件都在一個場

article.attachments 

如果您只需要例如視頻

article.attachments.select{|a|a.is_a? VideoMedia} 
+0

有沒有在軌道內置這個?我似乎無法找到它。你能爲這個文件提供一個鏈接,這樣我可以進一步閱讀嗎?另外,如果我這樣做,並做了'article.attachments.select {| a | a.is_a? VideoMedia}'我還需要做一個'VideoMedia.find(#)'才能找到實際的模型?或者我怎樣才能得到它? – index