Active Record is an Object-Relational Mapping (ORM) that allows you to map database tables to Ruby classes. A Ruby class will be its own table and instances of that class will be the rows of that table.
Let's imagine we are creating a simple cookbook application. You will have a class called Recipes, each row in the corresponding Recipes table will be an instance of the Recipes class and the database table would look like this:
After a friend expresses interest in the app, you decide that the app should allow for multiple users and those users can add recipes from the Recipes table to their individual accounts. How do you make that possible? First, you will need a new User class & table:
Next you will need away for those two tables to connect, this is where a JOIN table is needed, let's call it "user_recipes" and it will use the user_id & recipe_id to link recipes to the users.
Great, you know have all of the tables you need to be able to associate Users and Recipes together. But you still need to define the relationships between them to allow Active Record to work its magic.
Active Record has built-in macros to make these associations, or table relationships: belongs_to
, has_one
, has_many
, has_many through
, has_one through
, has_and_belongs_to_many
.
In my experience, belongs_to
, has_many
, has_many through
are most common and are the only ones needed for our simple cookbook app.
When creating the table relationships, it helps to break down each class individually, for example:
"A User can have many Recipes"
"A Recipe can have many Users"
We know now that the Users and Recipes tables need to have a many-to-many relationship. Now let's look at the JOIN table, the place where the user and recipe get associated together by their individual IDs. User 2 has Recipe 5 and 4, as shown on rows 2 & 3. Each row, or instance, of the UserRecipes table, class, is a one-to-one relationship
To create these relationships, we will use these macros: belongs_to
, has_many
, has_many through
"A User has_many
UserRecipes"
"A UserRecipe belongs_to
a User"
"A UserRecipe belongs_to
a Recipe"
"A User has_many
Recipes through
UserRecipes"
"A Recipe has_many
Users through
UserRecipes"
These associations will allow a User to have access to their own specific Recipes as well as be able to get the corresponding data from the Recipes table. Otherwise, the return would just be the IDs from the JOIN table and NOT the recipe itself.
This doesn't seem too complicated in the scope of our simple cookbook but can get very complicated very quickly as the application grows. Thankfully there are tools to help you create diagrams and visualize all of these connections such as: dbdiagram and Figma
Our app example, mapped out in dbdiagram would look similar to this:
No matter what diagram tool you use, there is no question that they will help to make your database development easier.
Top comments (0)