Soner Mezgitci
5 min readNov 19, 2019

AR BLOG

Active Record

1 What is Active Record?

Active Record is the M in MVC — the model — which is the layer of the system responsible for representing business data and logic. Active Record facilitates the creation and use of business objects whose data requires persistent storage to a database. It is an implementation of the Active Record pattern which itself is a description of an Object Relational Mapping system.

CRUD: Reading and Writing Data

CRUD is an acronym for the four verbs we use to operate on data: Create, Read, Update and Delete. Active Record automatically creates methods to allow an application to read and manipulate data stored within its tables.

Create

Active Record objects can be created from a hash, a block, or have their attributes manually set after creation. The new method will return a new object while create will return the object and save it to the database.

For example, given a model User with attributes of name and occupation, the create method call will create and save a new record into the database:

user = User.create(name: "David", occupation: "Code Artist")

Using the new method, an object can be instantiated without being saved:

user = User.new

user.name = "David"

user.occupation = "Code Artist"

A call to user.save will commit the record to the database.

Finally, if a block is provided, both create and new will yield the new object to that block for initialization:

user = User.new do |u|

u.name = "David"

u.occupation = "Code Artist"

end

Read

Active Record provides a rich API for accessing data within a database. Below are a few examples of different data access methods provided by Active Record.

# return a collection with all users

users = User.all

# return the first user

user = User.first

# return the first user named David

david = User.find_by(name: 'David')

# find all users named David who are Code Artists and sort by created_at in reverse chronological order

users = User.where(name: 'David', occupation: 'Code Artist').order(created_at: :desc)

Update

belongs_to associations must use the singular term. If you used the pluralized form in the above example for the author assoc belongs_to associations must use the singular term. If you used the pluralized form in the above example for the author association in the Book model and tried to create the instance by Book.create(authors: @author), you would be told that there was an "uninitialized constant Book::Authors". This is because Rails automatically infers the class name from the association name. If the association name is wrongly pluralized, then the inferred class will be wrongly pluralized too.

Once an Active Record object has been retrieved, its attributes can be modified and it can be saved to the database.

user = User.find_by(name: 'David')

user.name = 'Dave'

user.save

A shorthand for this is to use a hash mapping attribute names to the desired value, like so:

user = User.find_by(name: 'David')

user.update(name: 'Dave')

This is most useful when updating several attributes at once. If, on the other hand, you’d like to update several records in bulk, you may find the update_all class method useful:

User.update_all "max_login_attempts = 3, must_change_password = 'true'"

Delete

Likewise, once retrieved an Active Record object can be destroyed which removes it from the database.

user = User.find_by(name: 'David')

user.destroy

If you’d like to delete several records in bulk, you may use destroy_by or destroy_all method:

# find and delete all users named David

User.destroy_by(name: 'David')

# delete all users

User.destroy_all

Validations

Active Record allows you to validate the state of a model before it gets written into the database. There are several methods that you can use to check your models and validate that an attribute value is not empty, is unique and not already in the database, follows a specific format, and many more.

Validation is a very important issue to consider when persisting to the database, so the methods save and update take it into account when running: they return false when validation fails and they don't actually perform any operations on the database. All of these have a bang counterpart (that is, save! and update!), which are stricter in that they raise the exception ActiveRecord::RecordInvalid if validation fails. A quick example to illustrate:

class User < ApplicationRecord

validates :name, presence: true

end

user = User.new

user.save # => false

user.save! # => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank

You can learn more about validations in the Active Record Validations guide.

Callbacks

Active Record callbacks allow you to attach code to certain events in the life-cycle of your models. This enables you to add behavior to your models by transparently executing code when those events occur, like when you create a new record, update it, destroy it, and so on.

Migrations

Rails provides a domain-specific language for managing a database schema called migrations. Migrations are stored in files which are executed against any database that Active Record supports using rake. Here's a migration that creates a table:

class CreatePublications < ActiveRecord::Migration[5.0]

def change

create_table :publications do |t|

t.string :title

t.text :description

t.references :publication_type

t.integer :publisher_id

t.string :publisher_type

t.boolean :single_issue

t.timestamps

end

add_index :publications, :publication_type_id

end

end

Rails keeps track of which files have been committed to the database and provides rollback features. To actually create the table, you’d run rails db:migrate and to roll it back, rails db:rollback.

Note that the above code is database-agnostic: it will run in MySQL, PostgreSQL, Oracle, and others.

SQL

Ruby programs can interact with relational databases like MySQL via adapters in ActiveRecord. An adapter can be a pure Ruby implementation or a hybrid Ruby/C extension. From your Ruby code, you need to specify only the name of the adapter you want to use; ActiveRecord will provide the Ruby bridge code and worry about loading the native extension (if necessary).

MySQL is a one of the most popular open source databases around and is used by many prominent organizations from Yahoo to NASA.

Soner Mezgitci
Soner Mezgitci

Written by Soner Mezgitci

Software Engineer | Ruby on Rails | JavaScript | HTML5 | CSS | PostgreSQL | React | Redux