使用const_missing来引用模块外部的类

时间:2015-04-02 10:35:21

标签: ruby-on-rails ruby inheritance class-constants

我有一个具有此文件夹结构的应用程序:

# /app/controllers/first_controller.
class FirstController
  def method
    'External'
  end
end

# /app/controllers/second_controller.rb
class SecondController
  def method
    'External'
  end
end

# /app/controllers/foo/first_controller.rb
module Foo
  class FirstController < ::FirstController
    def method
      'Internal'
    end
  end
end

我的行为是:

Foo::FirstController#method => "Internal"

Foo::SecondController#method => "External"

因此,如果控制器未在模块Foo中定义,则应该实例化外部cass

我尝试创建文件foo.rb

# /app/controllers/foo.rb
module Foo
  def self.const_missing(name)
    "::#{name}".constantize
  end
end

但是使用它会使rails忽略/app/controllers/foo/*.rb下定义的所有类(根本不需要它们)。

我怎样才能获得这个?

1 个答案:

答案 0 :(得分:1)

如果类存在于Foo命名空间中,只需让Rails完成工作。它也使用const_missing来解析类名:

module Foo
  def self.const_missing(name)
    if File.exists?("app/controllers/foo/#{name.to_s.underscore}.rb")
      super
    else
      "::#{name}".constantize
    end
  end
end

输出:

Foo::FirstController.new.method
# => "Internal" 
Foo::SecondController.new.method
# => "External"