【问题标题】:Modify Rack App修改机架应用程序
【发布时间】:2013-03-10 17:06:44
【问题描述】:

对于我的一个 ruby​​ 应用程序,我需要服务器根据子域路由请求。有很多方法可以使用其他 gems 来做到这一点,但我决定制作自己的“中间件”。此代码根据请求的目的地运行应用程序。

config.ru

require './subdomain'
require './www'

run Rack::Subdomain.new([
  {
    :subdomain => "test", 
    :application => Sinatra::Application
  }
]);

子域.rb

module Rack
  class Subdomain
    def initialize(app)
      @app = app
    end

    def call(env)
      @app.each do |app|
        match = 'test'.match(app[:subdomain])
        if match
          return app[:application].call(env)
        end
      end
    end
  end
end

我的问题是我怎样才能修改这个工作代码以完全一样工作,但让它由看起来像这样的代码调用:

run Rack::Subdomain do
  map 'www' do
    Example::WWW
  end

  map 'api' do
    Example::API
  end
end

建议代码:

config.ru

require './subdomain'
require './www'

run Rack::Subdomain.new do |x|
  x.map 'test' do
    Sinatra::Application
  end
end

子域.rb

module Rack
  class Subdomain
    def initialize(routes = nil)
      @routes = routes
      yield self
    end

    def map(subdomain)
      @routes << { subdomain: subdomain, application: yield }
    end

    def call(env)
      @routes.each do |route|
        match = 'test'.match(route[:subdomain])
        if match
          return route[:application].call(env)
        end
      end
    end
  end
end

【问题讨论】:

    标签: ruby rubygems subdomain rack middleware


    【解决方案1】:

    您调用上述“工作代码”,但它似乎根本没有检测到子域,而是将其连接到文字“测试”。无论如何,您可以通过创建一个 map 方法来实现类似于您想要的模式,该方法将条目添加到您的子域-> 应用程序路由列表中。我已将您的 @app 重命名为 @routes,因为它是路由哈希,而不是应用程序引用。

    module Rack
      class Subdomain
        def initialize(routes = [])
          @routes = routes
          yield self if block_given?
        end
    
        def map(subdomain)
          @routes << { subdomain: subdomain, application: yield }
        end
    
        def call(env)
          @routes.each do |route|
            match = 'test'.match(route[:subdomain])
            if match
              return route[:application].call(env)
            end
          end
        end
      end
    end
    
    rsd = Rack::Subdomain.new do |x|
      x.map 'www' do
        Example::WWW
      end
    
      x.map 'api' do
        Example::API
      end
    end
    
    run rsd
    

    【讨论】:

    • 您好,感谢您在测试我得到的上述代码时的回答 2013-03-10T19:32:38+00:00 app[web.1]: /app/subdomain.rb:3:在“初始化”中:参数数量错误(0 表示
    • 2013-03-10T19:32:36+00:00 heroku[slugc]: Slug 编译完成 2013-03-10T19:32:38+00:00 app[web.1]: / app/subdomain.rb:3:in initialize': wrong number of arguments (0 for 1) (ArgumentError) 2013-03-10T19:32:38+00:00 app[web.1]: from config.ru:4:in block in
      ' 2013-03-10T19:32:38+00:00 app[web.1]: 来自 /app/vendor/bundle/ruby/1
    • 我试图切换 |x|但这并没有解决问题
    • 您好,谢谢您,但现在我收到此错误:“2013-03-11T22:22:43+00:00 heroku[web.1]: 使用命令启动进程bundle exec thin start -R config.ru -e $RACK_ENV -p 59512 2013-03 -11T22:22:46+00:00 app[web.1]: /app/subdomain.rb:5:in `initialize': no block given (yield) (LocalJumpError)"
    • 没有看到你的 /app/subdomain.rb 很难说错误是什么。尝试发布要点。 Rack::Subdomain.new 有附加块吗?每个x.map 节怎么样?您是否使用过x.map 'foo' {...} 而不是x.map 'foo' do...end
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-01
    • 2014-04-13
    • 1970-01-01
    • 2011-02-22
    • 2018-01-10
    • 2018-01-28
    相关资源
    最近更新 更多