2009-01-04 24 views
12

Rails-Gurus: Ich habe gerade named_scope dank eines anderen SO-Benutzers entdeckt. :)Verwenden von named_scope zum Abrufen der Zeilenanzahl

Ich möchte die Anzahl einer Reihe von Zeilen erhalten - d. H. Eine SELECT COUNT(*). Darüber hinaus möchte ich weiterhin in dem Aufruf benannte Bereiche verketten können.

Ist das eine legitime (wenn auch seltsame) Verwendung des benannten Bereichs?

named_scope :count, :select => "COUNT(*) as count_all" 

So dann kann ich (zum Beispiel) tun:

@foobar = Foobar.count.scope.scope.scope 

Die Zählung über @foobar.first.count_all zugegriffen wird.

(Edited Allans Kommentare zu adressieren)

Sie tun können:

@foobar = Foobar.scope.scope.scope.size 

Dies würde aber dazu führen, ein Ergebnis Abfrage und nicht die schnellere SELECT COUNT(*) Abfrage. Ich habe eine große Anzahl von Zeilen in der Datenbank, die ich abfrage.

Gibt es einen besseren Weg, dies zu tun?

Antwort

20

Die Funktionalität Sie suchen in gebaut

Foobar.count # SELECT count(*) AS count_all FROM "foobars" 
Foobar.named_scope.count # SELECT count(*) AS count_all FROM "foobars" WHERE .... 

Wenn Sie script/server im Dev-Modus ausführen, sehen Sie die Abfragen, wie sie ausgeführt werden.

+3

Duh. Manchmal sind die Dinge in Schienen so einfach, dass ich das Offensichtliche vermisse. Vielen Dank! – unknownuser

+0

Bitte korrigieren Sie mich, wenn ich arbeite, aber das scheint nicht zu funktionieren, wenn Ihr benannter Bereich ungefähr so ​​aussieht: def self.with_full_name select ("Benutzer. *, CONCAT (Vorname, Nachname) AS full_name") Ende –

2

Ich glaube nicht, dass das überhaupt richtig ist. Bereiche werden verwendet, um Suchanweisungen zu verfeinern, und die Zählwertabfrage wird mit diesen nicht gut funktionieren.

2

Es gibt einen besseren Weg, dies zu tun, Schienen gibt Ihnen schon die Mittel.

Arbeiten mit dem Beispiel, könnten Sie dies nur tun:

@foobar_size = Foobar.all.size #returns integer equal to total rows of Foobar 

und sogar Umfang es etwa so:.

@banned_foobars = Foobar.scope_to_find_banned.size #returns integer equal to total rows for "scope_to_find_banned" 
+0

Das habe ich ursprünglich versucht. Das Problem dabei ist, dass es die Tatsache nicht ausnutzt, dass SELECT COUNT (*) eine relativ schnelle Abfrage ist. Es würde eine Zeilenabfrage machen und ist viel langsamer. – unknownuser

+0

Ah! Ich verstehe was du meinst. Bitte verzeihen Sie mein Missverständnis. –

Verwandte Themen