Warum funktioniert eine Abfrage in Rails mit einem Limit nicht, wenn .all nicht am Ende steht?

9

Ich habe eine Abfrage wie folgt:

%Vor%

gibt ein Array von etwa 500 Datensätzen zurück - alle Datensätze in der Tabelle - d. h. die Limit-Klausel - werden ignoriert.

Aber wenn ich eine .all auf das Ende lege:

%Vor%

funktioniert und gibt 10 Datensätze zurück.

Dieser Code wird in einer Rake-Task ausgeführt, und ich verwende PostgreSQL, wenn das irgendeinen Unterschied macht.

Warum macht es das? Sicherlich sollte die .all nicht benötigt werden. Was vermisse ich?

    
Simon East 13.07.2011, 14:08
quelle

2 Antworten

6

Ich denke, das Verhalten hängt davon ab, wie Sie die Variable locations nach der Einstellung handhaben. Dies liegt daran, dass Location.order('id ASC').limit(10) keine Datensätze abfragt, aber ein Objekt vom Typ ActiveRecord::Relation zurückgibt. Die Abfrage wird nur ausgeführt, wenn Sie all , first , each , map usw. für dieses Objekt aufrufen.

Bei meinen Tests

%Vor%

gibt ein Array von 10 IDs zurück, wie Sie es erwarten würden. Aber

%Vor%

gibt die Gesamtzahl der Speicherorte in der Datenbank zurück, da SQL ausgeführt wird

%Vor%

gibt die vollständige Anzahl der Standortzeilen zurück (das Limit bezieht sich auf die Anzahl der zurückgegebenen Zeilen, nicht auf die Anzahl selbst).

Wenn Sie also das Ergebnis von Location.order('id ASC').limit(10) als Array behandeln, indem Sie es durchlaufen, sollten Sie dasselbe Ergebnis erhalten, als hätten Sie all hinzugefügt. Wenn Sie count aufrufen, werden Sie nicht. Irgendwie unglücklich, da ich denke, dass sie sich im Idealfall genauso verhalten sollten und man nicht wissen sollte, dass es sich um ein ActiveRecord::Relation handelt, anstatt um ein Array.

    
Mike A. 13.07.2011, 14:30
quelle
1

Ok, hier ist meine Erklärung Vor allem, wenn Sie Location.order('id ASC').limit(10).class haben, sehen Sie ActiveRecord::Relation next auf der Seite mit der Rails-API ActiveRecord::Relation nicht haben Sie eine Methode all , aber es enthält ActiveRecord::FinderMethods und wenn Sie dort suchen, finden Sie nächste

%Vor%

, so ruft es to_a method auf Wie in den railscasts erwähnt wurde, ist diese Methode als

definiert %Vor%

, so dass es eine SQL-Abfrage in einer dritten Zeile mit @records = eager_loading? ? find_with_associations : @klass.find_by_sql(arel.to_sql)

durchführt     
Bohdan 13.07.2011 14:32
quelle