Snow White & the 7 RESTful Routes

Melissa Gonzalez
Adventures in Code
Published in
10 min readJul 22, 2017
Snow White understands the key to staying healthy is getting enough REST and eating an apple a day!

All Good Things Come in Sevens?

Snow White had her 7 dwarves. A week has 7 days. Christians have 7 deadly sins. . . And programmers have 7 RESTful routes!

Rest is good for your personal health and well-being, whereas REST is good for the understandability and usability of your CRUD app (an app that can Create, Read, Update, and Delete data). In the context of web development, REST stands for Representational State Transfer and refers to a set of guidelines for html verb + url combinations and their designated actions.

Following these RESTful conventions makes it easier for developers to be on the same page. Since these routes are the same/similar for all CRUD apps, it’s easier for other developers to understand what your app is doing if you follow these conventions as well.

There are 7 routes for CRUD verbs and actions. These routes are:

get “/models” => “controller#index” 
# Shows all instances of your model
get “/models/new” => “controller#new”
# Shows form to create new instance
post “/models“ => “controller#create”
# Creates new instance from new form
get “/models/:id” => “controller#show”
# Shows individual instance (id#)
get “/models/:id/edit” => “controller#edit”
# Shows form to edit specific instance
patch “/models/:id” => “controller#update”
# Updates instance from Edit form
delete “/models/:id” => “controller#destroy”
# Removes instance from database

The beauty of following these conventions is that you don’t have to reinvent the wheel every time you build a new CRUD app. The routes and method names have already been decided, so you can just focus on the app itself.

Since all CRUD apps are capable of doing the same four basic actions, these routes can be used for all your projects. I’ll go through each of the CRUD actions one by one, and how each of the RESTful routes accomplishes each action.

For the purpose of this blog, I’ll refer to the CRUD actions with capital letters (Create, Read, Update, and Delete), whereas I’ll refer to the RESTful routes with a #hash symbol and the name of its method (#index, #new, #create, #show, #edit, #update, and #destroy). Hopefully that’ll make it easier to tell when I’m talking about an action, a route, or just describing things!

Once these routes are implemented in your app, you no longer have to use the terminal to update your database! You can do all your database updates within your app itself!

CRUD Action: Create

Within the RESTful routes, two routes are designed to work in conjunction to create a new instance of a model and save it to the database.

The #new route simply shows a form for the user to fill out, while the #create route takes the user inputs and adds the information to the database.

The code for these two routes are:

get “/models/new” => “controller#new” 
# Shows form to create new instance
post “/models“ => “controller#create”
# Creates new instance from new form

#new RESTful Route

When the user sends a get request to /models/new, it triggers the #new route, which simply shows a form for the user to fill out. The code for the new method is:

def new
render “new.html.erb”
end

To activate this route, the user simply visits the web address of the form by typing the url into the browser or (more likely) clicking a link. This sends the get request to the /models/new url. The user then fills out the form, but the new instance of the model will not be created until the user submits the form.

The code for the form will look something like:

<%= form_tag “/models”, method: :post do %>
<div>Attribute1: <input type=”text” name=“input1”></div>
<div>Attribute2: <input type=”text” name=”input2"></div>
<div><input type=”submit” value=”Create New Instance”></div>
<% end %>

In Rails, a Rails form_tag must be used rather than a usual html tag. It does the exact same function as the html tag, but with some added security to prevent hackers from sending false information through the form.

When the user hits the submit button on the form, this will save the attributes as parameters with the names given in the form. It will also send a post request to the /models URL.

#create RESTful Route

Once a post request is sent to the /models url, the #create route is triggered. The create method in the controller file is where all the code exists to take the user-inputted parameters and save them to the database. For the above example, the code for the create method will look like:

def create
new_instance = Model.new(
attribute1: params[“input1”],
attribute2: params[“input2”]
)
new_instance.save
flash[:success] = “New Instance Successfully Saved!”
redirect_to “/models”
end

This method

  • creates a new instance of the model,
  • populates the instance with the attributes that the user filled out in the “Create New Instance” form,
  • saves the new instance, and
  • redirects the user to the main “/models” route while alerting the user that their instance was created.

CRUD Action: Read

There are also two RESTful routes that allow us to read the data in our database. Unlike the Create methods, however, these routes function independently of each other. Rather than one route being generated by and receiving information from another route, they just show the same information in two different ways.

The two routes allowing us to read data are:

get “/models” => “controller#index” 
# Shows all instances of your model
get “/models/:id” => “controller#show”
# Shows individual instance (id#)

#index RESTful Route

As noted in the comments, the first route will render a page that shows all instances of the model. To do this, the method just calls an array of all the instances, and saves it as an instance variable:

def index
@models = Model.all
render “index.html.erb”
end

The html file can contain as much or as little information about each instance as you want. The main job of the index page is to list all the instances, and have a link to another page which will show more information for one particular instance.

To display all the instances and create a customized link for each particular link, we need to embed Ruby code into the HTML in order to loop through the @models array that was created in the controller. Here’s an example of what the HTML file might look like for a simple page that only lists the name of the instance, with a link to the instance’s #show page:

<% @models.each do |model| %>
<a href=“/models/<%= model.id %>”><%= model.name%></a>
<% end %>

The link to the individual product would then display additional information about the instance!

#show RESTful Route

The #show route utilizes URL segment parameters to allow us to build a single template that will display each instance in our database individually. In order for the correct page to be loaded containing the information for one specific instance, the controller method must first find the instance with the correct id, and return that instance only. The code for this looks like:

def show
@product = Product.find_by(id: params[“id”])
render “show.html.erb”
end

where id: refers to the id attribute that Rails assigns each instance of a model, and “id” is the url segment parameter :id of the #show route. This url segment parameter was defined in our index page as a link for the individual instance.

It’s definitely a daunting task keeping track of where similarly-named variables are coming from, but this type of attention to detail is very important when it comes to programming!

The “show.html.erb” file would then contain html to display all the information about the specific product. Here’s a basic example of what this code would look like:

<h1><%= model.name %></h1>
<h2><%= model.attribute1 %></h2>
<h3><%= model.attribute2 %></h3>

Obviously, there would be more html on this page to make it look nicer (perhaps using Bootstrap?) But the idea is that this page should display all the information you want the user to be able to see. The user would get to this page by clicking on the appropriate link in the Index page.

CRUD Action: Update

Similar to Create, there are two RESTful Routes that work in conjunction to perform the Update CRUD action.

The #edit route simply displays a form for the user to fill out, while the #update route takes the parameters from the form and actually updates the existing database instance.

get “/models/:id/edit” => “controller#edit” 
# Shows form to edit specific instance
patch “/models/:id” => “controller#update”
# Updates instance from Edit form

The #edit and #update routes work very similarly to the #new and #create routes. In fact, the code will be very similar except for a few small changes.

#edit RESTful Route

The job of the #edit route is simply to show a user a form to fill out. However, since we are editing an existing instance, it must first find the instance so that the app knows which instance we’re editing. The code for the controller#edit method would look like:

def edit
@model = Model.find_by(id: params[:url_segment_id])
render “edit.html.erb”
end

To activate this route, the user just visits /models/:url_segment_id/edit, where :url_segment_id is a URL segment parameter that refers to the id of the instance. Note: you can make the URL segment parameter any attribute in the database, but it’s best to use the id since that is unique to each instance. Also, it’s generated and managed by Rails, so we can’t accidentally mess with it and ruin our links!

The edit.html.erb file that the edit method renders will be a form similar to the one we used in create.html.erb. The main differences are:

  • The action of the Submit button will be patch “/models/:id”
  • The form will be pre-filled with the existing information in the database, so the user can just edit what’s already there, or leave it alone if not all attributes will be updated.

An example of the code for the html page:

<%= form_tag “/models/#{@model.id}”, method: :patch do %>
<div>Attribute1:
<input type=”text” name=“input1”
value=“<%= @model. attribute1 %>”>
</div>
<div>Attribute2:
<input type=”text” name=“input2”
value=“<%= @model. attribute2 %>”>
</div>
<div><input type=”submit” value=“Update this Instance”></div>
<% end %>

When the user hits the Submit button for this app, it will send a Patch request to /models/:url_segment_id and save the attributes into the params hash.

#update RESTful Route

Once a patch request is sent to the /models/:url_segment_id url, the controller#update route is triggered. Just like the “create” method, the “update” method in the controller file is where all the code exists to take the user-edited parameters and save them to the database. For the previous example, the code for the create method will look like:

def create
@model = Model.find_by(id: params[:url_segment_id]
@model.attribute1 = params[“input1”]
@model.attribute2 = params[“input2”]
@model.save
flash[:success] = “Instance Successfully Updated!”
redirect_to “/models/#{@model.id}”
end

This method

  • finds the existing instance based on the parameter listed in the url segment parameter
  • updates all the attributes based on the user input from the Edit. Note that if the user didn’t edit a field, it will just save the exact same value.
  • saves the instance
  • redirects the user back to the #show page while alerting the user that their instance was update.

CRUD Action: Delete

Delete is the most straightforward of the CRUD actions and is therefore the only CRUD action that one uses one route.

This route simply find the desired instance, and runs the .destroy method on it. Rather than rendering its own unique html page, it just redirects the user back to the index route while displaying a message saying the action was successful.

#destroy RESTful Route

The route for the Destroy action is:

delete “/models/:id” => “controller#destroy”

As with the post and patch requests that the #create and #update routes employed, the delete request cannot be submitted simply by clicking a link or visiting a website (these only send get requests). Instead, the appropriate request is submitted using a form.

However, unlike the create and update routes, for there aren’t any user inputs for the delete route besides simply clicking the Submit button, which in this case will be labeled Delete.

The code for this would be placed on another html page — perhaps the Edit page as a secondary button option apart from submitting the form or returning to the main page. It can even be made as an option in a pop-up window so that you have have the page display a warning before giving them access to the Delete button (more on how to do this in a future post!)

In any case, the code for the delete button is:

<%= form_tag “/models”, method: :delete do %>
<div><input type=”submit” value=“Delete”></div>
<% end %>

You can also use a link_to or button_to tag rather than a form_tag tag.

Once the user clicks on the delete button, it sends a Delete request to “/models”, which activates the Destroy method. The method for the Destroy action is:

def destroy
instance = Model.find_by(id: params[:id])
instance.destroy
flash[:warning] = “Instance Successfully Deleted!”
redirect_to “/index”
end

Since the instance will be deleted by the time the method reaches the end, there isn’t much to display, so the above code simply takes the user back to the index while displaying a message saying the item was deleted.

No need to reinvent the wheel when you follow RESTful conventions!

These seven routes serve as the foundation of any CRUD app. Following these conventions will allow you to set up a new app quickly and easily.

Not having to think about how to set up your routes and pages will allow you to focus your attention on the app itself and customize it to your needs.

Someone else already invented the wheel; no need to reinvent it! Use the structure that already exists so you can focus on more important aspects of your app!

--

--

Melissa Gonzalez
Adventures in Code

Aspiring Web Developer. Fitness Enthusiast. Foodie. Beer Lover. Triathlete. Former Research Scientist.