2013-07-12 28 views
0

在Ruby項目我的工作,我想補充的ActiveRecord風格,MVC功能類似如下的混入建築類型號:在mixin模塊中設置類變量的乾淨界面是什麼?

module Model 

    # Classes that mixin this module gain ActiveRecord-style class methods 
    # like Model.all, Model.first, Model.last et al. 
    # 
    # Throughout this module, @@database_bridge will contain a reference to a 
    # database ORM bridge, that does the dirty implementation of these methods. 

    def all 
    # Implementation stuff here, using @@database_bridge as appropriate 
    end 

    def first 
    ... 
    end 

    # et al 

end 


class ExampleModel 

    extend Model 

    # Model-specific implementation goes here... 

end 

調用e = ExampleModel.first將在數據庫中分配第一ExampleModele

我想在運行時使用依賴注入來設置@@database_bridge,這樣每個包含extend Model的類都使用相同的指定ORM對象。

我該怎麼做?

如果我可以編寫某種輔助方法來根據需要設置類變量,那就太好了。

+0

如果有人認爲我會更好地繼承基礎「模型」類的東西,那真的不符合我的類層次結構。 該框架在其_core_不是MVC,它只是使用MVC風格的類方法作爲從數據庫中提取東西的優雅方式。 – ChasingTheJames

回答

0

我發現比以前更好的解決方案,它比我想象的要簡單得多(D'哦!):由一個mixin模塊,通過公共接口,該方法在前綴與self.的方法Module.method變爲可用。

因此,我們只需添加一個setter到我們的模塊,使用self.attribute_set聲明。

在上面的例子中,上述方法將產生以下代碼:

module Model 

    # Classes that mixin this module gain ActiveRecord-style class methods 
    # like Model.all, Model.first, Model.last et al. 
    # 
    # Throughout this module, @@database_bridge will contain a reference to a 
    # database ORM bridge, that does the dirty implementation of these methods. 

    def all 
    # Implementation stuff here, using @@database_bridge as appropriate 
    end 

    def first 
    ... 
    end 

    def self.set_database_bridge(ref_to_new_bridge) 
    @@database_bridge = ref_to_new_bridge 
    ## any additional intialisation/sanitisation logic goes here 
    end 

    # et al 

end 


class ExampleModel 

    extend Model 

    # Model-specific implementation goes here... 

end 

調用Model.set_database_bridge將使我們能夠通在一個新的數據庫橋

如果我們實際上並不需要在我們的輔助函數初始化任何禁制或邏輯,還有一個更優雅的方式 - 一個class << self內添加attr_accessor,即:

module Model 

    # ... 

    class << self 
    attr_accessor :database_bridge 
    end 

end 

這樣,我們可以打電話給Ruby的標準setter方法Model.database_bridge = the_new_bridge

甜。

+0

這真的是我正在尋找的答案,如果沒有人對此方法有任何具體的「陷阱」,那麼明天就會打勾。 意見和建議表示讚賞! – ChasingTheJames

0

這不是答案,而是一個潛在的解決方案你可以調用class_variable_set一個模塊上,通過調用Module.class_variable_set

因此,您可以在某處調用Module.class_variable_set :@@class_var, "new value"的適當名稱空間中創建一個輔助方法。

對於上面的例子中,我的助手功能將是這樣的:

def set_database_bridge(new_bridge) 
    Model.class_variable_set :@@database_bridge, new_bridge 
end 

該解決方案產生一定程度的輔助功能和Model混入的執行之間的耦合,彷彿名稱@@數據庫橋將發生變化,輔助函數將會中斷。

如果任何人有一個更鬆散耦合/更封裝的解決方案的想法(我們可能在某個地方封裝了幫助函數Model),那太棒了!

相關問題