我有一个.ru文件,可以设置没有问题的映射(下面的'注册'映射)。
但是我希望服务能够通过点击URL来注册自己,所以我希望能够在其他映射中动态添加新的映射。
以下代码不可以工作。我做错了什么,这可能吗?
谢谢!
map '/register' do
run Proc.new { |env|
# inside of register i want to add another mapping.
# obviously 'bar' would be a value read out of env
map '/bar' do
run Proc.new{ |env| ['200', { 'Content-Type' => 'text/html' },'bar' }
end
[ '200', {'Content-Type' => 'text/html'}, "registered"]
}
end
答案 0 :(得分:1)
我认为没有办法使用map
在事后添加路线。另一种方法是使用Rack::URLMap来定义您的应用。您需要维护自己的已注册路由列表(作为哈希),并在每次向哈希添加新路由时调用Rack::URLMap#remap
:
url_map = Rack::URLMap.new
routes = {
"/register" => lambda do |env|
routes["/bar"] = lambda do |env|
[ "200", {"Content-Type" => "text/plain"}, ["bar"] ]
end
url_map.remap(routes)
[ "200", {"Content-Type" => "text/plain"}, ["registered"] ]
end
}
url_map.remap(routes)
run url_map
请注意,您可以只使用哈希,但URLMap提供了一些很好的便利,包括404处理。它实际上是一个非常好的小班,worth reading如果你还有五分钟的时间。
如果你如此倾向,你可以把它变成一个整洁的小班:
class Application
def initialize
@routes = {}
@url_map = Rack::URLMap.new
register_route "/register" do |env|
# When "/register" is requested, register the new route "/bar"
register_route "/bar" do |env|
[ 200, {"Content-Type" => "text/plain"}, ["bar"] ]
end
[ 200, {"Content-Type" => "text/plain"}, ["registered"] ]
end
end
def call(env)
@url_map.call(env)
end
private
def register_route(path, &block)
@routes[path] = block
@url_map.remap(@routes)
end
end
run Application.new
答案 1 :(得分:0)
根据https://rack.github.io/,"要使用Rack,请提供" app":响应调用方法的对象,将环境哈希作为参数,并返回包含三个元素的数组:
each
" 您的第三个元素不会回复each
。也许将它包装在一个数组中?