ruby - 如何在 Rack::Builder::map 中使用 Lotus 路由器

标签 ruby hanami hanami-router

有没有办法一起使用 map 和(莲花)路由器命名空间?下面是一个示例 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

最佳答案

您的问题是由于方法调用中 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

换句话说,该 block 被传递给 run,而不是像您预期的那样传递给 Lotus::Router.new,而 run 只是忽略 block 。

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

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

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

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

关于ruby - 如何在 Rack::Builder::map 中使用 Lotus 路由器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22367474/

相关文章:

c++ - 如何使用 va_list 解决错误?

Ruby ssh 错误 Net::SSH::AuthenticationFailed 而它与 PHP 一起使用

ruby - 花见 : access current page URL from views or templates

ruby - Sidekiq 在 Hanami 应用程序上找不到 worker 类别

ruby - Hanami 中的 2 个现场验证 + 干式验证

Hanami 路线助手在模板中不起作用

ruby-on-rails - 学习 Ruby on Rails。网上商店/在线购物车网络应用程序

ruby-on-rails - 向我解释 config 在 Rails 中是如何工作的