Computer >> Máy Tính >  >> Lập trình >> Ruby

Cách sử dụng Scopes trong Ruby on Rails

Phạm vi trong Rails là gì và tại sao nó lại hữu ích?

Chà…

Phạm vi là các truy vấn tùy chỉnh mà bạn xác định bên trong các mô hình Rails của mình với scope phương pháp.

Mọi phạm vi có hai đối số :

  1. Tên mà bạn sử dụng để gọi phạm vi này trong mã của mình.
  2. Một lambda, thực hiện truy vấn.

Có vẻ như thế này :

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

Kết quả của việc gọi một phạm vi, bạn sẽ nhận được một ActiveRecord::Relation đối tượng.

Có nghĩa là bạn có thể xâu chuỗi và kết hợp các phạm vi!

Ví dụ :

Fruit.with_juice.with_round_shape.first(3)

Bây giờ :

Còn nhiều điều cần tìm hiểu về phạm vi Rails, vì vậy chúng ta hãy tiếp tục khám phá chủ đề này.

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

Được rồi, phạm vi rất tuyệt, nhưng bạn nên sử dụng chúng khi nào?

Hãy xem một ví dụ.

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

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

Nó ổn.

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

Mã trùng lặp khiến dự án của bạn khó bảo trì hơn.

Hãy chuyển truy vấn này vào một phạm vi.

Như thế này :

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

Bây giờ hành động của bộ điều khiển của chúng tôi trông giống như thế này :

def index
  @books = Book.with_long_title
end

Tốt!

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

Bạn có thể muốn giới thiệu một biến vào một phạm vi để bạn có thể làm cho nó linh hoạt hơn.

Đây là cách thực hiện :

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

Dấu chấm hỏi (? ) là một trình giữ chỗ, nó sẽ được thay thế bằng giá trị của length . Điều này làm cho mã của bạn an toàn hơn.

Nếu bạn muốn một giá trị mặc định :

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

Hãy thử!

Phạm vi so với Phương pháp Lớp

Phạm vi không làm bất cứ điều gì kỳ diệu hoặc siêu đặc biệt.

Chúng chỉ là phương pháp.

Trên thực tế… Bạn có thể làm điều tương tự bằng cách sử dụng các phương thức lớp!

Như thế này :

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 phạm vi thay vì các phương thức lớp.

Đây là lý do tại sao :

  • Phạm vi dẫn đến mã rõ ràng hơn do cú pháp của chúng
  • Phạm vi được sử dụng cho chính xác một thứ, vì vậy, bạn biết mình nhận được gì ngay khi nhìn thấy một thứ
  • Phạm vi không bị trộn lẫn với các phương pháp khác, vì vậy chúng dễ phát hiện hơn

Về mặt chức năng, sự khác biệt duy nhất là phạm vi đảm bảo ActiveRecord::Relation và các phương thức lớp thì không.

Điều này giúp bạn tránh lỗi khi phạm vi của bạn không trả về.

Không sử dụng phạm vi mặc định

Phạm vi mặc định là phạm vi được tự động áp dụng cho mô hình của bạn.

Ví dụ :

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

Vâng!

Phạm vi mặc định rất hấp dẫn.

Nhưng chúng thường là lựa chọn sai vì có thể bạn sẽ quên rằng bạn đã xác định chúng, gặp phải các lỗi lạ và lãng phí thời gian quý báu để gỡ lỗi.

Với điều đó đã nói…

Nếu bạn phải làm việc với phạm vi mặc định, bạn có thể cần sử dụng unscoped phương pháp để vô hiệu hóa tất cả các phạm vi hiện đang được áp dụng.

Xem hướng dẫn bằng video

Tóm tắt

Làm tốt lắm! Kết quả của việc đọc bài viết này, bạn đã học được cách sử dụng phạm vi Rails một cách hiệu quả nhất.

Đừng quên áp dụng kiến ​​thức mới này vào thực tế để bạn có thể ghi nhớ cách thức hoạt động của nó.

Cảm ơn vì đã đọc. 🙂