在sinatra子应用程序中过滤之前

时间:2013-01-23 18:15:53

标签: ruby-on-rails ruby sinatra

我有一个Rails应用程序和一个Sinatra应用程序:

routes.rb中:

mount MySinatraApp => "/streaming"

sinatra app:

class MySinatraApp< Sinatra::Base
  ...
  before do
    puts 'hello from sinatra!'
  end
  ...
end

我希望过滤器只能在以/streaming...开头的请求上运行,但是,令我惊讶的是,过滤器会在对整个Rails应用程序的每个请求上运行。这样的行为怎么办? 我可以在before之后添加一个正则表达式过滤器,但我认为这不是一个好的风格。

2 个答案:

答案 0 :(得分:2)

好吧,我换了

mount MySinatraApp => "/streaming"

match "/streaming" => SinatraQuoridor, :anchor => false

并且过滤器开始按预期显示。 尽管如此,我并不清楚为什么会发生这种情况:根据this文章,mount应该只调用:anchor => false匹配,所以路由应该是相同的。但行为不同。

答案 1 :(得分:1)

我很惊讶地发现这种情况也会发生,但我认为它告诉我们filters是普遍存在的。既然如此,您可以尝试使用sinatra-contrib gem中的Sinatra::Namespace,例如

require 'sinatra/namespace'

class App < Sinatra::Base
  register Sinatra::Namespace

  namespace "/" do
    before do
      # this will only run within routes marked "/",
      # which should also be prepended with the mounted route, 
      # so "/streaming/"
    end

    get "/?" do
      # something here
    end

  end

我不完全确定这会起作用,这可能意味着路由必须包含尾部斜杠,所以“/ streaming /”不是“/ streaming”(肯定有一个解决方法)但至少可以解决问题你有。


更新

我测试了下面的代码,过滤器只针对自己应用的网址运行。这个代码似乎也不需要命名空间部分。我注意到你已经指定了mount方法,但这不是Rack的一部分 - 你使用哪个库?机架安装?

require 'rubygems'
require 'bundler'
Bundler.require

require 'sinatra'
require 'sinatra/namespace'

class StreamingApp < Sinatra::Base
  register Sinatra::Namespace

  namespace "/" do
    before do
      warn "Entering Streaming before filter"
    end

    get "/?" do
      "Hello from the StreamingApp"
    end
  end

  namespace "/something" do
    before do
      warn "Entering Streaming's /something before filter"
      warn "request.path_info = #{request.path_info}"
    end
    get "/?" do
      "Hello from StreamingApp something"
    end
  end
end

class OtherApp < Sinatra::Base
  before do
    warn "Entering OtherApp before filter"
    warn "request.path_info = #{request.path_info}"
  end
  get "/" do
    "Hello from the OtherApp"
  end
end

app = Rack::URLMap.new(
  "/streaming" => StreamingApp,
  "/" => OtherApp 
)

run app

输出:

[2013-01-25 14:19:52] INFO  WEBrick 1.3.1
[2013-01-25 14:19:52] INFO  ruby 1.9.3 (2012-04-20) [x86_64-darwin10.8.0]
[2013-01-25 14:19:52] INFO  WEBrick::HTTPServer#start: pid=78178 port=9292

Entering OtherApp before filter
request.path_info = /
127.0.0.1 - - [25/Jan/2013 14:20:03] "GET / HTTP/1.1" 200 23 0.0201

Entering Streaming before filter
request.path_info = 
127.0.0.1 - - [25/Jan/2013 14:20:11] "GET /streaming HTTP/1.1" 200 27 0.0044

Entering Streaming before filter
request.path_info = /
127.0.0.1 - - [25/Jan/2013 14:20:15] "GET /streaming/ HTTP/1.1" 200 27 0.0016

Entering Streaming before filter
request.path_info = /something
Entering Streaming's /something before filter
request.path_info = /something
127.0.0.1 - - [25/Jan/2013 14:20:21] "GET /streaming/something HTTP/1.1" 200 33 0.0018

注意两个过滤器如何在StreamingApp even though the docs for Namespace say that it shouldn't happen中运行。我一定做错了。