2016-12-21 72 views
1

我面臨選擇反對任何#1:紅寶石如何委派命名空間的模塊功能,命名空間:: Base的內部類

class Abstract 
end 
class Abstract::Foo < Abstract 
end 
class Abstract::Bar < Abstract 
end 

對#2:

module Abstract 
    class Base 
    end 
    class Foo < Base 
    end 
    class Bar < Base 
    end 
end 

我最終選擇選項#2,我的Abstract感覺更像是一個命名空間,我可能最終添加其他的東西像

module Abstract # Instead of class if I had used option #1 
    class SomeAbstractService 
    end 
end 

但是我覺得打電話Abstract::Base.some_class_method有點奇怪。有可能添加模塊功能委託?例如,如果我Base是一個ActiveRecord或Mongoid模型(所以Foo和Bar就像STI),我希望能夠查詢集合/表

Abstract.where(...)而不是Abstract::Base.where(...)

是否有可能將模塊功能.where委託給常量/類Base

喜歡的東西

module Abstract 
    class Base 
    end 

    delegate_module_function :where, to: :Base 
end 

還是有不同的/更好的方式來做到這一點?

回答

3

您可以使用標準Ruby庫,名爲Forwardable

require 'forwardable' 

module Abstract 
    extend SingleForwardable 
    class Base 
    def self.where(p) 
     "where from base : #{p}" 
    end 
    end 

    delegate :where => Base 
end 

Abstract.where(id: 3) 
# => "where from base : {:id=>3}" 

對於多種方法,你可以寫:

delegate [:where, :another_method] => Base 
+2

此。模塊和類就像任何其他對象一樣是對象,沒有什麼特別的。你將在它們之間委託方法的方式與你在任何其他兩個對象之間委託方法的方式完全相同,因爲它們*只是任何其他對象。 –