Rails’ Active Record Basics
A library that enables Rails to create, modify and interact with tables in the database.
Table of Contents
Active Record is the M in MVC (Model-View-Controller), which is the layer responsible for representing business data (tables in database) and logic (code). — Official Rails Guide.
It provides an interface between tables in the database and Ruby program code (Active Record Objects or model) to modify or create attributes and instances of a table.
In context of the rails application, the Active Record Object are commonly referred to as models. In this article I will refer to Active Record Objects or model as objects and Active Record as AR.
Stands for Object-Relational-Mapping which is used by AR to access or modify data from a table in the database.
When talking about ORM, most people are referring to a library (example Rails) that implements ORM, because:
- O stands for Object, it refers to the programming language we use. In our example it is Ruby.
- R stands for Relational, it refers to a Relational Database Manager System, aka Database.
- M stands for Mapping, where it bridges between our AR objects and database.
When ORM isn’t used in an application, it uses SQL to manipulate with data in the database, which is sophisticated, time-consuming, it involves executing many queries such as:
- Create a database connection.
- Write the SQL query.
- Run SQL query in the database.
- And get data from the database.
Whereas with ORM applications such as Rails, we can interact directly with an object in the same language we’re using. We don’t need to write separate SQL statements (if using SQL database) to interact with the database for most purposes. In Rails, it doesn’t matter which type of database we’re using as long as we’ve set up the
config/database.yml file properly. AR will handle all the nitty-gritty details of connecting our app with the database, even if we switch our database, we don’t need to change the application code, as it takes care of all the differences between databases so we can focus on the logic code that matters.
For more benefits of ORM, you can refer to this post.
By default, Rails will automatically pluralize the table name in the database depending on the name of the object declared. For example:
So if an object is of class
Book, then its corresponding table name will be
If an objects’ name consists of 2 or more words,
AdventureMovie, where each word is initialized by a capital letter, then in the database the words are divided by an underscore,
And for the object named
Person, its corresponding table name will be
people. Naming convention in Rails just doesn’t add a suffix
's’ to any word but it's smarter than that.
So in summary naming convention for:
object 👉 Singular-CamelCase
table 👉 Plural-snake_case
Just as AR uses a naming convention for names of a table in the database, similarly it uses for its columns/attributes too. There are certain names of an attribute that are reserved by AR to invoke certain functionality of it and it's not recommended to use these reserved names for other purposes. Those reserved names are:
idBy default, Rails will use this to uniquely identify each row or instance of a table. In other words, this is the Primary Key of a table. The data type of it will be an
integer for SQL & SQLite and
bigint for PostgreSQL & MySQL database. Rails will add this column by default when a table is created using AR Migration.
Let's say we have 2 tables named,
authors and we set up an association relationship between them. Both tables have a primary key,
id, but in addition,
books table will also have a column named
author_id (foreign key), where each instance of it will refer to the
id of authors table.
A foreign key isn’t set up by Rails automatically but only if we explicitly reference the relation in AR Migration. This is the attribute that AR will look for when we create associations between the tables.
Rails will automatically create these attributes when the table is created in the database using
timestamps method. The data type of these attributes will be of
datetime. The time-value of
created_at of an instance will be set only once at the time it was first created whereas for
updated_at, time-value updates every time an instance is modified.
Tells Rails that the object uses Single Table Inheritance (STI).
For Polymorphic Association.
It caches the number of belonging objects. Example: An
author has many
books. So in
authors table, an attribute named as
books_count will cache the number of books for each author.
These are the naming conventions of attributes adopted by Rails. If we follow these, it saves us from writing a lot of configuration code, hassle, and time, and in some cases no configuration to give at all! Hence, this is Rails’ Convention Over Configuration approach!
But Rails also provides the ability to explicitly configure in cases where we cant follow default convention.
If you want an AR object or models’ name to be different than that required by naming convention, then in the model file we give:
class AdventureMovie < ApplicationRecord
#sets new table name
self.table_name = "my_adventurous_movies"
Same way, it's also possible to override the attribute name of a primary key,
‘id’ (which is the default), by:
class AdventureMovie < ApplicationRecord
#sets new primary key name
self.primary_key = "movie_id"
However, from changing
movie_id, this won’t allow us to use another
id attribute in the same table for a different purpose.
Do not use attribute names as that are listed under schema convention for any other purpose than that set by Rails.
Stands for Create, Read, Update and Delete. These are the methods provided by AR which are created on the fly to read and manipulate the data stored in the table.
For any model or object, to set a new instance or record in the table, there are a couple of ways:
Instantiates an instance of the object, holds the data in memory until
.save method is called.
# instantiates object
person_1 = Person.new(name: "Juzer", gender: "M")#not saved yet, but available in memory
=> #<id: nil, name: "Juzer", gender: "M", created_at: nil, updated_at: nil>#will save in database
=> #<id: 1, name: "Juzer", gender: "M", created_at: 2021-07-12 11:04:44 UTC, updated_at: 2021-07-12 11:04:44 UTC>
person_1 is saved in the database, AR sets the value of
updated_at attributes itself.
Instantiates an instance and saves it instantly.
person_2 = Person.create(name: "Russell", gender: "M")
=> #<id: 2, name: "Russell", gender: "M", created_at: 2021-07-12 11:05:43 UTC, updated_at: 2021-07-12 11:05:43 UTC>
There are many methods to access data:
# returns first instance in the table
first = Person.first# extracts all the instances of female gender
females = Person.where(gender: "F")# returns all the peoples details
all = Person.all# extract data of an instance whose name is "Juzer"
juzer = Person.find_by(name: "Juzer")
….for more of these methods you can refer to the AR Query Interface guide.
Updates existing data:
russell = Person.find_by(name: "Russell")
russell.name = "Russell Fernandez"
To update multiple attributes at once:
russell.update(name: "Russell Fernandez")
To update data of several instances at once:
Person.update_all(relationship: nil, birth_date: nil)
To destroy an instance from a table:
juzer = Person.find_by(name: "Juzer")
To destroy multiple instances:
# deletes all records of Male gender
To destroy all users:
More of AR
There are tons of features provided by AR and the above discussed is just the tip of the iceberg. Features such as:
- Switching between different databases with ease:
Able to use MySQL in the development environment and PostgreSQL in production. Setup includes a couple of steps. Add required gem in Gemfile, run
bundle installand configure the
Enables to create, modify and delete tables from the database.
Enables connection between 2 or more models or objects.
Enables to validate a particular attribute of each instance before saving it to the database. Methods such as
updateetc will return
falseif any of the validation of the attribute fails.
Enables to add certain behavior to models when those events occur such as creating, updating, or deleting instances of a table.