ActiveRecord & Migration in Ruby for Beginners
By: James Dorr
Tags: Flatiron School, Ruby, Rake, Activerecord, Migration

So began my friendship with ActiveRecord…

ActiveRecord was created to make coding easier, but it can feel like a new language. We’ll start with a guide to ActiveRecord and migration and end with a list of methods ActiveRecord gives us in Ruby. This information can be useful to understand the concepts and as a reference.

ActiveRecord for Ruby

What is ActiveRecord and Why Do We Use It?

The classes (below) each have their own tables (above)

ActiveRecord gives coders a quicker way to make tables that correspond to classes. It also comes with many great methods for creating, reading, updating, and deleting information in our tables. Even more, some people love ActiveRecord because it eliminates our need for coding in SQL.

It’s wonderful, but it is confusing and difficult to start.

Standard practice says each class in our code should be its own table in our database, and each attribute in that class should be a column in that table. ActiveRecord does most of the work for us, but first it requires migration. This guide has three distinct phases.

1. Write the code that will create the database, tables, and columns

2. Run “rake db:migrate” to tell the computer to run the code in step 1

3. Create classes, which can already interact with the database

Let’s take a closer look.

First, we write code that will create the database and tables. From the project’s main folder in the Command Line Interface (“CLI”, Terminal on MacOS), we can make the appropriate files and folders by typing

rake db:create_migration NAME=create_xyz_table

This creates the folder “db,” the “migrate” folder inside “db,” and our file inside “migrate.” It’s the easiest way and also the least likely to cause issues with ActiveRecord. The table names will be like 20190305195340_create_xyz_table.rb; The number is the year, month, day, hour, minute, and second in 24-hour Greenwich Mean Time (GMT) when we made the file. Our version of “create_xyz_table” should be similar to create_songs_table, create_artists_table, add_genre_to_songs. Be descriptive.

Repeat the steps above to make files for each table, and the migration (in step 2) will run them in the order they were created (which is why they have the long time stamps at the front).

IMPORTANT: The class names inside those tables should have the same names as the descriptive file names, but each word is capitalized without spaces nor underscores. Also note that the table name is always plural (“songs,” “artists”). This will help everything run smoothly.

Here is an example for file 20190305200530_create_songs_table.rb.

This code will create a table named “songs”

In line 1, Migration[4.2] specifies the version, which is required. If we try step 2 without a number and brackets there, it could work. If it doesn’t work, the error message should tell us the proper number to put there.

The code above will create a table called “songs” in the database (which it also created for us — db/development.db), and the table’s columns are name, track_number, and good_song. The values in name are strings, track_number stores integers, and good_song has booleans (true or false).

Punctuation and capitalization are important. One of the trickiest things about using ActiveRecord in Ruby is the different syntax. We can copy examples until we feel comfortable using ActiveRecord on our own.

When the code in db/migrate is finished and saved, return to CLI (in the project’s main folder) and run

rake db:migrate

Only now is the code from part 1 executed. Hopefully we have a nice message validating our efforts.

// ☆ rake db:migrate

== 1 CreateSongsTable: migrating ===========================================

— create_table(:songs, {})

-> 0.0009s

== 1 CreateSongsTable: migrated (0.0011s) ==================================

If not, follow the error message or paste it into a search engine. Sometimes rake prefers “bundle exec rake db:migrate” instead.

PROBLEMS

Migration was one of the most difficult things for both me and my computer. If we run into problems, our “undo” button is

rake db:rollback

Type it into CLI, and this undoes the most recent migrations, allowing us to fix things in the db/migrate folder.

We can also add to our tables and modify them without “rake db:rollback.” This is standard practice and easier if the database was created successfully. Follow step 1 again to make another file (or files). This time, we can add another table or do things like rename_table, rename_column, add_column, and change_table. See the examples below.

rename_table

The table “songs” will be renamed “records”

rename_column

In the table “records,” the column “good_song” will be renamed “user_has_starred”

add_column

The table “records” will get a new column named “album,” and the datatype is string

change_table

change_table changes all the columns in a table

Standard practice is to create different files (each with its own class) for each change or addition. If we wanted to make each of the changes above, we would make four files, just like these examples, instead of doing them in one.

After adding files that add or change the tables (or their columns), run “rake db:migrate” again — files that are already migrated are automatically ignored.

Now we can make our classes! We can put our files in the “lib” folder, in “app/models,” or in the main folder. Standard practice is to have each class in its own file. Following the example above, the “record” class will be in “record.rb,” and an “artist” class would be in “artist.rb.”

Again, notice the naming conventions so our ActiveRecord will run smoothly — the table is “records” (plural and lowercase), so the file name is “record.rb” (singular and lowercase), and the class in the file is “Record,” (singular and capitalized).

The class must be “Record” (singular, capitalized) because the table is “records” (plural, lowercase)

We might have noticed that our migrations in steps 1 and 2 “inherit” (<) from ActiveRecord::Migration[4.2], but this class is not in db/migrate, so it inherits from ActiveRecord::Base instead. Remember, inherit Migration in the migrate folder, and inherit Base outside of that folder, and both start with ActiveRecord::.

Now we tell the tables how they relate to each other. To extend the current theme, below is an example of the relationships of ‘song’ to ‘artist,’ ‘album,’ and ‘manager.’