2012-03-15 34 views
10

Tôi đã xem xét hơn 10 trang cố gắng tìm lợi ích của phạm vi trên bất kỳ phương thức lớp ActiveRecord nào khác trả về một ActiveRecord :: Quan hệ.Lợi ích thực sự của phạm vi

Trong ví dụ sau đây là lý do tại sao phạm vi tốt hơn so với phương án dưới nó mà làm điều tương tự:

#scope :pat1, lambda {{:conditions => ["name like ?", 'J%']}}  
    #scope :pat2, lambda {{:conditions => ["id > 5"]}} 

    def self.pat1 
    where("name like ?", 'J%') 
    end 

    def self.pat2 
    where("id > 5") 
    end 

    def patx 
    self.class.pat1.pat2.first 
    end 

Các tài liệu hơn và hơn nữa nói rằng phạm vi có lợi vì họ có thể bị xiềng xích ...

"Tất cả các phương thức phạm vi sẽ trả về đối tượng ActiveRecord :: Relation sẽ cho phép các phương thức khác (chẳng hạn như phạm vi khác) được gọi trên đó." - guides.rubyonrails.org

"Phạm vi lý do chính là tốt hơn so với các phương pháp lớp đơn giản là họ có thể bị xiềng xích với các phương pháp khác" http://ruby.railstutorial.org

... nhưng thay thế ở trên cũng có thể được xích sản xuất cùng một kết quả.

Chỉ cố gắng tìm hiểu xem có điều gì mới về quần áo của hoàng đế đang diễn ra ở đây không. Ngay cả từ quan điểm cú pháp, dường như không có lợi ích gì. Có phải họ nhanh hơn - một số nguồn tin mơ hồ gợi ý điều đó.

Trả lời

3

Phạm vi ActiveRecord thực sự chỉ là đường cú pháp được bao bọc trong thực tiễn tốt nhất, như đã lưu ý.

Trong ngày 2.x của Rails, khi chúng được gọi là "named_scope", chúng quan trọng hơn một chút. Chúng cho phép dễ dàng chuỗi các điều kiện để tạo truy vấn. Với những cải tiến trong Rails 3.x với Arel, thật đơn giản để tạo các hàm cho các quan hệ truy vấn, như bạn đã lưu ý. Phạm vi chỉ cung cấp một giải pháp đơn giản và thanh lịch cho các truy vấn được xác định trước, có thể định trước. Có tất cả các phạm vi ở đầu mô hình sẽ cải thiện khả năng đọc và giúp hiển thị cách sử dụng mô hình.

+0

Arel Tôi giả sử có nghĩa là ActiveRecord :: Quan hệ. ĐƯỢC. Các lợi ích cú pháp có vẻ gây tranh cãi với tôi. Nhưng nếu họ đã làm một cái gì đó mà các phương pháp tiêu chuẩn không thể làm trong các phiên bản trước đó thì giải thích nó. – Mark

+2

Với đường ray sử dụng cú pháp tốt hơn là quan trọng. Không dành cho cơ sở mã tại ngày 1 (hoặc thậm chí 100) nhưng đối với cơ sở mã tại ngày 1000. –

2

Vâng, chúng là các cú pháp ngắn gọn về cơ bản đại diện cho các phương pháp mà bạn đã tìm thấy.
Tại sao tốt hơn?
Hiệu ứng tức thời nhất là mã 2 dòng là cách dễ đọc hơn và duy trì hơn 9 dòng mã.

Đường ray luôn tìm cách tiếp cận DRY và tại đây, số lần lặp lại def self.method end lặp lại của mã thực tế.

+0

Nhờ bạn và Sean Hill để xác nhận rằng nó không phải là vấn đề về tốc độ. Liên kết railstutorial.org ở trên cụ thể bắt đầu nói rằng việc thực hiện thay thế của chúng bằng cách sử dụng phạm vi là bằng cách nào đó nhanh hơn, nhưng rõ ràng là không liên quan đến chúng bằng cách sử dụng phạm vi. – Mark

3

Khi bạn viết một phạm vi, về cơ bản nó cũng làm như vậy. Dưới đây là những gì các nguồn Rails trông giống như:

def scope(name, scope_options = {}) 
     name = name.to_sym 
     valid_scope_name?(name) 
     extension = Module.new(&Proc.new) if block_given? 

     scope_proc = lambda do |*args| 
     options = scope_options.respond_to?(:call) ? unscoped { scope_options.call(*args) } : scope_options 
     options = scoped.apply_finder_options(options) if options.is_a?(Hash) 

     relation = scoped.merge(options) 

     extension ? relation.extending(extension) : relation 
     end 

     singleton_class.send(:redefine_method, name, &scope_proc) 
    end 

Các lợi ích cho phạm vi trong trường hợp này là rằng họ là những con đường thành ngữ định nghĩa truy vấn, trong một số trường hợp ít dòng mã, và bạn có thể làm phần mở rộng.

Ví dụ trong nguồn trông như thế này:

scope :red, where(:color => 'red') do 
    def dom_id 
    'red_shirts' 
    end 
end 

nào cho phép bạn gọi Model.red.dom_id.

0

Có một vài sự khác biệt rất thú vị giữa phạm vi và phương thức lớp trả về quan hệ.

  1. Nó là dễ dàng hơn để đối phó với các thông số bằng không cho phạm vi với một param.present? kiểm tra đơn giản, đối với phương pháp lớp học mà bạn phải trả lại một cách rõ ràng mối quan hệ phi nil nếu một param sẽ gây ra một mối quan hệ không.

  2. Phạm vi dễ dàng mở rộng hơn so với phương pháp lớp học. Đơn giản chỉ cần vượt qua một khối (ví dụ để đối phó với phân trang) để thêm các phương pháp. Các phương thức lớp có thể được mở rộng nhưng không được thanh lịch.

Để toàn bộ tóm tắt xem this post from Plataformatec.

Các vấn đề liên quan