我们可以写
get '/foo' do
...
end
Run Code Online (Sandbox Code Playgroud)
和
post '/foo' do
...
end
Run Code Online (Sandbox Code Playgroud)
这很好.但是我可以在一个路由中组合多个HTTP动词吗?
Phr*_*ogz 33
这可以通过作为sinatra-contrib的一部分的multi-route
扩展来实现:
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
Run Code Online (Sandbox Code Playgroud)
但请注意,您可以在没有扩展名的情况下自行完成此操作:
foo = lambda do
# Your route here
end
get '/foo', &foo
post '/foo', &foo
Run Code Online (Sandbox Code Playgroud)
或者更优雅地作为元方法:
def self.get_or_post(url,&block)
get(url,&block)
post(url,&block)
end
get_or_post '/foo' do
# ...
end
Run Code Online (Sandbox Code Playgroud)
您可能也对此功能的讨论感兴趣.
FWIW,我只是手动完成,没有辅助方法或扩展:
%i(get post).each do |method|
send method, '/foo' do
...
end
end
Run Code Online (Sandbox Code Playgroud)
虽然如果你做了很多,当然有必要将它抽象出来.
Phrogz有一个很好的答案,但是如果lambda或包含sinatra-contrib都不适合您,则此meta方法将达到与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
Run Code Online (Sandbox Code Playgroud)
如果您对能够将任意方法发送到有所警惕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
Run Code Online (Sandbox Code Playgroud)