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 とのみ呼び出す:anchor => false必要があるため、ルートは同じである必要があります。しかし、振る舞いは異なります。

于 2013-02-06T09:33:51.817 に答える
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」(確実に回避策があります) ですが、少なくとも問題は解決する可能性があります。


アップデート

以下のコードをテストしたところ、フィルターは独自のアプリの 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

Namespace のドキュメントには発生しないと書かれていますが、両方のフィルターが 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 に答える