如何使用带有Rack :: Builder :: map的lotus路由器

时间:2014-03-13 01:42:00

标签: ruby hanami hanami-router

有没有办法一起使用map和(lotus)路由器命名空间?下面是一个示例config.ru我正在尝试作为演示运行。

require 'bundler'
Bundler.require

module Demo

  class Application

    def initialize
      @app = Rack::Builder.new do
        map '/this_works' do
          run  Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["this_works"]]}
        end
        map '/api' do
          run Lotus::Router.new do
            get '/api/', to: ->(env) { [200, {}, ['Welcome to Lotus::Router!']] }
            get '/*', to: ->(env) { [200, {}, ["This is catch all: #{ env['router.params'].inspect }!"]] }
          end
        end
      end
    end

    def call(env)
      @app.call(env)
    end
  end  
end

run Demo::Application.new

1 个答案:

答案 0 :(得分:7)

您的问题是由于do..end在方法调用中的优先级。在您的代码中

部分
run Lotus::Router.new do
  get '/api/', to: ->(env) { [200, {}, ['Welcome to Lotus::Router!']] }
  get '/*', to: ->(env) { [200, {}, ["This is catch all: #{ env['router.params'].inspect }!"]] }
end

被Ruby解析为

run(Lotus::Router.new) do
  get '/api/', to: ->(env) { [200, {}, ['Welcome to Lotus::Router!']] }
  get '/*', to: ->(env) { [200, {}, ["This is catch all: #{ env['router.params'].inspect }!"]] }
end

换句话说,该块会传递到run,而不会传递给Lotus::Router.new,而run只会忽略该块。

要修复它,您需要确保该块与路由器的构造函数相关联,而不是调用run。有几种方法可以做到这一点。您可以使用{...}而不是do...end,因为它具有更高的优先级:

run Lotus::Router.new {
  #...
}

另一种方法是将路由器分配给局部变量,并将其用作run的参数:

router = Lotus::Router.new do
  #...
end
run router