1

我所知

 MyApp::Application < Rails::Application 

 Rails::Application < Engine
   def config #:nodoc:
     @config ||= Application::Configuration.new(find_root_with_flag("config.ru", Dir.pwd))
   end
 end

并且config方法是Application类的实例方法但是为什么我可以使用

  My::Application < Rails::Application
    config.encoding = "utf-8"
    #...
  end

config 方法不是 My::Application 的实例方法吗?我已经看到 railscast Rails Initialization Walkthrough有一些关于:

module Rails
  class Railtie
    module Configurable
      extend ActiveSupport::Concern
      module ClassMethods
        def method_missing(*args, &block)
          instance.send(*args, &block)
        end
      end
    end
  end
end

它覆盖了 method_missing,以便在这个类上调用的每个没有明确定义的类方法都被传递给实例。这就像单例一样,在类上调用的任何方法都将充当实例方法。但是在 Rails4 源代码中,我找不到使用 Module Configurable 的位置。

和同样的问题

class Engine < Railtie
  def routes
    @routes ||= ActionDispatch::Routing::RouteSet.new
    @routes.append(&Proc.new) if block_given?
    @routes
  end
end

可以说,routes 方法也是 Engine 的一个实例方法。但是在 MyApp 的 routes.rb 中我们定义的路由是

MyApp::Application.routes.draw do 
  #...
end

再次将 routes 方法用作类方法,为什么?我试试这个:

MyApp::Application.methods.grep(/routes/)  #=> []

MyApp::Application.singleton_methods.grep(/routes/)  #=> []

MyApp::Application.instance_methods.grep(/routes/)  #=> [:routes]

那么魔法发生在哪里呢?

4

0 回答 0