#21. Rails scope

Author has_many books

books belongs_to author

Named Scope

scope :available, -> { where(available: true) }

select 'books'.* from books where books.available = 't'


scope :unavailable, -> { where(available: [nil, false]) }

select 'books'.* from books where books.available = 'f' or books.available is null


scope :public_status, -> { where(status:  'public') }

3.1.2 :004 > Article.public_status

  Article Load (0.2ms)  SELECT "articles".* FROM "articles" WHERE "articles"."status" = ? AND

"articles"."status" = ?  [["status", "public"], ["status", "public"]]


Here two times same status(‘public’) checked because one of the default scope and

one of the named scope(public_status).

Author.joins(:books).merge(Book.available)

select authors.* from authors inner join books on books.author_id=authors.id where books.available = 't'

We can achieve the desire result with ActiveRecord::Relation#merge as above, we don't need any new scope like,

scope :available_books, -> { joins(:books).where("books.available = ?", true) }


Default Scope

default_scope { where(status: 'public') }

Or

default_scope -> { where(status: 'public') }


3.1.2 :001 > Article.all

Article Load (0.3ms)  SELECT "articles".* FROM "articles" WHERE "articles"."status" = ?  [["status", "public"]]



Unscope

Article.unscoped.public_status

  Article Load (0.1ms)  SELECT "articles".* FROM "articles" WHERE "articles"."status" = ?  [["status", "public"]]


Here no two times same status(‘public’) checked because default scope is unscoped so only one of normal scope is applied.



Comments

Popular posts from this blog

#6. Fetch time in rails