2010-01-15 19 views
19

Trong mô hình Post.rb tôi, tôi có default_scope :conditions => {:deleted => 'false'}default_scope Overriding trong Rails

Nhưng nếu tôi cố gắng chạy Post.find(:all, :conditions => "deleted='false'"), nó sẽ không trở lại bất cứ điều gì. Nó giống như default_scope được ưu tiên hơn mọi thứ.

Tôi muốn nó để khi tôi làm Post.find() nó không trả lại bài đăng đã xóa, nhưng tôi cũng muốn có thể truy cập chúng nếu tôi cần. Những gì cần phải được thay đổi trong truy vấn của tôi hoặc mô hình Rails của tôi?

Cảm ơn.

+0

'default_scope' * không * được ưu tiên hơn mọi thứ. Tôi đã viết một câu trả lời bằng cách sử dụng 'named_scope' cho câu hỏi trước của bạn mà tôi nghĩ rằng sẽ được áp dụng ở đây là tốt: http://stackoverflow.com/questions/2073197/how-to-get-a-model-to-specify-a- Điều kiện tiên quyết/2073858 # 2073858 – jerhinesmith

Trả lời

17

with_exclusive_scopeprotected, vì vậy bạn phải tạo ra một phương pháp học:

def self.include_deleted_in 
    Event.with_exclusive_scope { yield } 
end 

sau đó trong cuộc gọi điều khiển của bạn

Post.include_deleted_in { Post.find(:all) } 
+0

+1; Cảm ơn - câu trả lời hay nhất tôi tìm thấy trong net – Makibo

+0

Event.with_exclusive_scope {yield} không hoạt động đối với tôi, tôi phải đặt Post.with_exclusive_scope {yield}. Dù sao câu trả lời tuyệt vời. Cứu mạng tôi hôm nay. – workdreamer

1

sử dụng with_exclusive_scope

Post.with_exclusive_scope { Post.find(:all) } 
+0

Sử dụng mô hình này (bên ngoài Mô hình bài đăng) dẫn đến: phương pháp được bảo vệ 'with_exclusive_scope 'được gọi là # intepid

+0

Bạn có thể sử dụng' Post.send (: with_exclusive_scope) {.. .} ' –

1

Scopes có nghĩa là để được composable, nghĩa là bạn có thể kết hợp một bó của họ và nó có hiệu quả áp dụng tất cả các điều kiện. Trong trường hợp này ActiveRecord chỉ là quá ngây thơ để xác định rằng điều kiện rõ ràng nên phủ nhận cái đầu tiên. Nó chỉ xây dựng truy vấn tham gia tất cả các mệnh đề với AND. Vì lý do này default_scope có nhiều tiện ích nhất với: mệnh đề thứ tự mà không phải là composable (trong triển khai ActiveRecord 2.3 anyway). Có nhiều cuộc thảo luận hơn here. Cũng cần lưu ý rằng trong Rails 3 ActiveRecord đang sử dụng Arel cho rất nhiều công trình truy vấn sẽ làm tăng đáng kể sức mạnh của việc tạo truy vấn ActiveRecord trong khi đơn giản hóa rất nhiều nội bộ. Có khả năng là với Arel sẽ cải thiện tình hình của bạn. Trong thời gian chờ đợi, tôi khuyên bạn không nên đặt điều kiện trong default_scope trừ khi có những hàng mà bạn thực sự muốn ẩn với ứng dụng Rails của mình.

60

Kẻ nầy đã bằng cách nào đó trái ẩn :)

Chỉ cần sử dụng Post.unscoped.where(:deleted => true), nếu bạn đang sử dụng Rails 3

Tín dụng chuyển đến José Valim cho việc này.

+0

Dường như không hoạt động khi default_scope có một mệnh đề: order và bạn muốn ghi đè điều đó. – Zabba

+2

Zabba, đó là chính xác trường hợp của tôi và điều này làm việc hoàn hảo cho tôi. cảm ơn edgerunner. – taelor

+0

@Zabba, sử dụng 'sắp xếp lại' cho rằng – edgerunner