【问题标题】:Trouble on routing Racks路由机架的问题
【发布时间】:2011-07-03 07:51:43
【问题描述】:

我正在使用 Ruby on Rails 3,我想将一些 URL 路由到一些 Rack 中间件。也就是说,如果用户尝试浏览http://<my_site_name>.com/api/user/1,系统应该考虑在 Rack 文件之前运行,然后继续请求。

我有一个 Rack::Api:User 位于 lib/rack/api/user 文件夹中。

从 RoR 官方文档中我发现了这一点:

     Mount a Rack-based application to be used within the application.

       mount SomeRackApp, :at => "some_route"

     Alternatively:

       mount(SomeRackApp => "some_route")

     All mounted applications come with routing helpers to access them.
     These are named after the class specified, so for the above example
     the helper is either +some_rack_app_path+ or +some_rack_app_url+.
     To customize this helper's name, use the +:as+ option:

       mount(SomeRackApp => "some_route", :as => "exciting")

     This will generate the +exciting_path+ and +exciting_url+ helpers
     which can be used to navigate to this mounted app.

在我尝试过的 routers.rb 文件中

mount "Rack::Api::User", :at => "/api/user/1"
# => ArgumentError missing :action

scope "/api/user/1" do
  mount "Rack::Api::User"
end
# => NoMethodError undefined method `find' for "Rack::Api::User

我也试过了

match '/api/user/1' => Rack::Api::User
# => Routing Error No route matches "/api/user/1"

match '/api/user/1', :to => Rack::Api::User
# ArgumentError missing :controller

但没有人工作。


更新

我的 Rack 文件是这样的:

  module Api
    class User

      def initialize(app)
        @app = app
      end

      def call(env)
        if env["PATH_INFO"] =~ /^\/api\/user\/i
          ...
        else
          @app.call(env)
        end
      end
    end
 end

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 routing rack


    【解决方案1】:

    假设您在启动过程中的某个位置 require-ing 您的 Rack 应用程序,例如在初始化程序中(请记住,除非您编写代码,否则来自 lib 的文件不会自动加载!请参阅@ 987654321@),然后尝试在不带引号的情况下安装它。例如,而不是:

    mount "Rack::Api::User", :at => "/api/user/1"
    

    试试

    mount Rack::Api::User, :at => "/api/user/1"
    

    [更新]

    这是我对基本 Rails 应用程序所做更改的链接,该应用程序演示了自动加载和安装 Rack 应用程序:https://github.com/BinaryMuse/so_5100999/compare/master...rack

    [更新 2]

    啊,我明白你现在在说什么了。你想要一个中间件。我已经更新了上述 URL 中的代码,以将您的应用程序实现为中间件。 config/initializers/rack.rb 是加载和插入中间件的文件。希望这就是您想要的!

    【讨论】:

    • 你能举个真实的例子吗?如果我的机架文件在“/lib/api/user/”中,我必须如何以及在哪里“要求”它? P.S.:我编写了代码来加载 'application.rb' 文件中的 'lib' 路径('config.autoload_paths += %W(#{config.root}/lib)')。附言二:我更新了问题。 P.S.:我试过你的代码,但我得到了同样的错误。
    • 如果我没记错的话,如果你想自动加载Rack::Api::User,那么这个类应该定义在lib/rack/api/user.rb中。在任何情况下,您都可以通过在config/initializers/load_my_rack_app.rb 中创建文件来手动加载文件(config/initializers 中的任何内容都会自动加载)并输入代码require "lib/api/user/whatever.rb"
    • 但我得到一个“缺少:控制器”。这是'user.rb'文件中的 rack 语句吗?
    • @user502052:我已经更新了我的答案,提供了一些可能有帮助的工作代码的链接。
    • 你太棒了!然而,正如我所怀疑的那样,问题出在 rack 声明中:我使用了 'call' 而不是 'self.call' 以及 'def initialize(app) ...' (你在代码中的编写方式)一定不能在代码中。我唯一不明白的是:为什么使用'self.call'而不是常见的'initialize'/'call'方法?为什么是“SCRIPT_NAME”而不是“PATH_INFO”?
    猜你喜欢
    • 2015-06-18
    • 1970-01-01
    • 1970-01-01
    • 2019-11-03
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 2017-06-02
    • 2016-11-09
    相关资源
    最近更新 更多