据我所知
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
配置方法不是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源代码中,我找不到模块可配置的使用位置。
同样的问题
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]
那么魔法在哪里发生了?