Ruby 修改机架应用程序

Ruby 修改机架应用程序,ruby,rubygems,subdomain,rack,middleware,Ruby,Rubygems,Subdomain,Rack,Middleware,对于我的一个ruby应用程序,我需要服务器根据子域路由请求。使用其他gem有很多方法可以做到这一点,但我决定制作自己的“中间件”。这段代码根据请求的目的地运行应用程序 config.ru require './subdomain' require './www' run Rack::Subdomain.new([ { :subdomain => "test", :application => Sinatra::Application } ]); requ

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

config.ru

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

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

run Rack::Subdomain.new do |x|
  x.map 'test' do
    Sinatra::Application
  end
end
subdomain.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
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
我的问题是,如何修改此工作代码,使其工作方式完全相同,但由如下代码调用:

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([
  {
    :subdomain => "test", 
    :application => Sinatra::Application
  }
]);
require './subdomain'
require './www'

run Rack::Subdomain.new do |x|
  x.map 'test' do
    Sinatra::Application
  end
end
subdomain.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
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
模块机架
类子域
def初始化(路由=零)
@路线=路线
屈服于自己
结束
def映射(子域)
@routes您调用上述“工作代码”,但它似乎根本没有检测子域,而是将其连接到文本“test”。无论如何,您可以通过创建一个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
模块机架
类子域
def初始化(路由=[])
@路线=路线
如果给定块,则屈服于自身?
结束
def映射(子域)

@routes Hi感谢您在测试上述代码时给出的答案2013-03-10T19:32:38+00:00应用程序[web.1]:/app/subdomain.rb:3:“初始化”中的参数数目错误(0用于2013-03-10T19:32:36+00:00 heroku[slugc]:Slug编译完成2013-03-10T19:32:38+00:00应用程序[web.1]:/app/subdomain.rb:3:in
initialize]:参数数量错误(0代表1)(ArgumentError)2013-03-10T19:32:38+00:00应用程序[web.1]:来自config.ru:4:in
块中的'2013-03-10T19:32:38+00:00应用程序[web.1]:来自/app/vendor/bundle/ruby/1I我试图切换到| x |,但这并没有解决问题。我对此表示感谢,但现在我得到了这个错误:“2013-03-11T22:22:43+00:00 heroku[web.1]:使用命令
bundle exec精简启动-R config.ru-e$RACK_ENV-p 59512启动进程:/app/subdomain.rb:5:in`initialize':在没有看到您的/app/subdomain.rb的情况下没有给出任何块(yield)(LocalJumpError)”。很难说错误是什么。试着发布一个要点。您是否有一个块附加到
Rack::subdomain.new
?每个
x.map
节如何?您可能使用过
x.map'foo'{…}
而不是
x.map'foo'do…end