Thursday, February 13, 2020

Sinatra Project: Practice-It

I hesitate to say that I have "completed" my second project as part of Flatiron's Online Software Engineering Bootcamp. There are still some unresolved issues relating to connecting to a local host, and I have done absolutely no styling. (Starting to learn some CSS is on my agenda for break week!) However, I can proudly say that I have created an application that works and solves a real-world need of some sort. But, before we get to that...

Reflections on My Learning:

Databases were a big "a-ha" for me because all of a sudden I could imagine how companies store data related to all of the objects they create in the course of a day -- it's probably not in class array variables, but rather in tables that live in a database somewhere. Databases also solved the mystery of how information gets persisted, and further solidified my understanding of classes and objects. (In fact, I wish I had this analogy when I was teaching AP CS. There are some students who are confused about classes and objects all year, despite the 5,000 analogies you come up with. I actually think that the relationship between objects and databases -- that a table represents a class, and a row in that table an object from that class -- is one of the most student-friendly explanations I've heard!)

This was also been an exciting month because I've started to learn something that's totally new to me, which is how the internet works. I now feel comfortable with the idea that the internet functions because of conversations between a client (i.e., browser) and a server (the code that runs a specific website you're trying to load). Essentially, a client makes an HTTP request, the server runs some code (maybe code that future-me will write!) and sends a response, and then the client (browser) renders that response string into something visually appealing.

As we started to see how basic Sinatra apps are set up with models, views, and controllers, one of the big mysteries of my life became a little less foggy. When I taught CS, my kids would write programs in Java or Python that lived on their computer and could run through an IDE. They'd often ask me how you create websites that other people can interact with and allow your code to live somewhere other than your computer, and that's honestly something I was never able to answer (which is part of the reason I decided to go to boot camp!). I love the fact that I'm starting to gain a basic understanding of that process, and it's really the MVC framework that has been helpful for visualization:

  • Models are responsible for interacting with the data. In our Sinatra apps, these were written as Ruby classes, each of which was connected to a table in the database. The model classes were where we indicated associations between our objects (i.e., belongs_to and has_many), which are basically ActiveRecord macros that give us even more methods that we can call on objects from those classes.
  • Controllers are the middle-men. They contain routes that match HTTP requests (i.e., GET '/posts/new', which might result in a form for a new blog post displaying). Based on the request, the controller runs (Ruby) code that might redirect to a different route or render a view (something the user will see in their browser, like a form) using some information retrieved from the database.
  • Views are the front-end of your app (i.e., what the user will actually see on their screen). They are written in HTML and although they may display information from the database, they did not retrieve that information themselves! Instead, the "middle-man" controller got the necessary information and then passed it over to the view.
And in this way, we created a Sinatra app that is basically a lovely dance wherein the browser makes a request, the server processes the request and implements some logic in order to determine which view to render, and then digs into the database to find what it needs -- and then finally renders a view, which is all that the user will ever see. And this happens again and again. As I now visit websites in my everyday life, I'm amazed at how complicated -- yet how simple! -- it all seems. Complicated because I'm sure there are thousands of lines under the hood giving everything its functionality. Simple because, at the end of the day, it's all just HTTP requests and responses. Which finally brings us to the app that I created for my Sinatra project!

Reflections on Sinatra Project:

I was trying to come up with a "real-world" problem I could solve with my app, something that required managing a lot of content and giving users a nice interface for interacting with that content, when it hit me! As an AP teacher, I always had the following problem when it came time to reviewing for the AP exam: there are a ton of practice questions available for every combination of topics in the course, but it's really hard to keep track of which students have completed which questions. There is lots of other functionality related to this, like being able to easily access all questions related to a certain topic, or view all students who have completed a given question when you're looking for a good "peer tutor" for another student. So, I decided to create Practice-It, a Sinatra app for making an AP teacher's life easier during those critical review weeks.

I had a great time with this project, as it cemented for me a lot of the content we had been learning. It was also fun to think about an app from the perspective of a teacher user, since that's literally what I was until I started bootcamp!

It's hard to say for sure since I'm still knee-deep in the process, but I think I may have begun to clear a few hurdles on my way to becoming a software developer.
  • Workflow: I started to hit my stride in terms of an effective workflow. I set up a notes file in my project, which I used to record and categorize features I wanted to implement. I'd pick a feature, write a controller route that rendered a dummy view file, and then finally work on getting the correct HTML in the view file. After each component appeared to work even a little, I'd make a commit and push my code to GitHub. I'd then test the route out in the browser and use lots of binding.pry's to inspect what was going on from the console. After however many iterations that took, I'd make another commit, update my notes file, and then choose a new feature to work on.
  • Reading documentation: I spent a lot of time on Rails Guides learning about various ActiveRecord methods, as well as getting un-stuck on Stack Overflow. Stack Overflow used to intimidate the heck out of me -- I'd literally feel my anxiety level increase anytime I clicked on a post. I feel like our relationship is finally improving and, although I still certainly have trouble parsing through some of the responses, I generally feel like I can get what I need from it. 
  • Thinking about object relationships: Before this project, I had a basic understanding of object relationships (we focused on "is-a" and "has-a" in AP CS) as well as some of the ActiveRecord associations, like belongs_to and has_many. My project really clarified things like why I would ever need a join table (in my app, a student has many questions and a question has many students -- so I needed a join table to keep track of all (student, question) pairs) as well as the importance of thinking about all aspects of your program. For example, in the spirit of collaboration among teachers, all teachers in my app have access to all of the questions. However, every question has an "owner" who created it, and only that owner can update or delete a question. It was only after lots of fiddling around with various use cases that I came upon the question: what should happen to the questions a teacher "owns" when that teacher deletes their account? As a simple solution, I reassigned ownership of that question to another teacher in the database -- but it did get me thinking about some of the subtle questions that must come up when you've got lots of models with plethora of associations among them.
My next thought is to dive into CSS a bit so that I can make the user experience more visually appealing; I'd also love for teachers to be able to import student and question data via CSV files rather than having to manually enter it all into forms. 

I'll leave it at that for now, and invite you to check out the Practice-It GitHub repo. I'd love your feedback and ideas, and I really thank you for joining me on this journey!