在Sinatra内召唤Sinatra

Ste*_*lat 15 ruby sinatra

我有一个基于Sinatra的REST服务应用程序,我想从其中一个路由中调用其中一个资源,从而有效地组合另一个资源.例如

get '/someresource' do
  otherresource = get '/otherresource'
  # do something with otherresource, return a new resource
end

get '/otherresource' do
  # etc.
end
Run Code Online (Sandbox Code Playgroud)

重定向不起作用,因为我需要对第二个资源进行一些处理并从中创建一个新的.显然我可以a)使用RestClient或其他一些客户端框架或者b)构造我的代码所以其他资源的所有逻辑都在一个方法中然后调用它,但是,如果我可以重新使用它感觉会更清洁使用他们的DSL从Sinatra内部使用我的资源.

Cli*_*ous 12

另一个选项(我知道这不是回答你的实际问题)是将你的公共代码(甚至是模板渲染)放在一个辅助方法中,例如:

helpers do
  def common_code( layout = true )
    @title = 'common'
    erb :common, :layout => layout
  end
end

get '/foo' do
  @subtitle = 'foo'
  common_code
end

get '/bar' do
  @subtitle = 'bar'
  common_code
end

get '/baz' do
  @subtitle = 'baz'
  @common_snippet = common_code( false )
  erb :large_page_with_common_snippet_injected
end
Run Code Online (Sandbox Code Playgroud)


Abo*_*uby 9

我能够通过快速而脏的机架请求并直接调用Sinatra(机架应用程序)应用程序来解决问题.它不漂亮,但它的工作原理.请注意,将生成此资源的代码提取到辅助方法而不是执行此类操作可能会更好.但这是可能的,并且可能有更好,更清洁的方法来做到这一点.

#!/usr/bin/env ruby
require 'rubygems'
require 'stringio'
require 'sinatra'

get '/someresource' do
  resource = self.call(
    'REQUEST_METHOD' => 'GET',
    'PATH_INFO' => '/otherresource',
    'rack.input' => StringIO.new
  )[2].join('')

  resource.upcase
end

get '/otherresource' do
  "test"
end
Run Code Online (Sandbox Code Playgroud)

如果你想了解更多关于幕后发生的事情,我已经写了几篇关于你可以阅读的Rack基础知识的文章.有什么是机架式?使用Rack.


Mar*_*cny 9

Sinatra的文档涵盖了这一点 - 基本上您使用底层rack接口的call方法:

http://www.sinatrarb.com/intro.html#Triggering%20Another%20Route

触发另一条路线

有时传球不是你想要的,而是你希望获得调用另一条路线的结果.只需使用call即可实现此目的:

get '/foo' do
  status, headers, body = call env.merge("PATH_INFO" => '/bar')
  [status, headers, body.map(&:upcase)]
end

get '/bar' do
  "bar"
end
Run Code Online (Sandbox Code Playgroud)