I've got a Rails app and a Sinatra app inside it:
routes.rb:
mount MySinatraApp => "/streaming"
sinatra app:
class MySinatraApp< Sinatra::Base
...
before do
puts 'hello from sinatra!'
end
...
end
I expectedly want the filter to run only on the requests starting with /streaming...
, but, what surprises me, the filter runs on every request to the whole Rails app. What can I do with such a behaviour?
I can add a regexp filter after before
, but I don't think it's a good style.
Well, I replaced
mount MySinatraApp => "/streaming"
with
match "/streaming" => SinatraQuoridor, :anchor => false
and filters started to word as expected.
Allthough, I do not understand clearly why it is happening: according to this article, mount should just call match with :anchor => false
, so the routes should be the same. But the behaviour differs.
I'm surprised to see this happen too, but as it has I suppose it tells us that the filters
are universal. Since they are, you might try using Sinatra::Namespace
from the sinatra-contrib gem, e.g.
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
I'm not entirely sure this will work, and it may mean that routes must include the trailing slash, so "/streaming/" not "/streaming" (there's surely a workaround) but at least it might solve the problem you have.
I tested the code below and the filters only run for their own app's urls. It appears that even the namespace part isn't needed with this code either. I noticed you've specified the mount
method, but that isn't part of Rack - which library are you using for that? rack-mount?
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
The output:
[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
Notice how both filters get run in StreamingApp even though the docs for Namespace say that it shouldn't happen. I must've done something wrong there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With