First of all, Scope is same as Class method
def self.with_suger
where("suger > 0")
end
This is same as
scope :with_suger, -> {
where("suger > 0")
}
and then, use it as class method.
BendingMachine.with_suger
cut in
#{table_name} is useful π
- I'd recommend you to use this, otherwise, you will see this error message when you join and merge the scope with another model scope.
- Especially, when your model name and table name is different, you easily go into confusing. But this way, you'll be still in Object World.
ActiveRecord::StatementInvalid:
Mysql2::Error: Column 'created_at' in where clause is ambiguous:
scope :created_until_the_day, -> (date) {
where("#{table_name}.created_at < ?", date)
}
π Simple Scope
scope :creator_filter, -> {
where(creator: true)
}
scope :over_x_years_old, (x)-> {
where('age >= ?', x)
}
π¦join table
It makes "Inner Join" on with the relation.
scope :with_authored_book, -> {
joins(:book)
}
π¦π¦join Multi Scope
scope :with_authored_book_and_laptop, -> {
joins(:book, :laptop)
}
ππ₯Hierarchy Scope
scope :with_authored_book_of_abc_publisher, -> {
joins(book: :publisher)
}
ππ₯π¦π¦ Hierarchy and multi Scope
scope :with_authored_book_of_abc_publisher, -> {
joins(:laptop, {book: :publisher})
}
ππ₯ WHERE with Hierarchy scope
You can write both ways.
.where(User.table_name => {name: 'john connor'})
.where("#{User.table_name}.name = ?", 'john connor')
Merge
without merge
joins(:user)
.where("#{User.table_name}.name = ?", 'john connor')
or
joins(:user)
.where(User.table_name => {name: 'john connor'})
With Merge
joins(:user)
.merge(User.where(name: 'john connor'))
EXISTS
WHERE NOT exists (
SELECT *
FROM users
WHERE users.company_id = :company_id
AND users.story_id = stories.id
)
.where(User.joins(:company, :story).where(comapny_id: company_id).exists.not)
Top comments (0)