2014-10-01 41 views
2

我正在尋找在我的項目之一中的實施策略設計模式,這是在軌道上。基本上,我必須調用由數據庫中的單個字段區分的對象的方法,而這種差異將確保不同的方法行爲。在數據庫中存儲類名以模仿設計模式 - Ruby on Rails

經過一番研究,我發現紅寶石很少需要設計模式,它使用鴨子打字。現在爲了實現同樣的效果,我正在考慮將類名稱存儲在數據庫中,並在需要時調用該類的方法。像這樣,

duckOne = Duck.find(id) 
duckOne[:className].fly(duckOne) #This scenario is same as Class.fly,but class is coming from db 

duckTwo = Duck.find(id) 
duckTwo[:className].fly(duckTwo) #Similar to above, just a different class from database 

有沒有更好的方法來做到這一點?這種方法是否正確?

+0

的此另一種方法被定義在[此處](http://stackoverflow.com/questions/3570611/cheat-sheet-for-all-design-patterns-implemented-in - 魯比),看看。 – Anss 2014-10-01 08:58:26

回答

1

基本上,從你所描述的,我認爲你正在尋找Single Table Inheritance (STI)(你可能需要滾動才能找到信息)。

使用STI,您可以使用一個數據庫表來表示來自同一個超類的多個類。 Rails使用名爲type的列來知道將哪個類解釋爲db行。

您仍然可以在超類上使用find方法來查找各種子類模型。

例如:

class Bird < ActiveRecord::Base 
    def quack 
    "quack" 
    end 
end 

class Duck < Bird 
    def quack 
    "foo" 
    end 
end 

class Goose < Bird 
    def quack 
    "bar" 
    end 
end 

duck = Duck.create 
goose = Goose.create 

Bird.find(duck.id).quack 
# => "foo" 
Bird.find(goose.id).quack 
# => "bar" 
+0

這是一個可能的解決方案,但它完全不符合我的方案。我將類名存儲在數據庫中,獲取它,做了'className.constantize',並將className用作class'className.fly'超級簡單! – Anss 2014-10-01 14:30:56

+0

請解釋此解決方案如何不符合您的「問題」(這似乎更像是一個討論邀請)。我認爲STI可以根據數據庫中的某些數據來實現某種行爲變化,尤其是與屬於同一個表中的對象有關的情況。使用繼承是在面向對象的上下文中建模的一種好方法。 – Jesper 2014-10-01 14:42:07

+0

當然,如果你想在幾個模型上共享這個策略模式,其中一些不使用相同的數據庫表,你最好做一些你所做的變體,或許把它抽象成一個模塊。 – Jesper 2014-10-01 14:47:14