2010-01-15 8 views
19

In meinem Post.rb Modell, ich habe default_scope :conditions => {:deleted => 'false'}Zwingende default_scope in Rails

Aber wenn ich versuche, Post.find(:all, :conditions => "deleted='false'") zu laufen, wird es nichts zurück. Es ist so, als hätte das default_scope Vorrang vor allem.

Ich will es so, dass, wenn ich Post.find() tun, es keine gelöschten Beiträge zurückgibt, aber ich würde auch gerne in der Lage sein, auf sie zuzugreifen, wenn ich muss. Was muss in meiner Abfrage oder in meinem Rails-Modell geändert werden?

Danke.

+0

'default_scope' * hat * Vorrang vor allem. Ich schrieb eine Antwort mit 'named_scope' auf Ihre vorherige Frage, die ich hier ebenfalls anwenden könnte: http://stackoverflow.com/questions/2073197/how-to-get-a-model-to-specify-a- pre-required-condition/2073858 # 2073858 – jerhinesmith

Antwort

17

with_exclusive_scope ist protected, so haben Sie eine Klassenmethode zu erstellen:

def self.include_deleted_in 
    Event.with_exclusive_scope { yield } 
end 

dann in Ihrem Controller Anruf

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

+1; Danke - beste Antwort die ich im Netz gefunden habe – Makibo

+0

Event.with_exclusive_scope {yield} hat bei mir nicht funktioniert, ich musste Post.with_exclusive_scope {yield} setzen. Wie auch immer, gute Antwort. Rette mein Leben heute. – workdreamer

1

Verwendung with_exclusive_scope

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

Mit diesem (außerhalb des Post-Modells) ergibt sich: geschützte Methode 'with_exclusive_scope 'aufgerufen für # intepid

+0

Sie können' Post.send (: with_exclusive_scope) {.. .} ' –

1

Scopes sollen zusammensetzbare sein, das heißt, Sie ein paar von ihnen verbinden kann und es wirksam anwendet alle Bedingungen. In diesem Fall ist ActiveRecord einfach zu naiv, um zu bestimmen, dass die explizite Bedingung die erste negieren sollte. Es erstellt nur die Abfrage, die alle Klauseln mit ANDs verbindet. Aus diesem Grund hat default_scope das meiste Dienstprogramm mit den: order -Klauseln, die nicht zusammensetzbar sind (in der Implementierung von ActiveRecord 2.3 sowieso). Es gibt mehr Diskussion here.

Beachten Sie auch, dass ActiveRecord in Rails 3 Arel für eine Vielzahl von Abfragekonstruktion verwendet, die die Leistung der ActiveRecord Query Generation stark erhöhen wird, während viele Interna vereinfacht werden. Es ist wahrscheinlich, dass Arel Ihre Situation verbessern wird. In der Zwischenzeit empfehle ich, keine Bedingungen in ein default_scope zu setzen, es sei denn, es gibt Zeilen, die für Ihre Rails-App wirklich unsichtbar sein sollen.

60

Dieser war irgendwie links versteckt :)

Verwenden Sie einfach Post.unscoped.where(:deleted => true), wenn Sie Rails 3

verwenden 10

Kredit geht zu José Valim dafür.

+0

Scheint nicht zu funktionieren, wenn das default_scope eine: order-Klausel hat und diese überschrieben werden soll. – Zabba

+2

Zabba, das war genau mein Fall und das funktionierte einwandfrei für mich. Danke Edgerunner. – taelor

+0

@ Zabba, verwenden Sie 'reorder' für das – edgerunner