Losing Rest Over RESTful Routes

Recently, I created my first web application using Sinatra: a web application framework (WAF) implemented in Ruby which, like other WAFs, helps to alleviate certain overhead associated with common tasks experienced in web development. Although Sinatra helped reduce some of the basic burdens I otherwise would have experienced in creating my first web application, the process was not entirely stress free and smooth-sailing. As a newcomer to software engineering, RESTful routing — routing that provides mapping from HTTP verbs (get, post, put, delete, patch) to controller CRUD actions (create, read, update, delete), was a difficult concept to grasp. I will attempt to clarify this concept using examples from my own web application (BaseballCardManager: an application which helps users organize their baseball card collection and view the collections of other users) in the hopes of providing clarity for present and future developers alike.


A controller is often thought of as a go-between. The controller relays data from the browser to the application, and from the application to the browser. In Sinatra, controllers are written in Ruby and consist of routes that take requests sent from the browser, run code based on those requests using models, and then render the files for the user to see. Proper controller action set-up is essential for the flow and functionality of a web application.


Create Controller Action

The first controller action I will discuss is the create action. When a user of the application wants to add a new card to their collection (create) they will click a link which directs them to the URL path /cards/new. On this page a user will see an HTML form with information to fill out. This form is created with a POST request which posts data to the server — as well as an action which tells the form what specific route the post request should be sent to.

Every form also needs a corresponding route in the controller file. In our case, a user fills out a form with details specific to the card they want to create, hits a button which submits the information and posts the details on the /cards URL page, but instead redirects the user to the specific card that was created. The user is then shown the details of their new card. If the user were to visit /cards the card would be there along with any other cards the user (or other users) may have created.


Read Controller Action

The read controller action (which corresponds with the second method in the image above) does not make use of an HTML form. In order to display a single card, we need a show action. For instance, if a user was viewing an index of all the cards (/cards) and wanted to view the details of a specific card, the user could click the card link on the index page and would be shown the details of the selected card. This controller action uses a dynamic URL — we are able to access the the ID of a card through the params hash and retrieve the selected card from our database which is then passed to the show page (cards/show) using the @ card instance variable.


Update Controller Action

The update controller action is arguably the most difficult to implement. The first controller action loads the edit form through the use of a GET request and retrieves the selected card using the params hash (see read controller action for params explanation). The form rendered by cards/edit — like the HTML form implemented to create a new card, makes use of a POST request. However, the corresponding route in our controller file uses a PATCH request. In order to rectify this difference we must allow our program to override a prior request. This is done by implementing the following code in config.ru:

Additionally, within the HTML form we must specify the method we will override POST with:

Once a user selects a card they will also be given an option to edit a card. Clicking edit directs the user to the /cards/:id/edit URL path. This displays a form identical to the form displayed by the create controller. However, once the form is completed the details of an updated card are displayed — no new card is added to the application.


Delete Controller Action

Unlike the update controller action, the delete action is relatively easy to implement. First a form is created on the card show page. Similar to our update action we must implement the following code:

Note: the form action must correspond with a route in the controller file which in this instance is /cards/:id. Therefore our action attribute should be set to the following:

action=”/cards/<%= @ cards.id %>/edit”

Visiting a page for a specific card, a user will see the option to delete the card. If the delete button is selected the card will be removed from the web application and the user will be redirected to the /cards URL path. The deleted card will no longer be present on the page.


Building a web application has been a difficult but rewarding process. Please feel free to view and use my application using the following link:



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store