我所知
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]
那么魔法发生在哪里呢?