I have a common base path; say: get /base
where I need to have basic auth performed and working for all sub calls under that path. Say: get /base/foo
and get /base/bar
.
Looking at http://www.sinatrarb.com/intro.html#Helpers suggests I should be able to do this with the use of helpers. I was looking at the pass
helper and use of call
under triggering a new route in the documentation. But, another suggestion I read was using dynamic routing using regexes IE %r{/base/?:(path)?}
or some such. So what about:
def '/base'
# do some funky basic auth stuff here
# to work with all request to this common
# base path?
pass
end
def %r{/base/?(path)?} do |path|
case path
when 'foo'
# do something.
when 'bar'
# do something else.
end
# some kind of redirection or template rendering here:
erb :template
end
Has anyone dealt with this kind of thing before? I'm trying to keep it DRY. Of course, I'm not sure the given example would be the best in preserving params.
There are a few ways you could do this (these aren't in any order, they're all good):
http://rubydoc.info/gems/sinatra-contrib/1.3.2/Sinatra/Namespace
require 'sinatra/namespace'
class App < Sinatra::Base
register Sinatra::Namespace
namespace "/base" do
helpers do # this helper is now namespaced too
def authenticate!
# funky auth stuff
# but no need for `pass`
end
end
before do
authenticate!
end
get "/anything" do
end
get "/you" do
end
get "/like/here" do
end
end
require 'sinatra/namespace'
class App < Sinatra::Base
register Sinatra::Namespace
set(:auth) do |*roles| # <- notice the splat here
condition do
unless logged_in? && roles.any? {|role| current_user.in_role? role }
redirect "/login/", 303
end
end
end
namespace "/base", :auth => [:user] do
# routes…
end
namespace "/admin", :auth => [:admin] do
# routes…
end
helpers do
def authenticate!
# funky auth stuff
# but no need for `pass`
end
end
before '/base/*' do
authenticate!
end
class MyBase < Sinatra::Base
helpers do
def authenticate!
# funky auth stuff
# but no need for `pass`
end
end
before do
authenticate!
end
get "/" do
end
get "/another" do
end
end
# in rackup file
map "/" do
run App1
end
map "/base" do
# every route in MyBase will now be accessed by prepending "/base"
# e.g. "/base/" and "/base/another"
run MyBase
end
#…
I'm not sure about the need to DRY up routes using a case statement. If the routes each do something different then I'd just write them out separately as it's a lot clearer and you're duplicating the work Sinatra does in matching routes.
How about using before
filters:
before '/base/?*' do
@foo = 'bar'
end
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