Tips For Starting a Sinatra App

Julian Rosenthal
3 min readJan 11, 2021

--

Three things to know before starting a project with Sinatra.

Background

Sinatra is a Ruby web application framework. It is more lightweight than other web frameworks, and is often used without the standard Model-View-Controller(MVC) pattern you would find in a Ruby on Rails application. However, if you were to create an MVC application with Sinatra, here are some tips that could help you along, as well as save you some headaches.

Use Corneal to Generate Sinatra Template

Corneal is a gem that generates a template for your MVC Sinatra app. It creates all the folders and files that you will need to get started, and populates your Gemfile. It is very simple to use, and instructions can be found by following the hyperlink above.

Use Bcrypt to Store Passwords

You should never store passwords directly into your database. In fact, it is downright irresponsible to do so. Users will often use the same password for multiple websites and applications. Failure to encrypt your users’ passwords could lead to hackers getting access to your user’s bank accounts, social media accounts, etc. if they are able to obtain a copy of your database. Therefore passwords should be stored salted and hashed. The bcrypt gem makes this task very easy for us. First, add the gem to your Gemfile. Then add a column to your users table (or wherever you need a secure password) with datatype of string, and name of password digest.

create_table :users do |t|
t.string :username
t.string :password_digest
end

Next, add the following line of code to the model associated with this table:

class User < ActiveRecord::Base
has_secure_password
end

And that’s it! You can check your work by creating a user in a tux or pry console, and you will see that the password was stored as gibberish. It is important to note that you should still create users with a password attribute, bcrypt will automatically change the attribute to password_digest

User.create(username: 'sample1', password: 'password1')#<User id: 8, username: "sample1", password_digest: "$2a$12$GP5mAsFKx5JBuvtd3gcjS.uaCeWZxfGdHE/a/VifQ1t...">

Finally, when a user logs in, you will need to use bcrypt’s authenticate method to check if the password that the user types in matches the salted and hashed password that is is stored in your database. If true, it will return the instance of the User class, otherwise, it will return false. Continuing from the example above:

@user = user.find_by(username: 'sample1')@user.authenticate('password1')
#<User id: 8, username: "sample1" password_digest:"$2a$">...
@user.authenticate('password')
false

And that is the basic gist of it. However, you should still read the documentation here.

Use ‘before’ Filter to Dry Up Your Code

While creating your app, you will most likely have many occasions where you will need to check to see if a user is logged in before allowing them to access different urls. Instead of adding an if/else statement to every controller action, simply add a ‘before’ filter to do this. You can read more about filters here, but a sample implementation would be as follows:

# Require environment file here
class ApplicationController < Sinatra::Base
enable :sessions
before '/samples*' do # Before all routes that start with /samples
# Redirect somewhere, perhaps homepage, perhaps login
# For this example we will redirect to login
redirect '/login' unless logged_in?
end
helpers do
def current_user
@current_user ||= User.find_by_id(session[:user])
end

def logged_in?
current_user != nil
end
end
end

You’ll notice I added two helper methods which check for current user and if they are logged in. The source of the methods can be found here.

Conclusion

Thanks for reading! Hopefully these tips will allow you to spend less time worrying about the boring parts of setting up your application, and more time typing. Happy coding!

--

--