class Book < ActiveRecord::Base
belongs_to :author
has_many :reviews
end
class Author < ActiveRecord::Base
has_many :books
end
class Review < ActiveRecord::Base
belongs_to :book
end
book_ids = Book.where(publish_year: '2015').map(&:id)
# => SELECT "books".* FROM "books" WHERE (publish_year = '2015')
reviews = Review.where(publish_date: '2015-11-15',
book_ids: book_ids).to_a
# => SELECT "reviews".* FROM "reviews" WHERE "reviews"."publish_date" = '2015-11-15' AND "reviews"."book_ids" IN (1, 2, 3)
books = Book.where(publish_year: '2015')
# => ActiveRecord::Relation
# as a search parameter we could use an active record relation
reviews = Review.where(publish_date: '2015-11-15', book: books).to_a
# SELECT "reviews".* FROM "reviews" WHERE "reviews"."publish_date" = '2015-11-15' AND "reviews"."book_id" IN (SELECT "books"."id" FROM "books" WHERE "books"."publish_year" = '2015')
class Review < ActiveRecord::Base
belongs_to :book
scope :approved, ->{ where(approved: true) }
end
# to get books with approved reviews
books = Book.where(publish_year: '2015')
.includes(:reviews)
.references(:reviews)
.where('reviews.approved = ?', true )
.to_a
books = Book.where(publish_year: '2015')
.includes(:reviews)
.references(:reviews)
.merge(Review.approved) # => .merge scope feature!
.to_a
# => SELECT #long books and reviews column select# FROM "books" LEFT OUTER JOIN "reviews" ON "reviews"."book_id" = "books"."id" WHERE "books"."publish_year" = '2015' AND (reviews.approved = 't')
```
# `.unscoped` method
`authors = Author.unscoped.where(last_name: 'Smith').take(5)`- removes all default scopes
# `.touch` method
To update a single timestamp column on an ActiveRecord object, `touch` is a great option.
This method can accept the column name which should be updated in addition to an object’s `:updated_at` (if present).
```
class ReviewsController < ApplicationController
def show
@review = Review.find(params[:id])
@review.touch(:last_viewed_at)
end
end
```
# `.changes` method
```
review = Review.find(1)
review.book_id = 5
review.changes
# => {"book_id"=>[4, 5]}
Each key in the changes hash maps to a record’s attribute. The value of each key is an Array with two elements: what the attribute value used to be, and what it is now.
review = Review.find(1)
review.book_id = 5
review.changed?
# => true
review = Review.find(1)
review.status = 'Approved'
review.status_was
# => 'Pending'