Active Record

Active Record Models map an object’s attributes to columns in a relational database.

The Active Record Pattern is a pattern that maps:

  1. Classes to tables
  2. Objects to rows of data within that table
  3. Getters/Setters to columns in that table

 

Active Record uses naming conventions for the columns in database tables, depending on the purpose of these columns.

  • Foreign keys – These fields should be named following the pattern singularized_table_name_id (e.g., item_id, order_id). These are the fields that Active Record will look for when you create associations between your models.
  • Primary keys – By default, Active Record will use an integer column named id as the table’s primary key. When using Active Record Migrations to create your tables, this column will be automatically created.

 

This is how it works.

By default the model looks for a lower case plural name of the model
users database table:

id username email
1 joe joe@yahoo.com
2 bob bob@apple.com
3 jon jon@yahoo.com

 


user.rb  ActiveRecord model:

# ActiveRecord model

class User < ActiveRecord:Base
 
end

When we instantiate a user object, we automatically have getters and setters for all columns.

Now run these in the rails console …

# Creates an in memory User object:
user = User.new(username: 'bill')

These methods save to the database:
user.save
user = User.create(username: 'rick')

Retrieve column values:
user = User.find_by username: 'joe'
user.email
users = User.where(username: 'joe')

Active Record Associations

Rails supports six types of associations:

  • belongs_to
  • has_one
  • has_many
  • has_many :through
  • has_one :through
  • has_and_belongs_to_many

ActiveRecordAssociations

Database Layer

This is a data view of one table:

Screen Shot 2015-03-22 at 12.45.24 AM

This is a schema view of all the tables:

Screen Shot 2015-03-23 at 5.50.35 PM

Model Layer

Screen Shot 2015-03-23 at 4.11.53 PM

Screen Shot 2015-03-22 at 4.34.00 AM

Screen Shot 2015-03-22 at 4.30.36 AM

Screen Shot 2015-03-22 at 4.26.07 AM


Let's work with the models in a 1 to M relationship

user = User.create(username: 'chip')
(0.1ms)  begin transaction
SQL (7.1ms)  INSERT INTO "users" ("created_at", "updated_at", "username") VALUES (?, ?, ?)  [["created_at", Mon, 23 Mar 2015 20:39:39 UTC +00:00], ["updated_at", Mon, 23 Mar 2015 20:39:39 UTC +00:00], ["username", "chip"]]
(1.8ms)  commit transaction
 => #<User id: 6, username: "chip", created_at: "2015-03-23 20:39:39", updated_at: "2015-03-23 20:39:39">

post = user.posts.create(title: 'Rails')
(1.2ms)  begin transaction
SQL (5.7ms)  INSERT INTO "posts" ("created_at", "title", "updated_at", "user_id") VALUES (?, ?, ?, ?)  [["created_at", Mon, 23 Mar 2015 21:05:21 UTC +00:00], ["title", "Rails"], ["updated_at", Mon, 23 Mar 2015 21:05:21 UTC +00:00], ["user_id", 6]]
(1.6ms)  commit transaction
 => #<Post id: 5, title: "Rails", url: nil, description: nil, created_at: "2015-03-23 21:05:21", updated_at: "2015-03-23 21:05:21", user_id: 6>

user.posts << post
(0.1ms)  begin transaction
(0.1ms)  commit transaction
 => #<ActiveRecord::Associations::CollectionProxy [#<Post id: 4, title: "Rails for dummies", url: nil, description: nil, created_at: "2015-03-23 20:45:05", updated_at: "2015-03-23 20:45:05", user_id: 6>, #<Post id: 5, title: "Rails", url: nil, description: nil, created_at: "2015-03-23 21:05:21", updated_at: "2015-03-23 21:05:21", user_id: 6>, #<Post id: 5, title: "Rails", url: nil, description: nil, created_at: "2015-03-23 21:05:21", updated_at: "2015-03-23 21:05:21", user_id: 6>]>

post.save
(0.1ms)  begin transaction
(0.1ms)  commit transaction
 => true

post.creator.username
 => "chip"

user.posts
 => #<ActiveRecord::Associations::CollectionProxy [#<Post id: 4, title: "Rails for dummies", url: nil, description: nil, created_at: "2015-03-23 20:45:05", updated_at: "2015-03-23 20:45:05", user_id: 6>, #<Post id: 5, title: "Rails", url: nil, description: nil, created_at: "2015-03-23 21:05:21", updated_at: "2015-03-23 21:05:21", user_id: 6>]>


 



Let's work with the models in a M to M through relationship

post = Post.find 1
Post Load (8.6ms)  SELECT "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT 1  [["id", 1]]
=> <#Post id: 1, title: "Test Post", url: nil, description: "Description 1", created_at: "2015-03-18 23:13:21", updated_at: "2015-03-19 23:54:06", user_id: 5>

post.categories
Category Load (0.2ms)  SELECT "categories".* FROM "categories" INNER JOIN "post_categories" ON "categories"."id" = "post_categories"."category_id" WHERE "post_categories"."post_id" = ?  [["post_id", 1]]
 => #<ActiveRecord::Associations::CollectionProxy [#<Category id: 1, name: "Python", created_at: "2015-03-18 23:26:21", updated_at: "2015-03-18 23:26:21">]>

cat = Category.create(name: "Ruby Books")
(0.2ms)  begin transaction
SQL (6.8ms)  INSERT INTO "categories" ("created_at" "name", "updated_at") VALUES (?, ?, ?)  [["created_at", Sun, 22 Mar 2015 08:40:06 UTC +00:00], ["name", "Ruby Books"], ["updated_at", Sun, 22 Mar 2015 08:40:06 UTC +00:00]]
(1.0ms)  commit transaction
 => #<Category id: 2, name: "Ruby Books", created_at: "2015-03-22 08:40:06", updated_at: "2015-03-22 08:40:06"%gt;

post.categories << cat
(0.1ms)  begin transaction
SQL (0.6ms)  INSERT INTO "post_categories" ("category_id", "created_at", "post_id", "updated_at") VALUES (?, ?, ?, ?)  [["category_id", 2], ["created_at", Sun, 22 Mar 2015 08:40:38 UTC +00:00], ["post_id", 1], ["updated_at", Sun, 22 Mar 2015 08:40:38 UTC +00:00]]
(0.8ms)  commit transaction
 => #<ActiveRecord::Associations::CollectionProxy [#<Category id: 1, name: "Python", created_at: "2015-03-18 23:26:21", updated_at: "2015-03-18 23:26:21">, #<Category id: 2, name: "Ruby Books", created_at: "2015-03-22 08:40:06", updated_at: "2015-03-22 08:40:06">]>

cat.name
 => "Ruby Books"