I was recently asked if I could sketch up the difference between when you do and don’t use a join table for complex associations. Let’s take a look at the join table below:
So here we have a join table called post_category.rb
represented by the blue box. Notice the contiguous loop of arrows highlighted in yellow; if you start anywhere along this yellow path, you will trace it through all of the association statements back to where you started. All of the code for these objects (and their analogous migration tables) are provided in the illustration. Now let’s take a look at another project where a join table is not used:
Here we have the appointment.rb
object model in the same place as our previous (blue colored) post_category.rb
join table in the previous example. What is the fundamental difference between this illustration and the previous one? Simply put, the appointment.rb
here is an actual thing; it is a full-fledged Ruby class object model that can accept Ruby instance methods. It also has an analogous migration table (CreateAppointments.rb
) that contains a row; in this case the datetime
that converts an integer timestamp into a readable format with the month name. If we wanted to, we could add the location of the appointment, we could also specify start & end times as well. In effect, the appointment is a join table with extra stuff going on - but it uses the same logic (to bind together objects) as an actual join table. To be sure, we could associate users to post_category.rb
in the first example such that users follow specific post categories, but then it would be better to change the name of post_category.rb
to something like topic.rb
so we know this is no longer simply a join table.
In the Sinatra module we learn about restful routes and how to properly incorporate an object id number into our app’s URLs. In this lab here we encountered a workspace that puts the object’s name into the URL rather than the object’s id number. I thought this was cool and wanted to do the same thing for my Sinatra portfolio project here since I already knew how to use the object id. What follows is a step-by-step process for anyone who wants to do the same thing.
If you are building a Sinatra app and you want to use Rack::Flash to generate all of your warning messages displayed to your users, then this is the blog post for you. Below I will walk you through how to set this all up and get it running. To be sure, the Learn.co (Flatiron) curriculum sort-of covers this here but I will cover these additional topics:
Before starting this portfolio project, I began a paradigm shift away from illustrating whole programs to just illustrating the general frameworks they were written in. The idea is, if we can graphically conceptualize the framework in a single illustration, we can recycle that illustration and use it on multiple projects. From the outset of this portfolio project, I coded in an ambitiously complex set of object models to see if I could get them to collaborate properly. Although this project allowed me to explore Active Record’s abilities in depth, the stringent requirements for restful routes limited my abilities to refactor my controllers and views. This was partly due to me using the more complex slugging of objects in the URLs rather than using object ID’s, but also due to another fundamental limitation: our use of Sinatra did not explore the abstracting-out of embedded Ruby code.
For a while now I’ve been wondering how programmers keep track of all their work when the code they’re working with is so massive. It seem the answer is: ‘frameworks.’ Frameworks set up the ground rules so multiple programmers can collaborate on a set of [valid] assumptions, they also disentangle what would otherwise become spaghetti-code wherein one little change in the program somewhere will break the whole thing and force you to chase down bugs for weeks on end. Best of all, they save time by doing a lot of work for you that several programmers would otherwise have to each do on their own, forcing them to all write the same code over & over again.