2017-10-14 86 views
0

我們有一個使用2種模型的rails應用程序:圖像和視頻。 它們都屬於收藏實體。 如果我們想要以統一的方式查詢或使用這兩種類型 - 我們不能。所以如果我們想取得最後15個,我們會查詢兩次,然後再排序,然後再取15個。 如果我們想找到()一些ID,我們需要總是得到它是什麼類型 - 視頻或圖像...設計多態類

所以我們正在考慮如何解決這個問題。 持有指向任一個的資產模型? 它能夠被急切加載嗎?

在我看來,它必須是Asset.find(_id),並且我將無法識別圖像或視頻。

在Rails中解決這個問題的最簡單或最正確的方法是什麼?

謝謝!

+0

我認爲在軌道'enum'是你正在尋找。 http://api.rubyonrails.org/v5.1/classes/ActiveRecord/Enum.html。希望這個幫助。 – thanhnha1103

+0

沒有正確的方法來解決這個問題,因爲它是[Object-relational impedance mismatch](https://en.wikipedia.org/wiki/Object-relational_impedance_mismatch)的一個例子。解決這個問題的常用方法是使用單表或多表繼承。 – max

+0

使用Tamer所描述的STI將允許您執行MediaItem.find(id)並根據結果獲取視頻或圖像模型 – s1mpl3

回答

1

您可以使用Single Table Inheritance來實現此目標。

比方說,你有一個模式叫Media

rails g model media_item type:string <other attributes here> 

然後你從中兩款車型繼承:VideoImage,像這樣:

rails g model video --parent=MediaItem 
rails g model image --parent=MediaItem 

現在在你的模型:

class MediaItem < ApplicationRecord 
    belongs_to :collection 
end 

class Collection < ApplicationRecord 
    has_many :media_items 
end 

此方法隨附索姆儘管如此。例如,子類可能具有許多不同的屬性,並且最終可能會有太多屬性用於一個子類中,而不是另一個子類,反之亦然。

有一些解決方法,如有一個類似散列的properties字段幷包含子類特定的屬性。但是,如果您需要對特定屬性進行索引並且您的數據庫不支持此類索引,則這可能也會出現問題。或者你可以用1對1關係爲每個子類創建一個單獨的屬性 表,這種方式稱爲多表繼承,但這也有其缺點。這完全取決於你的具體用例。

+2

「或者您可以爲每個子類使用1對1關係創建單獨的屬性表「。這就是通常所說的多表繼承。 – max

+0

@max非常感謝,我其實不知道它有一個名字哈哈。將相應地更新答案。 –

+0

我期待使用我現在的模型。你所建議的是我應該將我的整個模型和應用程序轉換爲MediaItem。 – Himberjack