This week I found myself diving back into Ruby on Rails. Mostly because I recently came up with an idea for an app I want to build which requires a back end. My dog recently had her DNA sent in to a doggy DNA testing site, and I want to build a simple form page my family and friends can visit, guess up to 5 different breeds, and submit their answers to the database so I can ultimately tally up each persons score and send out a results email.
I quickly started realizing I hadn’t worked with Ruby in awhile, and it was good to shake the cob webs off! I figured now was as good of time as any to write this simple guide of how to get a Ruby on Rails API up and running. For me, the purpose of doing this efficiently is so I can quickly move on to the front end fun.
For this demonstration I will build out the back end for my doggy breed guessing app, which I will appropriately name ‘Name That Pooch!’. In order to get that going, we need to know what types of values we expect for each column in our table. By that I mean we may have a column or key called
Now, from the beginning!
App Creation and Setup
Open a terminal and navigate to the folder you wish to create this project in. Since we want to build an API, we can use a special flag which helps Rails know what we want and what we don’t need right away,
--api. This flag helps us shave a little extra time in creation as well! Here’s the command:
rails new name_that_pooch --api --database=postgresql
--database=postgresql? This tells Rails to initiate our app with a Postgres database instead of the default SQLite3. I found Postgres is required to deploy to a hosting service I frequent called Heroku.
After running this command we should see the app building and end with this result:
We can now open up our new back end with
code name_that_pooch/, let’s take a look at the file tree:
Now is usually when I create a new repository on Github and connect it to my new project, that way I can make an initial commit which marks the very beginning. Once I’ve pushed up my first commit, I am good to move on!
The next step I like to do right away is activate the CORS (cross-origin resource sharing) I don’t know a ton about this, but I do know this is how I am able to access my API from anywhere. You can otherwise state to only share resources with specific sites, however, in this case, I don’t really care!
Start by going to the
gem ‘rack-cors’, then uncomment it:
Next, navigate to
config/initializers/cors.rb and uncomment line 8 through 16 like so:
Now that we have some new gems, we should probably install them with a bundler, using
bundle install. We should see this result when complete:
Models, Controllers, Migration
Now it’s time to “generate” our model, migration file, controller, and set up routes. Let’s call our form a “guess card”, so that will be the model name in this next command, then I’ll break down the rest of what happened:
rails g resource guess_card name:text email:text breed_one:text breed_two:text breed_three:text breed_four:text breed_five:text
Breakdown of this command:
rails g resource — this part tells rails to generate what follows, in this case I chose resource because it sets up all of the necessary files at once.
guess_card — name of the model, convention needs this to be singular.
name:text — Every pair like this that follows establishes a column in the table, on the right side of the colon, we designate what type of value we are looking for, might be an integer, or string.
I read somewhere that Postgres is finicky with strings, so I have been using
text in place of
string. Another note about this, if I were to omit the
:text on each pair, the default type would in fact be
string. Wanted to throw that out there!
We should see this result after running the command:
We now have a new controller, migration file, and model. Since we have a migration file, we should check it out before we migrate this table into our database:
Looks good to me, let’s run that migrate command,
rails db:migrate, should work great, right?
What happened? Let’s take a look at the top of these error messages:
Key words here:
database “name_that_pooch_development” does not exist
How can that be? We have a Postgres database right? Not yet! We are set up for it, but we never actually created it. Start with command
rails db:create to get this result:
That’s better! Let’s try to run
rails db:migrate again now that we have an existing database:
With this command complete, we can now head to
db/migrate/schema.rb and see the changes:
We have a way for the the guess cards to be recorded, now how do we get actual instances in our database? We need to put the actions we want in our controller so Rails knows what we can and can’t do when it comes to HTTP requests.
There are 7 RESTful routes — index, new, create, show, edit, update, and destroy. This article by Melissa Gonzalez is great for going into deeper detail.
For the purpose of this app, all I really want is to be able to create new
guess_cards in the database, and then be able to retrieve all the
guess_cards in an array from the API I serve up. To do that, we only need 2 actions —
index (shows all
create (allows a new
POST to be made to the database).
Let’s take a look at that after navigating to
index is pretty self explanatory, we are rendering every
JSON. But what is happening in
create? We are saying create a new instance of
if it successfully saves, render the
GuessCard we just created. Otherwise, render the error messages associated with what happened.
I like to test my actions in Postman, it’s easy to check
create can’t be checked without having a form built into your front end with a
POST request. So that’s where Postman comes in, they provide a way for me to do query params without pre-coding any forms. I’ll spin up the dev server with the command
rails s in the terminal, and we can begin testing it in Postman.
While Postman is set to
GET, if we go to the correct localhost port (3000 here) and add the
/guess_cards ending, we get an empty array back. That makes sense, because we haven’t made any
guess_cards yet! We could add seeds in the editor, but I like to add them in Postman to test the
create action at the same time.
To do that, I’ll change
POST, and then a query param for every column in the table, along with a made up value, like so:
After hitting send, we get this result in the body:
We are seeing the first
guess_card! I will go ahead and add another one, then go to localhost:3000 in the browser to see what we’ve got! Check it out!
Finally, we have a working API which can accept new
guess_cards, and also makes a list of all
guess_cards available in an array. Our goal has been met, and I am ready to start using this API right away! Not so bad right? Rails makes it easy!
Thanks for reading and following along, and as always, happy hacking!