Sinatra Todo Application with MVC

Salma El Shahawy
6 min readApr 22, 2018
MVC interaction structure

Sinatra is considered a light weight Ruby framework for creating simple web applications with minimal effort. In this post, I will walk you through how to build a simple todo application with multiple controllers using CRUD methods. If you are interested in the code, you can find it in the Github repository . You are more than welcome to contribute any improvements.

This post assumes having a good experience in the ERB syntax, database, ActiveRecord, Sinatra, and Sqlite3

Structure the MVC

The most challenging task for any beginner in Sinatra is to structure the Model Views Controller correctly. Specifically, the process of setting up the environment. A helpful tool that can ease the structuring process of the Model Views Controller is a cool gem called corneal — this is the link to the repo. Corneal is designed and created by Brian Emory; it is a Ruby gem that is a Sinatra app generator with Rails-like simplicity. You only need to install the gem by gem install corneal and run corneal new APP-NAME. Then, run bundle install to install all missing gems, that’s it! You may refer to the full instructions in the corneal README file for more information.

Building the ActiveRecord associations

It is very important to make a check list NOTE file in your application to list all what you need to make the app run with full functionality.

ActiveRecord has built-in macros for setting up the object relationships. What you have to do is just figure out what are the correct macros you should use. This application has two relationships: the user object has_may todos and the todo object belongs_to user.

Using encrypted password

Encryption is crucial to protect your users information. ActiveRecord gives a good macro option — has_secure_password for this purpose. To utilize this macro, you have to fulfill the following conditions:

  1. The application must have bcrypt-ruby gem installed.
  2. The users table must have a string column for “password_digest”.

Then, you can use has_secure_password macro :-)

Start running your database

In the db/migrate, you can find the user_table and todo table. You have to create the table and identify the type of data.

the users table
The todo table

Then, in the terminal, run rake db:migrate to migrate your tables to obtain the schema file.

the schema file after migration

There is UI application that allows you to browse your tables DB browser for sqlite.

Test your pages

It is a rule of thumb to start carefully and test each step you did. Otherwise, you will find your self sinked in a series of errors that you don’t know where it came from. Try to start with application controller and confirm that the index page work using get verb.

application controller

Applying CRUD using RESTful routes

CRUD means create, read, update and delete using a restful routes. A RESTful route provides a mapping between HTTP verbs, controller actions, and (implicitly) CRUD operations in a database— Railsguide. I used the following table as a guide to implement the CRUD methods.

the restful table guide in rubyonrails.org

Users controller

The user controller was responsible for implementing the user sign-in/sign-out, sign-up, and to edit the user profile. The authenticate method was used to confirm the password with the saved password in the password_digest column in the data base.

The sign-up/sign-in forms

It is a simple HTML form tag that use two main attributes: action attribute, which is set to /signup route; and method attribute, which set to “POST”. Sign-in form is a repetitive process.

Sign-up form (new)
sign-in form

Show the user profile page

To show the user his profile page, you will need to pull out the user.name from the user object. That can be achieved by using the ERB syntax — iterating over the user object and set the dynamic route to print out the user name of the current user using the user.id route.

The user profile page

Edit the user personal information

To edit — according to RESTful table, you have to use PATCH HTTP verb, but it won’t work directly! For POST and DELETE verbs, the browser do not support those verbs. To overcome this issue, you have to make the following two steps:

  1. Use the Rack::MethodOverride inside your config.ru file. Allow the method to be overridden if params[:_method] is set. This is the middleware which supports the PATCH/PUT and DELETE HTTP method types.
  2. Establish an input with the following attributes: id and type set to hidden, name to a “_method” and finally the value to “PATCH”.

and that’s it, you are done :-).

using the MethodOverride in config.ru
setting up the PATCH

In the todo object, you will use the same functions to create, show, and update the profile of the user. The only exception is demonstrated below.

Read the ToDo for a specific user

The most challenging task is to guarantee that the user is the only one permitted to view/edit/delete his related todos. To do so, I used the binding.pry and checked out @todos.methods to grab the targeted one. The QueryMethods that I chose named “where”. It’s job was to search for a saved user ID in the database that matches the entered user ID and display the corresponding ToDo list.

the user can only see his todos
The user can only edit his todos

Validating your entry fields

You can ban the user from bad entries, such as bad email formatting or leaving one of the fields empty. To do so, you need to use the ActiveRecord validations for the entry fields. Here, I used the shortcut validation format to confirm the validity of the user entry. In the Models folder of the user class, I created a constant for email format using RegEx.

Validation methods in the User class

Conclusion

To wrap up, ActiveRecord is not magic, but it is smart. To know how to utilize the ActiveRecord, you really need to read the related documentations meticulously. Hence, you would learn a huge number of methods that can make your app fancier.

If you have any questions or comments on the app, please don’t hesitate to reach me by commenting on the post. Thank you!

Acknowledgment

  1. Sinatra-todo-app Github repository
  2. Corneal gem this is the link to the repo
  3. Medium Blog for Brian Emory
  4. DB browser for sqlite.
  5. RESTful guide table — Railsguide
  6. Rack::MethodOverride documentation rubyonrails
  7. Where query-method documentation ActiveRecord
  8. Validation methods ActiveRecord:Validation

--

--