Sinatra’s Little Helpers

Share this article

Key Takeaways

  • Sinatra, a web application library in Ruby, provides a range of helper methods that simplify common web development tasks, including generating URLs, redirecting to other pages, and stopping a request in its tracks.
  • The ‘enable’ and ‘disable’ methods can be used for app-wide settings, with a handy helper method created for any boolean settings to easily check if they are true.
  • The ‘halt’ and ‘pass’ methods control the HTTP request cycle, with ‘halt’ stopping a request immediately and ‘pass’ passing the method down the chain to the next matching route.
  • Other useful methods include ‘Request.xhr?’ to check if a request was made using Ajax, ‘redirect back’ to return the user to the page they came from, and ‘splat’ to create named parameters in the route definition.
While I’ve been working on my little book about Sinatra, I’ve picked up a few helper methods that Sinatra provides. Some of these I already knew about, but hadn’t really used much and some I didn’t even know about. Sinatra has a bucket load of helper methods that contribute to making it such a nice experience for the developer. I’ve collected a few of them here for with some examples. Some of these may be new to you, or like me you may have heard of them before and just be grateful of the reminder.

Enable and Disable

You can make app-wide settings (or module-wide settings if you’re using a modular-style app) easily in Sinatra using the set method:
set :title, "My Amazing Blog"
set :comments, true
set :tags ,false
But if the setting is a boolean value, you can use the enable and disable methods instead. This not only uses less code, but also reads much better.
enable :comments
disable :tags
You can also use this for built-in settings:
enable :logging
enable :sessions
Sinatra also creates a handy helper method for any boolean settings to help check if they are true. Basically it’s the name of the setting followed by a question mark. This allows us to write easy to read and follow code that checks if a settings is true or not:
if settings.comments? then display @page.comments
redirect to('/') unless settings.?

Which Environment

The following methods make checking which environment is being used a cinch:
production?
development?
test?
This means you can write some nice looking conditional statements, such as:
require 'sinatra/reloader' if development?
run! unless test?

Halt and Pass

These two methods can be used in route handlers to control the HTTP request cycle. halt will stop a request in its tracks, with an optional message or view and status code. It can be used if a process is taking too long or a critical error has occurred. Other uses include if somebody is trying to view an unauthorized page.
get '/important-process' do
  halt 500 if something_bad_happened?
  "Everything is okay"
end

get '/secret-page' do
  halt 401,"This page is secret" unless logged_in?
  "For your eyes only"
end
The pass
method can be used to pass the method down the chain to the next matching route. In the example below we have a standard route that says hello, but if the name entered in the URL is ‘daz’ then I want to pass the request on to the more specific route handler that will display a much nicer message:
get '/:name' do
  pass if params[:name] == 'daz'
  "Hello, #{params[:name]}"
end

get '/daz' do
  "Well hello there DAZ!"
end
Of course in the example above it would just be easier to change the order of the route handlers, but there may be instances where you don’t have control over this.

Request.xhr?

If you want to know if a request was made using Ajax, then the Request.xhr? helper method comes in handy. This will return true if the XML HTTP Request object was used. I often use this to do redirect if Ajax wasn’t used, like in the example below which is used to delete a page. If Ajax is used then the page will just be deleted and we want the user to stay on the ‘/pages’ page, but if Ajax isn’t used then we will have to manually redirect them back to the ‘/pages’ page:
delete '/page/:id' do
  page = Page.get params[:id]
  page.destroy
  redirect to('/pages') unless request.xhr?
end

Redirecting Back

If you have a route handler that basically performs an operation and then sends the user back to the page they came from then the back helper method is just what you need to make you code read nicely. Used along with the redirect helper method this will simply send the user back to the page from whence they came. For example, the delete page route handler that we saw :
delete '/page/:id' do
  page = Page.get params[:id]
  page.destroy
  redirect back unless request.xhr?
end

Splats

In Sinatra you can can create named parameters by placing a colon in front of them in the route definition, like so:
get '/hello/:name' do

end
This will store whatever is entered in the place of :name in params[:name]. We can be more general than this and use * in the route. This allows any amount of text to be entered. It is accessible through params[:splat], for example:
get '/goodbye/*/hello/*' do

end
The URL ‘/goodbye/shoes/hello/flipflops’ would give params[:splat] = [“shoes”,”flipflops”] You can also use it with block parameters if you don’t like using the the word splat. This also makes your code more readable and self-explanatory:
get '/*.*' do |path,ext|

end
In the example above, the route ‘/application.js’ would result in variables path = 'application' and ext = 'js', which could then be used inside the route handler block. You can also use the splat to grab urls of indeterminate length:
get '/blog/ *' do |path|
  @page = Page.first(:slug => path.first)
end
In the example above the route entered after ‘/blog’ can be accessed using path.first. For example, a route such as ‘/blog/all/about/sinatra’, would result in path.first = '/all/about/sinatra'. This can be useful when dealing with things like pretty URLs.

Cache Control

You can control how pages are cached by setting the headers directly, but there are also the cache_control
, expires, last_modified and etag helpers that make cache control a piece of cake. For example, if you had a page model in a simple CMS system, you could use the following:
get '/page/:id'
  @page = Page.get(params[:id])
  last_modified @page.updated_at
  etag @page.content
  markdown @page.content
end
For quick and dirty cache control for all pages, you can use the application start time to set the last_modified and etag headers globally. While the application start time may not strictly be the actual time all the files were last modified, we can usually assume that if the application has been restarted then something must have changed. In this case, It’s worth flushing the cache out and reloading the pages anyway. To set the application start time, place the following code in a configure block:
configure do
  set :start_time, Time.now
end
This works because the code in a configure block is only run once at start up. Now we can use this setting to set the last_modified and etag headers. The settings is a Time object, so it is fine to use for the last_modified header, but it will need to be converted to a string in order to be used for the etag header. If the following code is placed in a before block then it will be applied to all pages:
before do
  last_modified settings.start_time
  etag settings.start_time.to_s
  cache_control
end
Now you should get a 304 status code instead of 200 if you refresh a page that hasn’t been modified. This is a useful way of reducing the load on the server in an application by avoiding any needless round trips to the server.

That’s All Folks

What all these methods do is make the code much easier to read and maintain. If you look at some of the code samples above, they read almost like a full sentence of English and make it very obvious what is being done. These methods also let you perform neat tricks and use less code. This is the beauty of using Sinatra – the code is short and sweet. Most of these helper methods are covered in more detail in the book. Have you used any of these and found them useful, have I missed any? Leave your answers in the comments below.

Frequently Asked Questions (FAQs) about Sinatra’s Little Helpers

What are Sinatra’s Little Helpers and how do they work?

Sinatra’s Little Helpers are a set of helper methods provided by the Sinatra web application library in Ruby. They are designed to simplify common tasks in web development, such as generating URLs, escaping HTML, or redirecting to another page. These helpers are automatically included in every Sinatra application and can be used directly in your routes and views. They are designed to be intuitive and easy to use, making your code cleaner and more readable.

How can I use the ‘url’ helper in Sinatra?

The ‘url’ helper is used to generate absolute URLs in your Sinatra application. This is particularly useful when you’re creating links in your views. Here’s an example of how you can use it:

get '/example' do
"<a href=\"#{url('/other')}\">Other page</a>"
end

In this example, the ‘url’ helper generates the absolute URL for the ‘/other’ route.

How can I use the ‘redirect’ helper in Sinatra?

The ‘redirect’ helper is used to redirect the user to a different route or URL. This is often used in form submissions, where you want to redirect the user after they’ve submitted the form. Here’s an example:

post '/form' do
# Process the form data...
redirect '/thanks'
end

In this example, after the form data is processed, the user is redirected to the ‘/thanks’ route.

What is the ‘halt’ helper and how can I use it?

The ‘halt’ helper is used to immediately stop a request and return a specific response. This is useful when you want to return an error or stop processing due to certain conditions. Here’s an example:

get '/admin' do
halt 403 unless admin?
# Continue processing...
end

In this example, if the ‘admin?’ method returns false, the request is immediately halted and a 403 Forbidden response is returned.

How can I use the ‘erb’ helper to render views in Sinatra?

The ‘erb’ helper is used to render views using the ERB (Embedded Ruby) template system. You can use it in your routes to render a view and return it as the response. Here’s an example:

get '/hello' do
@name = 'World'
erb :hello
end

In this example, the ‘erb’ helper renders the ‘hello.erb’ view, passing in the ‘@name’ instance variable.

What is the ‘params’ helper in Sinatra?

The ‘params’ helper is a hash that includes both the query string parameters and the POST parameters. It allows you to access the parameters sent with the request. For example:

get '/hello' do
"Hello, #{params[:name]}!"
end

In this example, the ‘params’ helper is used to access the ‘name’ parameter from the query string.

How can I use the ‘session’ helper in Sinatra?

The ‘session’ helper is a hash that you can use to store data between requests. This is often used for things like user authentication. Here’s an example:

enable :sessions

get '/login' do
session[:user_id] = User.authenticate(params[:username], params[:password])
redirect '/dashboard'
end

In this example, the ‘session’ helper is used to store the authenticated user’s ID.

What is the ‘content_type’ helper in Sinatra?

The ‘content_type’ helper is used to set the Content-Type header of the response. This tells the client what type of data you’re sending back. For example:

get '/data.json' do
content_type :json
{ message: 'Hello, World!' }.to_json
end

In this example, the ‘content_type’ helper is used to set the Content-Type to ‘application/json’.

How can I use the ‘request’ helper in Sinatra?

The ‘request’ helper is an object that encapsulates the HTTP request made by the client. It provides methods to access the request headers, the request method, the request URL, and more. For example:

get '/example' do
"You're using #{request.user_agent}"
end

In this example, the ‘request’ helper is used to access the User-Agent header of the request.

What is the ‘settings’ helper in Sinatra?

The ‘settings’ helper is an object that provides access to the configuration settings of your Sinatra application. You can use it to access the settings defined with the ‘set’ method. For example:

set :title, 'My App'

get '/example' do
"Welcome to #{settings.title}"
end

In this example, the ‘settings’ helper is used to access the ‘title’ setting.

Darren JonesDarren Jones
View Author

Darren loves building web apps and coding in JavaScript, Haskell and Ruby. He is the author of Learn to Code using JavaScript, JavaScript: Novice to Ninja and Jump Start Sinatra.He is also the creator of Nanny State, a tiny alternative to React. He can be found on Twitter @daz4126.

Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week