ActiveRecord Basics

RailsGirlsTO Meetup, June 28, 2016


@jennyveens

Why should You care about ActiveRecord?

ActiveRecord is

MAGIC

ActiveRecord is NOT

MAGIC

So what is ActiveRecord?


Technical Term:

ActiveRecord is an Object-Relational-Mapping system (ORM). A technique that connects objects in an application with the related tables in a database system.

Wait, what?


My Terms:

ActiveRecord is a translator and data commander.

ActiveRecord gets stuff DONE.

What can ActiveRecord do for us?


  • Migrations
  • Validations
  • Associations
  • CRUD
  • Callbacks

A word about MODELS

It puts the 'M' in MVC!

Before we can generate a new model, we have to create an app:


➜ rails new testapp
➜ cd testapp
➜ rails generate model Post

Other ways to get the job done:

➜ rails g model Post
➜ rails generate model Post title:string body:text
➜  testapp rails generate model Post
Running via Spring preloader in process 20026
  invoke  active_record
  create    db/migrate/20160628011521_create_posts.rb
  create    app/models/post.rb
  invoke    test_unit
  create      test/models/post_test.rb
  create      test/fixtures/posts.yml

Migrations

class CreatePosts < ActiveRecord::Migration
  def change
    create_table :posts do |t|
      t.string :title
      t.text :body

      t.timestamps null: false
    end
  end
end
➜ rake db:migrate

== 20160628012148 CreatePosts: migrating ======================================
-- create_table(:posts)
-> 0.0014s
== 20160628012148 CreatePosts: migrated (0.0015s) =============================
					

Creating new Models isn't all we can do with migration. We can also use migrations to edit or remove existing columns and tables.

➜ rails generate migration AddSomethingToPost

add_column
add_index
add_timestamps
change_column
change_table
create_table
drop_table
remove_column
remove_index
remove_timestamps
rename_column
rename_index
rename_table

Benefits?


Master List of DB build steps


Reversible

➜ rake db:rollback

Validations

Why Validate?


Quality-control our data before it's in our database.


Front-end validations are good... but validations are better.

Validations are super easy to set up:


validates :the_model_to_validate, validation: value
					

acceptance
confirmation
exclusion
format
inclusion
length
numericality
presence
absence
uniqueness

Let's Try It!


class Post < ActiveRecord::Base

	validates :title, :length => { in: 4..40 }

end
					
➜ a = Post.new
 => #<Post id: nil, title: nil, body: nil, created_at: nil, updated_at: nil>
➜ a.valid?
 => false

➜ b = Post.new
➜ b.title = "I'm a title!"
 => "I'm a title!"
➜ b.valid?
 => true

Error Handling

➜ a = Post.new
 => #<Post id: nil, title: nil, body: nil, created_at: nil, updated_at: nil>
➜ a.valid?
 => false

➜ a.errors.full_messages
 => ["Title is too short (minimum is 4 characters)"]

Custom Error Mesages


class Post < ActiveRecord::Base

	validates :title, :length => { in: 4..40, message: "isn't the right length!" }

end

➜ a.errors.full_messages
 => ["Title isn't the right length!"]

					

Associations

Associations let us create relationships between our Models.

belongs_to
has_one
has_many
has_many :through
has_one :through
has_and_belongs_to_many

class Post < ActiveRecord::Base

	has_many :comments
	belongs_to :author

end

class Comment < ActiveRecord::Base

	belongs_to :post

end
									

Let's Talk about CRUD Baby!

This can also be referred to as the 'Object Life Cycle'.

Create

p = Post.new title: "I'm the title", body: "I'm the body text"
 => #<Post id: nil, title: "I'm the title", body: "I'm the body text", created_at: nil, updated_at: nil>
p = Post.save

(0.2ms)  begin transaction
  SQL (0.7ms)  INSERT INTO "posts" ("title", "body", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["title", "I'm the title"], ["body", "I'm the body text"], ["created_at", "2016-06-28 12:46:59.593867"], ["updated_at", "2016-06-28 12:46:59.593867"]]
   (1.1ms)  commit transaction
 => true


p = Post.create
					

Read

Finding our records...

Post.all
Post.first
Post.last
Post.find id
Post.find [ array of ids to find ]
Post.find_by_title "string"

Update

p.update_attributes title: "This is the new title."
p.update( title: "This is the new title." )

(0.1ms)  begin transaction
  SQL (0.6ms)  UPDATE "posts" SET "title" = ?, "updated_at" = ? 
  WHERE "posts"."id" = ?  [["title", "This is the new title"], 
  ["updated_at", "2016-06-28 12:55:44.194719"], ["id", 2]]
   (1.0ms)  commit transaction
 => true
					

Destroy

p.destroy

(0.1ms)  begin transaction
  SQL (0.6ms)  UPDATE "posts" SET "title" = ?, "updated_at" = ? 
  WHERE "posts"."id" = ?  [["title", "This is the new title"], 
  ["updated_at", "2016-06-28 12:55:44.194719"], ["id", 2]]
   (1.0ms)  commit transaction
 => true
					

Callbacks

Object Creation


before_validation
after_validation
before_save
around_save
before_create
around_create
after_create
after_save
after_commit/after_rollback
class Post < ActiveRecord::Base

	after_save :do_this_awesome_thing

end

Want to know more?

Check out RailsGuides - http://guides.rubyonrails.org/