2

我在 Rails 应用程序中看到类似以下内容:

Application.routes.draw do
    root :to => "accounts#index"
end

我在这里被告知,如果“/”是所要求的路径,这将定义 Rails 路由到的位置。但是,在 rails 代码中定义的这个“根”函数到底在哪里?我不明白要让这个技巧发挥作用涉及哪些范围界定问题。

我可以看到一个块正在传递给draw函数。所以我假设draw函数调用yield来执行传递的块。但我仍然不确定为什么该root函数会神奇地在传递的块的范围内。

4

2 回答 2

5

root定义在 上ActionDispatch::Routing::Mapper::Base,包含在 中ActionDispatch::Routing::Mapper

幕后发生的事情比乍看之下要多一些。

如果我们看一下 的定义draw,我们就会明白为什么:

# action_dispatch/routing/route_set.rb
def draw(&block)
  # ...
  eval_block(block)
  # ...
end

该块被转换为一个 proc (with &) 并传递给eval_block它被定义得更远一点:

def eval_block(block)
  # ...
  mapper = Mapper.new(self)
  # ...
  mapper.instance_exec(&block)
end

因此,事实证明,yield根本没有使用。我们传递给的块Application.routes.draw只是在ActionDispatch::Routing::Mapper.

如果我们添加puts self到我们的config/routes.rb,我们可以看到这个:

Application.routes.draw do
  puts self
end

当我们运行时,rake routes我们会得到类似于以下的内容:

#<ActionDispatch::Routing::Mapper:0x007feadf52cbd8>
# ...

如需进一步阅读,请参阅:

http://ruby-doc.org/core-1.8.7/Object.html#method-i-instance_exec https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/routing/route_set .rb#LC296 https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/routing/mapper.rb#LC336 http://www.amazon.com/Metaprogramming-Ruby-Program-Like -优点/dp/1934356476

于 2013-02-05T02:05:01.567 回答
1

https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/routing/mapper.rb

def root(options = {})
  options = { :to => options } if options.is_a?(String)
  match '/', { :as => :root, :via => :get }.merge!(options)
end

https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/routing.rb

module Routing
  autoload :Mapper, 'action_dispatch/routing/mapper'
于 2013-02-04T22:47:29.677 回答