Tìm hiểu Scopes trong Ruby on Rails

1.Scopes là gì ?

Scopes là các truy vấn tùy chỉnh mà bạn xác định bên trong Rails models của mình bằng scope method.

Mọi Scopes có hai đối số:

Một là tên mà bạn sử dụng để gọi Scopes.

Hai là lambda để thực hiện truy vấn.

Ví dụ :

class Fruit < ApplicationRecord
    scope :with_juice, -> { where("juice > 0") }
end

Gọi scope sẽ nhận được một đối tượng ActiveRecord :: Relation. Có nghĩa là chúng ta có thể kết hợp các Scopes.

Ví dụ :

Fruit.with_juice.with_round_shape.first(3)

2.Khi nào thì sử dụng Scopes?

Ví dụ :

def index
	@books = Book.where("LENGTH(title) > 20")
end

Đây là index controller action muốn hiển thị sách có tiêu đề dài hơn 20 ký tự.

Ok. Nhưng nếu muốn sử dụng truy vấn này ở những nơi khác, sẽ có code bị trùng lặp.

Trùng lặp code làm cho dự án khó bảo trì hơn.

Bây giờ hãy chuyển truy vấn này vào một scopes.

  • Chúng ta sẽ có :
class Book
	scope :with_long_title, -> { where("LENGTH(title) > 20") }
end

Và trong controller chúng ta gọi scope như sau :

def index
    @books = Book.with_long_title
end

3.Cách sử dụng Rails Scopes với đối số.

Chúng ta có thể thêm biến vào scopes để làm cho nó linh hoạt hơn .

Ví dụ :

class Book
    scope :with_long_title, ->(length) { where("LENGTH(title) > ?", length) }
end

Ở đây, dấu chấm hỏi (?) là à một phần giữ chỗ, nó sẽ được thay thế bằng giá trị length. Điều này làm cho code an toàn hơn.

Chúng ta cũng có thể đặt giá trị mặc định.

class Book
	scope :with_long_title, ->(length = 20) { where("LENGTH(title) > ?", length) }
end

4 .Scope và class method

Scope chỉ là một method.

Trên thực tế chúng ta có thể làm điều tương tự với class method:

Ví dụ :

class Fruit
  def self.with_juice
    where("juice > 0")    
  end
end

Nhưng có những lợi thế về thiết kế khi sử dụng scopes thay vì class method :

1.Dùng scope giúp code rõ ràng hơn do cú pháp của chúng.

2.Scope được sử dụng chính xác cho 1 việc,nên chúng ta dễ dàng hiểu những gì sẽ nhận được khi nhìn thấy.

3.Scope không bị trộn lẫn với các method khác, nên giúp dễ dàng nhận ra hơn.

Về mặt chức năng, sự khác biệt duy nhất là scope đảm bảo ActiveRecord :: Relation còn class method thì không.

Điều này giúp tránh lỗi khi scope không trả về gì.

5.Không nên dùng Default Scopes

Default Scopes là Scopes được áp dụng cho tất cả các truy vấn trên model.

Ví dụ :

class Post
  default_scope { where(published: true) }
end

Không nên dùng default scope vì nó sẽ ảnh hưởng đến các truy vấn khác , gây ra nhiều lỗi lạ và chúng ta không hiểu lỗi từ đâu.

Nếu bắt buộc phải dùng default scope thì các truy vấn khác cần thêm unscoped method.

6.Tổng kết

Trong bài này mình đã giới thiệu với các bạn những điều cơ bản về Scopes trong Ruby On Rails . Cảm ơn mọi người đã đọc !

Tài liệu tham khảo:

https://www.rubyguides.com/2019/10/scopes-in-ruby-on-rails/


All Rights Reserved