Halfway through my school program and we’re finally dipping our toes into the backend — creating a small database to fill whatever web app my heart desires. Our first foray had us tackle using Ruby and Active Record to create the models and migrations for a basic SQLite database. For my personal project, I decided I wanted to create a small library web app, where you could add your favorite books and browse them. To do this, I created a Shelf model which will have many books, and a Book model, which will belong to a shelf. This was as easy as typing
in their respective class files. My books and my shelves classes are inheriting their methods and class methods from Active Record based on their relationship to each other. After setting that up, I still need to fill my tables in my database. Again, this is very simple and requires only:
I have set up a migration here for my Books table, one that will create the table and its columns based on the titles I’ve supplied (name, author, summary, etc.), with the last one (shelf_id) needed to reflect my Book’s relationship to it’s given shelf. Shelf was much easier to create, only needing a genre column to differentiate them from each other. I will also note that after this I set up a second migration for my Books table in which I added a column (using add_column instead of create_table) for an image URL so my books could have a cover when they’re displayed on the page. Using some handy-dandy rake migration commands in my terminal, I implemented the migrations and now I had a way to create individual books, and some shelves to house them.
Now, all I need to do is create some preliminary objects to populate my database. Again in the command line, using rake console, I can simply say “Shelf.create(genre: “Mystery”)” and I will have a new Shelf, where I will place my beloved mystery books, saved to my new database. Let’s say I temporarily save this shelf to a variable, “a”, so I can more quickly say: “a.books.create(name: “And Then There Were None”)” — so now I have my first book, handily now saved to its shelf, And Then There Were None. Who wrote that again? Oh right, Agatha Christie! I guess that’s something I might like to know when looking at my book, so I should add that in there. Again, let’s say I’ve saved my book to a variable, b, so I can succinctly say something like b.author = “Agatha Christie”, or b.pages = 272. Eventually, I’ll have a fully fleshed-out book to add to my Library:
Great! And of course, don’t forget to .save your newly added info before moving on.
Now that I’ve done this a few times to get my Library fleshed out, I think I’m ready to create a simple website to house it. I won’t get into that part, simply because I could sit here for another few hours explaining it. Which, honestly, I don’t want to do. Sorry. What I will say, is that I created a very, very, simple web app with React, where I will fetch my book and shelves data from my library database — but wait! I’m not done. Where exactly do I need to fetch from in my frontend, and what exactly do I want to send back?
For me, this was the most challenging aspect. Once I got the hang of it, it’s simple enough, but you really need to work for it. So, in my backend folder, I have my aptly named application file. This is a ruby file, and it will house all of my fetch request responses.
To start simple, here we see we are using Rack, a ruby gem that “provides a minimal, modular, and adaptable interface for developing web applications in Ruby”. So, for example in the “test” route, if we get a request from somewhere like, oh I don’t know, HTTP://localhost:3000/test, the only thing sent back will be a nice little message saying “test response”.
To keep in line with my specific app, one of my routes includes “/shelves”, so I set up some logic for that particular route’s request. Firstly, when adding a book, I have sent a ‘POST’ request from a form set up on my shelves page. I put that request’s parsed body into a variable, input, so I can use it here:
If that request’s body included an author (which, if you’re adding a book, it will), I would like to create a new book with all the information a user put into their book form, and return back to their updated shelves, where their new book will be on its shelf. Otherwise, where in this case the other POST option is creating an entirely new shelf, I would like to create that shelf with the desired genre, and again return that new shelf back on my shelves page. The same sort of logic can be applied to a DELETE request:
Or with a new route — an individual page for a selected book, on which you’ll see all the details of the specific book nicely laid out for you:
Here we can delete the book, or simply look at and read about it.
So really, that’s the basics. It was a challenge, learning a completely new language and building a database from it. However, the giddy feeling of accomplishment when it all came together and worked exactly how I wanted it to, was well worth it. Here’s what it looked like together: