Sinatra中与动词无关的匹配

时间:2011-12-07 11:13:01

标签: ruby sinatra

我们可以写

get '/foo' do
  ...
end

post '/foo' do
  ...
end

哪个好。但是我可以在一个路由中组合多个HTTP动词吗?

4 个答案:

答案 0 :(得分:33)

这可以通过作为sinatra-contrib的一部分的multi-route extension来实现:

require 'sinatra'
require "sinatra/multi_route"
route :get, :post, '/foo' do
  # "GET" or "POST"
  p request.env["REQUEST_METHOD"]
end

# Or for module-style applications
class MyApp < Sinatra::Base
  register Sinatra::MultiRoute
  route :get, :post, '/foo' do
    # ...
  end
end

但请注意,您可以通过以下方式自行完成此操作:

foo = lambda do
  # Your route here
end
get  '/foo', &foo
post '/foo', &foo

或者更优雅地作为元方法:

def self.get_or_post(url,&block)
  get(url,&block)
  post(url,&block)
end

get_or_post '/foo' do
  # ...
end

您可能也对this discussion on the feature感兴趣。

答案 1 :(得分:8)

FWIW,我只是手动完成,没有辅助方法或扩展名:

%i(get post).each do |method|
   send method, '/foo' do 
       ...
   end
 end

虽然如果你做得很多,那么将它抽象出来当然是有意义的。

答案 2 :(得分:4)

Phrogz有一个很好的答案,但如果lambdas或包括sinatra-contrib不适合你,那么这个元方法将达到与sinatra-contrib相同的结果:

# Provides a way to handle multiple HTTP verbs with a single block
#
# @example
#   route :get, :post, '/something' do
#       # Handle your route here
#   end
def self.route(*methods, path, &block)
    methods.each do |method|
        method.to_sym
        self.send method, path, &block
    end
end

如果您对能够向self发送任意方法有点谨慎,那么您可以通过在数组中设置允许方法的白名单来保护自己,然后检查符号在阵列。

# Provides a way to handle multiple HTTP verbs with a single block
#
# @example
#   route :get, :post, '/something' do
#       # Handle your route here
#   end
def self.route(*methods, path, &block)
    allowed_methods = [:get, :post, :delete, :patch, :put, :head, :options]
    methods.each do |method|
        method.to_sym
        self.send(method, path, &block) if allowed_methods.include? method
    end
end

答案 3 :(得分:0)

这是一个服务不可用的服务器,我设法获得单行:)

require 'sinatra';set port: ARGV[0]||80;%w.get post put patch options delete..map{|v|send(v,'*'){503}}

我实际上用它来测试面对503s的某些客户端代码的行为。