2010-09-17 37 views
16

Sự cố sau:
Tôi cần một thứ gì đó giống như phạm vi trống. Điều này có nghĩa là phạm vi này là emtpy, nhưng đáp ứng tất cả các phương thức mà một phạm vi thường trả lời. Tôi hiện đang sử dụng một chút hack bẩn. Tôi chỉ đơn giản cung cấp "1 = 0" làm điều kiện. Tôi thấy điều này thực sự xấu xí, vì nó truy cập cơ sở dữ liệu. Chỉ cần trả về một mảng trống sẽ không hoạt động, vì kết quả phải trả lời cho các phương thức có phạm vi.Phạm vi trống với Ruby on Rails

Có giải pháp hiện tại nào tốt hơn cho điều này hay tôi sẽ cần tự viết mã này?

Có lẽ một số mã ví dụ có thể giúp giải thích những gì tôi cần:


class User < ActiveRecord::Base 
    named_scope :admins, :conditions => {:admin => true } 
    named_scope :none_dirty, :conditions => "1=0" # this scope is always empty 

    def none_broken 
    [] 
    end 

    def self.sum_score # okay, a bit simple, but a method like this should work! 
    total = 0 
    self.all.each do |user| 
     total += user.score 
    end 
    return total 
    end 
end 
User.admin.sum_score # the score i want to know 
User.none_drity.sum_score # works, but hits the db 
User.none_broken.sum_score # ...error, since it doesn't respond to sum_score 
+0

Tại sao điểm số của tập trống rỗng là bất kỳ điều gì khác hơn 0? Bạn đang cố gắng làm gì ở đây? – jdl

+1

Bạn đang tìm kiếm một bộ sưu tập trống. – Swanand

+0

@jdl: nó không phải là thứ gì khác ngoài 0. – Baju

Trả lời

0

Điều bạn đang tìm kiếm không tồn tại. Bạn có thể thực hiện một cái gì đó như thế này bằng cách monky vá phương pháp find. Tuy nhiên, điều này sẽ là một overkill, vì vậy tôi khuyên bạn nên giữ điều này, trừ khi nó hiệu suất quan trọng.

0

tôi điều bạn cần User.scoped({})

+0

'User.scoped ({})' có tương đương với 'User.all' không? – Swanand

+0

Nó không phải là tuyệt đối tương đương, nhưng nó không hoạt động. – Baju

+0

@Swanand: chúng không tương đương, 'scoped' trả về một' ActiveRecord :: NamedScope :: Scope' trong khi 'User.all' trả về một mảng. – tokland

2

Xin lỗi User.scoped không phải là thứ bạn muốn. Như nhận xét này trả về tất cả mọi thứ. Nên chú ý nhiều hơn đến câu hỏi.

Tôi đã xem where('1 = 0') được đề xuất trước và Rails có lẽ cũng nên lưu vào bộ nhớ cache.

Ngoài ra, where('1 = 0') sẽ không nhấn vào cơ sở dữ liệu cho đến khi bạn thực hiện .all, .each hoặc một trong các phương pháp tính toán.

+1

'User.scoped' trả về tất cả người dùng, vì vậy nó không thực sự là một phạm vi" trống ". Tôi nghĩ anh ấy có nghĩa là một phạm vi trống sẽ không trả lại người dùng nào. Sắp xếp tương đương với [] nhưng phạm vi. –

0

Làm thế nào về User.where(id: nil)?

Hoặc User.where(_id: nil) cho mongoid.

+0

Điều đó vẫn sẽ nhấn vào cơ sở dữ liệu và nó không đáng tin cậy (Có thể có một bản ghi với một trường id null đặc biệt là các cơ sở dữ liệu cũ, không phải Rails). – PhilT

-1

Nhìn vào ví dụ mã của bạn cho thấy bạn có thể không biết về các truy vấn tổng hợp trong SQL được tiếp xúc như các phương pháp tính toán trong Rails:

User.sum(:score) sẽ cung cấp cho bạn tổng điểm tất cả người dùng

Hãy xem tại Rails Hướng dẫn cho biết thêm:

http://guides.rubyonrails.org/active_record_querying.html#sum

+0

Ehm, không, tổng chỉ là một ví dụ như đã nêu ở trên – Baju

11
User.where('false') 

trả Active Record :: Quan hệ với các phần tử zero, đó là một phạm vi chuỗi có khả năng sẽ không nhấn vào cơ sở dữ liệu cho đến khi bạn thực sự cố gắng truy cập vào một trong các phần tử của nó. Điều này tương tự như giải pháp của PhilT với ('1 = 0') nhưng thanh lịch hơn một chút.

+0

Mặt khác, nơi ('false') không hoạt động với SQLite, và '1 = 0' không ... –

18

Rails 4 giới thiệu phạm vi none.

Nó sẽ được sử dụng trong trường hợp bạn có phương thức trả về một quan hệ, nhưng có một điều kiện mà bạn không muốn truy vấn cơ sở dữ liệu.

Nếu bạn muốn có một phạm vi để trả lại một phạm vi sử dụng không thay đổi gì all:

Không còn sẽ một cuộc gọi đến Model.all thực hiện một truy vấn ngay lập tức và trả về một mảng các bản ghi. Trong Rails 4, các cuộc gọi đến Model.all tương đương với việc không được dùng nữa Model.scoped.Điều này có nghĩa là nhiều mối quan hệ hơn có thể bị xích vào Model.all và kết quả sẽ được đánh giá một cách lười biếng.