5

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

路线.rb:

mount MySinatraApp => "/streaming"

西纳特拉应用程序:

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

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

4

3 回答 3

2

嗯,我换了

mount MySinatraApp => "/streaming"

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

过滤器开始按预期说话。尽管如此,我不清楚为什么会这样:根据这篇文章, mount 应该只调用 match with :anchor => false,所以路由应该是相同的。但行为不同。

于 2013-02-06T09:33:51.817 回答
1

我也很惊讶地看到这种情况发生,但我想它告诉我们这filters是普遍的。既然是这样,您可以尝试使用Sinatra::Namespacesinatra -contrib gem,例如

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”(肯定有解决方法)但至少它可能会解决您遇到的问题。


更新

我测试了下面的代码,过滤器只针对他们自己的应用程序的 url 运行。似乎此代码也不需要命名空间部分。我注意到你已经指定了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 中运行的,即使命名空间的文档说它不应该发生。我一定在那里做错了什么。

于 2013-01-24T02:12:11.123 回答
0
['/streaming', '/otherlink', '/whatever'].each do |path|
  before path do
    puts 'hello from sinatra!'
  end
end

编辑:

如果您真的想保留您的结构,您还可以执行以下操作(但我的第一个答案绝对是更好的解决方案):

before do
  if request.path.start_with? '/streaming'
    puts 'hello from sinatra!'
  end
end
于 2013-01-23T19:32:07.590 回答