2. Active record?
facilitates the creation and use of business objects whose data requires
persistent storage to a database.
is a description of an Object Relational Mapping system.
ORM, is a technique that connects the rich objects of an application to tables
in a relational database management system.
3. Convention over Configuration
Naming convention
Database Table - Plural with underscores separating words (e.g.,
book_clubs).
Model Class - Singular with the first letter of each word capitalized (e.g.,
BookClub).
Schema convention
Foreign keys - These fields should be named following the pattern
singularized_table_name_id.
Primary keys - By default, Active Record will use an integer column named
id as the table's primary key
optional column names like created_at, updated_at, type etcs….
9. 2.1.1 :001 > c=Customer.create(name:'cust1')
=> #<Customer id: 1, name: "cust1", created_at: "2015-
01-03 07:58:03", updated_at: "2015-01-03 07:58:03">
To Add new Order
2.1.1 :002 > o=Order.new
2.1.1 :003 > o.customer_id=c.id
2.1.1 :003 > o.description="this is a test description"
2.1.1 :006 > o.save
To deleting a customer, and ensuring that all of its
orders get deleted as well
2.1.1 :009 > orders= Order.where(customer_id: c.id)
2.1.1 :010 > orders.each do |order|
2.1.1 :011 > order.destroy
2.1.1 :012?> end
2.1.1 :013 > c.destroy
10. With Association
class Customer < ActiveRecord::Base
has_many :orders, dependent: :destroy
end
class Order < ActiveRecord::Base
belongs_to :customer
end
2.1.1 :001 > c=Customer.create(name:'cust1')
=> #<Customer id: 1, name: "cust1", created_at: "2015-
01-03 07:58:03", updated_at: "2015-01-03 07:58:03">
To Add new Order
2.1.1 :002 > o=c.orders.create(description:”this is
first order”)
To deleting a customer, and ensuring that all of its
orders get deleted as well
2.1.1 :003 > c.destroy
13. The belongs_to Association
a one-to-one connection, such that each
instance of the declaring model "belongs
to" one instance of the other model.
must use the singular term
17. class Customer < ActiveRecord::Base
has_one :order, dependent: :destroy
end
class Order < ActiveRecord::Base
belongs_to :customer
end
c.create_order(description:"ccc")
c.order
18. The has_many Association
a one-to-many connection.
the "other side" of a belongs_to association.
The name of the other model is pluralized
when declaring a has_many association.
22. rails g model physician name:string
rails g model patient name:string
rails g model appointment physician_id:integer patient_id:integer
description:string
rake db:migrate
rails c
23. class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients, :through => :appointments
end
class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, :through => :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
end
25. The has_one :through Association
a one-to-one connection with another model.
declaring model can be matched with one instance of
another model by proceeding through a third model.
if each supplier has one account, and each account is
associated with one account history, then the supplier
model could look like this:
29. Classwork 1: Create two tables husband and wife with one on one relationship and test things.
Create a rails app which should have a database named 'blog_db' in MySQL. Then do the following
1. Create models Articles (title, content), Comments (comments, article_id), Tags (name)
2. Article should have many comments and each comment should be associated to one article
3. Each article can have many tags and each tag may be assigned to many articles.
4. Create the relation such that if we delete an article then all the comments associated with that
article is also deleted
5. Create a scope to query all the articles of yesterday sorted descending according to created date
32. class_name: Controlling association scope
By default, associations look for objects only within the current module's scope. For example:
module MyApplication
module Business
class Supplier < ActiveRecord::Base
has_one :account
end
class Account < ActiveRecord::Base
belongs_to :supplier
end
end
end
33. Supplier and Account are defined in different scopes:
module MyApplication
module Business
class Supplier < ActiveRecord::Base
has_one :account
end
end
module Billing
class Account < ActiveRecord::Base
belongs_to :supplier
end
end
end
will not work!!
34. module MyApplication
module Business
class Supplier < ActiveRecord::Base
has_one :account,
class_name: "MyApplication::Billing::Account"
end
end
module Billing
class Account < ActiveRecord::Base
belongs_to :supplier,
class_name: "MyApplication::Business::Supplier"
end
end
end
35. or
if an order belongs to a customer, but the
actual name of the model containing
customers is Patron, you'd set things up
this way:
class Order < ActiveRecord::Base
belongs_to :customer, class_name: "Patron"
end
36. :validate
If you set the :validate option to true, then associated objects will be validated whenever you save this
object. By default, this is false: associated objects will not be validated when this object is saved.
class User
belongs_to :account
validates :account, :presence => true
end
.
37. class Order < ActiveRecord::Base
belongs_to :customer, -> { where active: true },
dependent: :destroy
end
39. allows inheritance by storing the name of the class in a
column that is named “type” by default.
a way to add inheritance to your models.
STI lets you save different models inheriting from the
same model inside a single table
Ref: http://samurails.com/tutorial/single-table-inheritance-
with-rails-4-part-1/
40. rails new sti --no-test-framework
rails g model animal name:string age:integer
race:string
rake db:migrate
# app/models/animal.rb
class Animal < ActiveRecord::Base
belongs_to :tribe
self.inheritance_column = :race
# We will need a way to know which animals
# will subclass the Animal model
def self.races
%w(Lion WildBoar Meerkat)
end
end
Note that self.inheritance_column = :race is used to
specify the column for STI and is not necessary if you
are using the default column type.
If you want to disable Single Table Inheritance or use
the type column for something else, you can use
self.inheritance_column = :fake_column.
44. Scenario:
Imagine a school or college system where both students
and teachers can add posts.
The post has an author->author could be a student or
a teacher.
The students and teachers can ->add many posts.
Therefore we need an association between the Student,
Teacher and Post models.
45. $ rails generate model student name:string email:string
$ rails generate model teacher name:string email:string office:integer
$ rails generate model post author:references{polymorphic}:index title:string
body:text
Note: created the post model with the author reference set as polymorphic and
an index
46. simplified by using the t.references form
author:references{polymorphic}:index
class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.references :author, polymorphic:
true, index: true
t.string :title
t.text :body
t.timestamps
end
end
end
class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.string :title
t.text :body
t.integer :author_id
t.string :author_type
t.timestamps
end
add_index :posts, :author_id
end
end
47. The Post model will already be setup correctly
# app/models/post.rb
class Post < ActiveRecord::Base
belongs_to :author, polymorphic: true
end
# app/models/student.rb
class Student < ActiveRecord::Base
has_many :posts, as: :author
end
# app/models/teacher.rb
class Teacher < ActiveRecord::Base
has_many :posts, as: :author
end
2.1.1 :019 > s=Student.create(name: ‘Ananta’)
2.1.1 :019 > s=Student.find(1)
2.1.1 :011 > p=Post.new
=> #<Post id: nil, author_id: nil, author_type: nil, title:
nil, body: nil, created_at: nil, updated_at: nil>
2.1.1 :012 > p.author= s
=> #<Student id: 1, name: "ananta", email: nil,
created_at: "2015-01-03 07:06:51", updated_at: "2015-
01-03 07:06:51">
2.1.1 :013 > p.title="test title"
=> "test title"
2.1.1 :014 > p.save
2.1.1 :015 > Post.all
[#<Post id: 1, author_id: 1, author_type: "Student", title:
"test title", body: nil, created_at: "2015-01-03 07:08:02",
updated_at: "2015-01-03 07:08:02">
52. Scenario
You have Users.
Now, some of those Users are subscribed to your newsletter.
You marked those who receive a newsletter by adding a field to the Users
Database (user.subscribed_to_newsletter = true).
Naturally, you sometimes want to get those Users who are subscribed to
your newsletter.
ref: http://stackoverflow.com/questions/4869994/what-is-scope-named-scope-
in-rails
53.
54. of course, we always do this:
User.where(subscribed_to_newsletter: true)
Instead of always writing this you could, however, do something like this.
#File: users.rb
class User < ActiveRecord::Base
scope :newsletter, where(subscribed_to_newsletter: true)
end
This allows you to access your subscribers by simply doing this:
User.newsletter
55. Class methods on your model are automatically available on scopes. Assuming the following setup:
class Article < ActiveRecord::Base
scope :published, -> { where(published: true) }
scope :featured, -> { where(featured: true) }
def self.latest_article
order('published_at desc').first
end
def self.titles
pluck(:title)
end
end
We are able to call the methods like this:
Article.published.featured.latest_article
Article.featured.titles
57. class Post
default_scope where(published: true).order("created_at desc")
end
> Post.limit(10)
Post Load (3.3ms) SELECT `posts`.* FROM `posts` WHERE `posts`.`published` = 1 ORDER BY
created_at desc LIMIT 10
> Post.unscoped.order("updated_at desc").limit(10)
Post Load (1.9ms) SELECT `posts`.* FROM `posts` ORDER BY updated_at desc LIMIT 10