Scope và class method có thật sự khác nhau?

Đăng bởi Lưu Đại vào ngày 29-02-2024
Câu trả lời theo mình là nó không khác gì nhau cả. Bản chất của scope chính là class method

Vậy tại sao scope methods có thể gọi nối với nhau (chained)?

Để class method có thể gọi chained thì khi object mà nó trả ra phải chứa các class methods của class đang được gọi
Test thử trên class Post của project mình xem rails trả gì ra sau khi goi 1 scope
image.png

Ồ vậy là nó trả ra một Post::ActiveRecordRelation, đây là một class được tạo ra khi class Post extend ActiveRecord::Base. Cụ thể là đoạn lệnh tạo class này được viết trong module Delegation::DelegationCache
image.png

Mỗi một class ActiveRecord::Relation được tạo ra sẽ được tạo trong namespace (module) của model tương ứng trong trường hợp trên là Post
Khi tạo các class này sẽ được import các methods của class tổ tiên (nếu class cha không kế thừa trực tiếp từ ActiveRecord::Base thì nó sẽ tiếp tục lần ngược lên để đảm bảo các methods đều được import vào class mới này). VD: Có một class BlogPost < Post khi tạo class ActiveRecord::Relation nó sẽ gọi đệ quy để import method class cha (Post) trước sau đó mới import methods class BlogPost
image.png

Vậy nếu muốn class method chain được thì chỉ cần trả ra đúng ActiveRecord::Relation là được 😉

Tại sao lại phải phân ra scope và class method? 

Vì Ruby có luật: "Convention over configuration" scope và class methods được phân ra để tách biệt hơn về mặt mục đích sử dụng.
Cụ thể khi nào dùng scope khi nào dùng class method có thể tham khảo bài blog này Should You Use Scopes or Class Methods?