Scope in Rails là gì & Tại sao nó lại hữu ích.
Scope là một custom queries
mà bạn có thể define trong Model
Every scope takes two arguments:
- Tên (name) mà bạn dùng để gọi
scope
trong code của mình - A
lambda
, để thực hiện câu truy vấn
Ví dụ:
class Fruit < ApplicationRecord
scope :with_juice, -> { where("juice > 0") }
end
Kết quả sau khi gọi một scope, bạn sẽ nhận được ActiveRecord::Relation
object.
Có nghĩa là bạn có thể chain & combine scopes!
Ví dụ:
Fruit.with_juice.with_round_shape.first(3)
Có nhiều điều cần tìm hiểu về Rails scopes
. Vì vậy chúng ta hãy tiếp tục khám phá chủ đề này.
When To Use Scopes? Ok, scopes rất tuyệt, nhưng bạn nên sử dụng chúng khi nào?
Hãy xem ví dụ dưới đây:
def index
@books = Book.where("LENGTH(title) > 20")
end
Đây là index
controller action để hiển thị tất cả books với titles có độ dài > 20 ký tự.
Nhưng nếu bạn sử dụng câu query này ở nơi khác, code bạn sẽ bị trùng lặp. Trùng lặp code sẽ làm cho project khó maintain. Hãy move câu query vào scope
class Book
scope :with_long_title, -> { where("LENGTH(title) > 20") }
end
Tại controller action code
def index
@books = Book.with_long_title
end
How to Use Rails Scopes With Arguments
Bạn có thể truyền biến vào trong scope
để có thể sủ dụng linh hoạt hơn
Cách sử dụng
class Book
scope :with_long_title, ->(length) { where("LENGTH(title) > ?", length) }
end
Dấu chấm hỏi (?) là một placeholder, nó sẽ được thay thế bằng giá trị của biến length truyền vào khi gọi scope
. Điều này giúp cho code được an toàn hơn.
Gán giá trị mặc định
class Book
scope :with_long_title, ->(length = 20) { where("LENGTH(title) > ?", length) }
end
Scope vs Class Method
Scopes
không có gì kỳ diệu hay đặc biệt. Chúng chỉ là methods.
Trên thực tế... Bạn có thể làm điều tương tự bằng cách sử dụng class methods!
Như thế này:
class Fruit
def self.with_juice
where("juice > 0")
end
end
Nhưng có những lợi thế khi sử dụng scope
so với class methods
Lý do:
- Dùng
scope
giúp code bạn clean hơn bởi cú pháp của nó. - Scope được sử dụng cho chính xác một nhiệm vụ. Bạn có thể hiểu ngay mục đích của scope khi lần đầu sử dụng nó.
- Scope không mixed với các method khác
Về mặt chức năng sự khác biệt của scope
là kết quả trả về là một ActiveRecord::Relation
, class method thì không.
Điều này giúp bạn tránh được lỗi khi scope returns nothing
.
Don’t Use Default Scopes
default_scope
sẽ tự động được gọi mỗi khi gọi 1 scope
bất kỳ nếu bạn khai báo trong model
Ví dụ:
class Post
default_scope { where(published: true) }
end
Yes!. default_scope
rất tiện khai báo 1 lần nó sẽ applied vào tất các scope trong model.
Nhưng đó là lựa chọn sai khi sử dụng nó, bới bạn có thể sẽ quên là có nó trong model của mình. Gặp lỗi lạ không mong muốn, làm tốn thời gian debbug.
Bạn có thể dùng unscoped
method để vô hiệu hóa default_scope
.
Summary Qua bài viết này bạn đã cơ bản học được cách sử dụng scope trong rails.
Đừng quên áp dụng kiến thức học được vào dự án của mình để hiểu được cách thức hoạt động của nó nhé.
Cám ơn bạn đã đọc. 🙂
Nguồn tham khảo: https://www.rubyguides.com/2019/10/scopes-in-ruby-on-rails/