在通用基础路线之上构建路线? [英] Build routes on top of a common base route?
问题描述
我有一个共同的基本路径;说: get / base
我需要执行基本身份验证并为该路径下的所有子调用工作。说:获取/ base / foo
和获取/ base / bar
。
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
.
查看 http:// www。 sinatrarb.com/intro.html#Helpers 建议我应该能够通过使用帮助器来做到这一点。我正在查看 pass
助手,并在触发文档中的新路线的情况下使用了 call
。但是,我读到的另一个建议是使用正则表达式IE %r {/ base /?:( path)?}
使用动态路由。那么呢?
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 /命名空间
require 'sinatra/namespace'
class App < Sinatra::Base
register Sinatra::Namespace
namespace "/base" do
helpers do # this helper is now namespaced too
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
命名空间条件
Namespace with a condition
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 and a before过滤器
Helpers and a before filter
helpers do
authenticate!
# funky auth stuff
# but no need for `pass`
end
end
before '/base/*' do
authenticate!
end
映射的应用程序
mapped Apps
class MyBase < Sinatra::Base
helpers do
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
#…
我不确定是否需要使用case语句来干燥路由。如果每个路线的功能有所不同,那么我会分别将它们写清楚,因为它更加清晰,并且您正在复制Sinatra在匹配路线中所做的工作。
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.
这篇关于在通用基础路线之上构建路线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!