How to Build a Todo App with Ruby on Rails

In this tutorial you will get a Ruby on Rails Todo App up and running on your local server, and will push your work into github. If you are casually browsing and are maybe interested in doing a Ruby on Rails tutorial, stop what you are doing RIGHT NOW and give this podcast a listen! It will give you the fuel you need to continue down the web developer path; it definitely fueled me.

Reading and executing tutorials is an amazing way to learn, so roll up your sleeves, take a slug of coffee, and let’s dive in!

This tutorial is loosely transposed from Mackenzie Child’s Youtube Tutorial. I’m transposing this tutorial because Mackenzie flies through the content and I wanted to slow it down a bit. I figured I’d add some value to the Ruby on Rails community and learn a little myself by transposing into blog format.

This tutorial assumes you have Ruby on Rails installed and all other pre-requisites, like github and a text editor and such.

I’m going to run through things as I would do them. It’s not necessarily the way to do it, just how I do it, and — loosely — how Mackenzie Child does it in his tutorial. Let’s dive in:

Image for post
Image for post

Get into your terminal and type:

This will bring bring up a list of directories — or folders — such as “Desktop” “Documents” “Downloads” “Library” etc.

Change Directory into “Desktop”:

Type “ls” to show all available directories

and then jump into the directory you want to store your project in

mine’ll be saved in Projects, so I’ll jump into Projects

You could create a similar folder with the command:

Then “cd” into your new folder.

Next, I’m going to call into being the skeleton of my rails app. Easy:

A whole bunch of cool stuff happens in the terminal:

Image for post
Image for post

Next, I’ll “cd” into the project folder

and check out the files within:

Neat. Now I’ll run the rails server:

And then navigate to localhost/3000 to make sure everything is working:

Yay! You’re on Rails!

Image for post
Image for post

Now I’m going to create a new repository on github, and then commit and push my first commit.

First, create a new repository. Looks something like this:

Image for post
Image for post

Hit “create repository” and you’ll get something like this:

Image for post
Image for post

We’ll come back to this page, but first go back to your command line terminal, and kill the server with a control + c.

Then type:

And then check the git status with:

You’ll see that you have some untracked files in some red text. Let’s stage those for our first commit with:

And then check the status again with:

Ah, wonderful. Green text. We’re ready to commit:

Then you can head back to your github page to find the remaining code you need:

Image for post
Image for post

Yours will be slightly different, with your username instead of mine, of course.

Then let’s push!

If you have any errors, welcome to your first programming challenge! Google that sh!t. The more I learn about programming, the more I learn that you must be a self-sufficient problem solver. Ask for help, but ask google first.

Refresh your github page, and your todo app repository should look something like:

Image for post
Image for post

Wonderful.

Next we’re going to get back to our command line and do some “scaffolding”.

Scaffolding is like a shortcut. Scaffolding automatically generates the models, views and controllers you need for a table. A quick google search tells us:

Scaffolding in Ruby on Rails refers to the auto generation of a simple set of a model, views and controller usually for a single table. Would create a full CRUD (create, read, update, delete) web interface for the Users table”

If you’re wondering what a model, view or controller is, this image from codeacademy may help. The image demonstrates the interaction of a person with a webpage:

Image for post
Image for post

Forgive me for simplifying too much, but this is my loose understanding: a model is a database, a view is your visual aspects: the html + css, etc. and is exactly what you see on a webpage, and a controller helps the model and the view talk to each other.

Ok, back to programming. We did something to the model, the database, so now we’ve got to run a rake command.

What does this do? I’m not completely sure but we can always ask Google. In this case, Google provides us with an answer from stackoverflow.

Let’s check out local server again to make sure everything worked out:

Instead of http://localhost:3000/, you’ll want to navigate to http://localhost:3000/todo_lists/.

Image for post
Image for post

This is the todo list view that the scaffold created. The view becomes plural for some reason. Ask google “why?”.

Add a todo list, and hopefully you get something that looks like:

Image for post
Image for post

Now let’s open up our text editor (I’m using sublime 2) and look at our code.

Image for post
Image for post

Open up the config/routes.rb file and make the root of the application the todo list controller:

Your whole routes.rb file will look something like this:

Save the file.

Now boot up the local server again…

… and see what we just did at http://localhost:3000/!

Instead of the “Yay! You are running Rails” page, we have navigated directly to the todo_lists/index.html.erb page.

Image for post
Image for post

If you right-click and look at the page source, you’ll find the same code as you would if you looks at app/views/todo_lists/index.html.erb.

Image for post
Image for post

With root “todo_lists#index”, we pointed the root of the app to this todo_lists index page. Cool, huh?

Ok, kill the server (ctrl + c) and let’s write some more code:

With this code, we’re building a model (think “database”) that will store the todo items, nested underneath the todo list.

And what do we do after making changes to the model?

You can check your db/migrate files and your app/models files to see what we’ve done. We added a database migrate file:

Image for post
Image for post

And we added a todo_list model, with an association to the todo_item model, that says the model “belongs_to :todo_list”

Now we need to make an additional association. Update the todo_list.rb file from:

to:

SAVE THE FILE.

Now we’re going to get into our routes.rb file and create some routes!

Update this:

To this:

Save, and then see the routes that you created in the terminal by typing:

Whew! I’m glad we didn’t have to do that ourselves. Ah, the beautiful laziness of Rails. Or am I the lazy one? Let’s not answer that question.

Next!

We are going to generate a controller for our todo_items. In the terminal, type:

Hurray! Success!

Check your controller file to see what you’ve done:

Image for post
Image for post

Update your todo_items_controller.rb file from:

To:

So we’ve done a lot here, and I won’t pretend to know everything we’ve done— learning all this myself as we go along — but I do know that we’ve created an action for creating new todo’s, so now we need a form that will let us collect this data from the user in the views.

We will create two “partials” in our views/layouts folder:

_todo_item.html.erb and _form.html.erb

What is a partial? Let’s ask Google:

“Partials in Ruby on Rails. … Partials allow you to easily organize and reuse your view code in a Rails application. Partial filenames typically start with an underscore ( _ ) and end in the same .html.erb extension as your views.”

You might use a different partial for a guest vs. a logged-in user of your website.

Back to adding a form:

First, let’s open the _form.html.erb file and add:

Then, open the _todo_item.html.erb file and add:

Next, we want to show these items under the todo_lists show.html.erb page.

Update this:

To this:

Then, pull up the server again.

I get an error message:

Image for post
Image for post

This stumped me for several minutes. I tried googling “missing template ruby” and looked around stackexchange but found nothing that helped.

Then I read: “missing partial todo_items/_form”, “searched in: /Users/deallen/Desktop/Projects/todo/app/views” and realized that maybe my partial file was saved in the wrong place.

Bingo.

After a couple of tries, I eventually got the page to work by saving the _form.html.erb file in the views/todo_items folder rather than the /views/layouts folder:

Image for post
Image for post

Click on “show”, and you are directed to http://localhost:3000/todo_lists/1

Image for post
Image for post

Hurray! Successful bug hunt.

Let’s test the form.

Image for post
Image for post

Oops. We needed to put both partials under the todo_items folder. Like this:

Image for post
Image for post

Fix your code, and then refresh your page. You should be able to add some Todo’s now. I added 2:

Image for post
Image for post

Now we’re going to add the ability to DELETE a todo item.

Update your _todo_item.html.erb file from this:

to this:

Refresh to make sure it’s working:

Image for post
Image for post

It works, but it doesn’t look too hot, does it? Let’s amend the code to say “Delete” :

Image for post
Image for post

If you tried out your delete button, you would be disappointed.

Image for post
Image for post

We need to add a destroy method to our todo_items_controller.rb.

To create the destroy method, add this code into the todo_items_controller.rb:

So the whole file will look like:

Image for post
Image for post

Try it out!

We’ve done quite a bit, and probably should have made a few github commits by now. I’m going to go ahead and do one now:

Wow. Lot’s of red. Lot’s of changes.

Let’s see some green.

Ok, let’s commit,

and then push:

Next we’re going to add the ability to mark an item as “complete”.

Before we can mark an item as “complete” we will need to add a new column to our database:

Which will show you this in the terminal:

Image for post
Image for post

And you can go find your new db file that looks like:

Image for post
Image for post

We’ve made a change to our database so we need to run the rake db:migrate command:

Great. Next we are going to add a route:

Before:

After:

We also need to add a link to our _todo_item.html.erb view:

Before:

After:

We still aren’t ready to mark as “Complete” yet.

Back in our todo_items_controller.rb, we need to add a private method, a before action and a complete method. Those snippets will look like:

And,

And,

File will look like:

Now, give it a whirl:

Image for post
Image for post

“Todo item completed”

Nice. The item was marked as complete, but nothing else happened. Let’s do something about that.

First, I’m going to update the _todo_item.html.erb file from:

to:

Then, in the todo_item.rb model, I’m going to define this “.completed? method you may have spotted in the first line of the if statement above.

Before:

After:

Go back to your local server, refresh, and hope for success:

Image for post
Image for post

YESSSSSS. The Second Todo is struck out and opacitated.

Opacitated? It’s lighter than it was before. The updates I made to the _todo_item.html.erb file worked.

Let’s celebrate with a git commit.

shows a bunch of changed files, then

then

shows all your files staged for a commit, then

then

Ok, great. Now we’re going to work on styling our Todo app.

Navigate to app/assets/stylesheets/application.css

Rename application.css to application.scss so that we can use sass.

Image for post
Image for post

What is sass? Google will tell us!

“Sass is a CSS pre-processor with syntax advancements. Style sheets in the advanced syntax are processed by the program, and turned into regular CSS style sheets.”

At this point, Mackenzie just copy/pastes in his own stylings, so we’re going to navigate over to his github for this project and copy/paste his stylings.

Find it yet? It’s here. Copy and paste directly into your application.scss file.

Save.

Refresh.

Image for post
Image for post

Wow! Nice, huh?

The next thing we’re going to do is head to the application.html.erb file under views/layouts and put our <%= yield %> inside a container.

Before:

After:

Next we are going to take care of the index:

app/views/layouts/todo_lists/index.html.erb

And add the following to the top of the page:

You can delete the rest of the code underneath! We don’t need it any more. Or comment the code out so that you don’t loose it with:

Ok, cool. Now refresh and go back to http://localhost:3000/

Ta-Dah!

Image for post
Image for post

Looks pretty awful doesn’t it? That scrunched up text is miserable.

I’m going to dig into the application.scss code to fix it up a bit. Here is the culprit (or at least one of them):

The font is way too big for the title I’ve chosen. So I can update my title, or decrease the font. I’m going to decrease the font:

Cool:

Image for post
Image for post

Don’t get comfortable yet! We still have some work to do. Check out that first todo list and tell me it’s not hideous:

Image for post
Image for post

In our view/layouts/application.html.erb file we need to add some font links so that our app looks like Mackenzie’s app. Let’s go steal the links from his github file and copy/paste them into our application.html.erb file:

Github file is here.

Before:

After:

You can go ahead and refresh your page but you’ll be disappointed. We still have some work to do.

Get into your _todo_item.html.erb file under app/views. We’re going to replace the “Mark as Complete” with an icon from font-awesome:

Save and refresh!

Image for post
Image for post

Cool, but we clearly have more work to do.

Dig back into your _todo_item.html.erb file and update the “else” side of the if /else statement. You can just copy/paste from the “if” side of your statement, but you will want to remove the opacity style and maybe even change the icon.

I went over to the font awesome icon section and found one I liked for the “not completed” todo’s. Mine looks like this:

Instead of fa fa-check, I used fa fa-circle-thin:

Image for post
Image for post

Next, let’s work on the “delete” buttons:

Before:

After:

Don’t forget to update both sides of the If/else statement. The whole code block will look like this:

Image for post
Image for post

Next, we are going to clean up the links. Head over to views/todo_lists/show.html.erb.

Before:

After:

Then we’re going to make those edit / back links look a little better, by placing them inside a div with the class “links”. Remember, we’ve already styled some of our app with the stylesheet we “borrowed” from Mackenzie’s github page. Now, we’re just simply tagging our code with the new stylings.

In the same show.html.erb file, at the bottom, Before:

After:

Ah! And we have completely forgotten a link to delete the list if we like. So we’ll add that inside the links div with:

The whole page will look like:

Ok, now that we’ve added a ‘Delete’ button, we need to go back into our todo_lists_controller.rb and fix the Destroy method.

Right now it says:

Which will redirect us to the todo_lists_url, which is not where we want to be. We want to be redirected back to the home page, or root url.

Test your app to make sure it’s working correctly.

Next we need to get into our new.html.erb file under views/todo_lists and style up the remaining schlokeyness of our app.

Before:

After:

Save. And refresh:

Image for post
Image for post

Wow! Looking pretty great.

We’ll want to copy/paste the same stylings into the edit.html.erb file next.

Before:

After:

We updated ‘Back’ to ‘Cancel’ and removed the ‘Show’ links because we don’t really need it.

Refresh, and let’s see how we did:

Image for post
Image for post

Looking good!

Ok, whelp. That’s about it, I think. Take a look around your new todo app and start getting some sh!t done!

And don’t forget to push all your changes

That’s it! My code is here if you want to check it out. Please let me know if you have any questions!

Written by

Documentation and tutorials on Python, Programming, and Data Analysis. FPL Addict. Occasionally writing about biohacking, PMing, and food.

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