Calling Sinatra from within Sinatra
I was able to hack something up by making a quick and dirty rack request and calling the Sinatra (a rack app) application directly. It's not pretty, but it works. Note that it would probably be better to extract the code that generates this resource into a helper method instead of doing something like this. But it is possible, and there might be better, cleaner ways of doing it than this.
#!/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
If you want to know more about what's going on behind the scenes, I've written a few articles on the basics of Rack you can read. There is What is Rack? and Using Rack.
How to call a Sinatra route from IRB console
I discovered the Tux gem. It allows calling of get and post routes from within IRB console.
Sinatra route function call & helpers
You've overcomplicated things. See the Helpers section of docs.
Put this in your Application controller:
helpers do
def render
@page = Page.find_by permalink: request.path_info
if @page then
else
halt 400
end
end
end
Now your route will be:
get '/*' do
render
end
Still, too complicated if you ask me, no need to ape Rails. Why not keep it simple?
require 'sinatra'
get '/*' do
@page = Page.find_by permalink: request.path_info
if @page then
haml :something
else
halt 400
end
end
That's it, that's the whole Sinatra app without recourse to inheritance and a structure that isn't required. Unless you're adding pages dynamically after the app is deployed then I'd also define the routes more explicitly.
Don't use globals. I actually can't remember the last time I saw one used, there are so many better alternatives. If you find you need one it's a clue you're going down the wrong path.
Calling a Sinatra app instance method from TestCase
Sinatra aliases the new
method to new!
before redefining it, so the simplest solution is to use that instead:
def app
MyApp.new!
end
Of course I only noticed that after I’d come up with the following, which I’ll leave in as it could be useful/informative.
A possible way to get round Sinatra redefining the new
method and returning a complete Rack app a get hold of an instance your actual base class is to do what the “real” new
method does yourself:
def app
a = MyApp.allocate
a.send :initialize
a
end
This is a bit of a hack, but it might be useful for testing.
Another technique would be to “walk” the middleware stack until you got to your class. The following is a little fragile, as it depends on all the middleware involved to use the name @app
to refer to the next app in the stack, but this is fairly common.
def app
a = MyApp.new
while a.class != MyApp
a = a.instance_variable_get(:@app)
end
a
end
That won’t work on the yet to be released Sinatra 1.4 though (at least not on the current master, which is commit 41840746e866e8e8e9a0eaafc53d8b9fe6615b12), as new
now returns a Wrapper
class and the loop never ends. In this case you can grab the base class directly from the @instance
variable:
def app
MyApp.new.instance_variable_get :@instance
end
(note this last technique may well change before the final 1.4 release).
Call erb within an external class in sinatra
You can achieve this by creating a helpers module for your methods:
# module instead of a class
module MyHelpersModule
# no need for 'self'
def some_function(request)
erb :some_template
end
end
Then in your main app file call helpers MyHelpersModule
. This will make all the methods in MyHelpersModule
available in your application and also, since they are executed in the same context, the existing Sinatra methods (like erb
) will be available to your helpers.
require 'sinatra'
require './my_helpers_module'
helpers MyHelpersModule
get '/' do
some_function(request)
end
Related Topics
Rails Form Validation Conditional Bypass
How to Use Gems Not in a Gemfile When Working with Bundler
Selenium Scroll Element into (Center Of) View
How to Find Each Instance of a Class in Ruby
How to Validate Xhtml with Nokogiri
Why Does Ruby's String#To_I Sometimes Return 0 When the String Contains a Number
What's the Best/Easiest Gui Library for Ruby
Keep Getting Oauth::Unauthorized Error When Using Oauth and Twitter Ruby Gems
How to Ftp in Ruby Without First Saving the Text File
How to Skip Has_Secure_Password Validations
Why Is Enumerable#Each_With_Object Deprecated
How to Read a File from Bottom to Top in Ruby
Detect If Application Was Started as Http Server or Not (Rake Task, Rconsole etc)
Rvm Does Not Install Ruby 1.9.2 on Snow Leopard: 'Error Running 'Make '