1

我面临选择 #1 的问题:

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

还是有不同/更好的方法来做到这一点?

4

1 回答 1

3

您可以使用名为Forwardable的标准 Ruby 库。

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
于 2016-12-21T22:09:10.560 回答