2013-07-02 7 views
9

Ich versuche, eine Abfrage zu erstellen wie folgt ausführen zu müssen:eine Active Beziehung Gebäude, ohne dass die Abfrage

rel = article.where(version: 'some_version') 
      .joins(:categories) 
      .merge(Category.where(:uuid => 'some_cat_uuid')) 

articles = rel.where(published: true).limit(10) 
# etc. 

Das Problem ist die erste Abfrage, egal auszuführen scheint, was ich tue. Mache ich etwas falsch?

+0

Umm, du bist zweite Variable 'articles' verwendet Ihre erste Variable' rel'. Natürlich wird es diese Abfrage jedes Mal ausführen! –

+2

@n_i_c_k wie? Sie können Arel-Anfragen wie diese gut ketten. Ich vermute, dass die Ausführung der Abfrage geschieht, weil dieser '.merge' ... – nzifnab

+3

Scratch, dass' .merge' sollte die Abfrage nicht ausführen. Machst du das in der Konsole? – nzifnab

Antwort

13

Wenn Sie Befehle in der Konsole ausführen, fügt automatisch etwas ähnliches wie .inspect am Ende der Ergebnisse des Befehls anzuzeigen. Zum Beispiel (das ist in meiner Anwendung, die ich arbeite jetzt):

irb(main):061:0> Job.where(id: 251000) 
    Job Load (3.8ms) SELECT "jobs".* FROM "jobs" WHERE "jobs"."deleted_at" IS NULL AND "jobs"."id" = 251000 
=> [#<Job id: 251000, {...}>] 

Also, Ihre erste Zeile des Codes ist gut und würde die Abfrage normalerweise nicht ausführen, aber da Sie liefen sie in Die Konsole wird sofort ausgeführt, damit sie die Ergebnisse für Sie anzeigen kann.

Eine Möglichkeit, dies zu umgehen, ist das Hinzufügen von ; nil am Ende des Befehls, damit die Konsole nicht versucht, die Ergebnisse anzuzeigen (es wird nur NIL als Ergebnis dieser Zeile angezeigt. IE:

irb(main):062:0> Job.where(id: 251000); nil 
=> nil 

es auf diese Weise tun, sollten Sie tun, was Sie in der Lage erwartet hatten (Verzögerung Ausführung der Abfrage, bis Sie tatsächlich die Ergebnisse müssen):

rel = article.where(version: 'some_version') 
      .joins(:categories) 
      .merge(Category.where(:uuid => 'some_cat_uuid')); nil 

articles = rel.where(published: true).limit(10); nil 

Dann können Sie die Abfrage ausführen, indem articles.all mit (in Rails 3) oder articles.to_a (in Rails 4)

Natürlich, wenn Sie diesen Code an einem Rechen Aufgabe oder Modell oder etwas bewegen können Sie diese ; nil Bits gelöscht werden, da sie an diesem Punkt ein wenig unübersichtlich und wäre nutzlos aussehen.

Ein weiterer Streitpunkt für die Konsole könnte sein, dass es an diesem Punkt, dass .where() {NEWLINE} und führen Sie die Abfrage sehen werde, neige ich dazu, den Punkt in der vorhergehenden Zeile zu setzen jede Zweideutigkeit zu entfernen, wo mein Befehl endet:

rel = article.where(version: 'some_version'). 
      joins(:categories). 
      merge(Category.where(:uuid => 'some_cat_uuid')); nil 
+0

Perfekt. Dank – rainkinz

+3

Es scheint, dass dies funktioniert nur mit [Activerecord :: QueryMethods] (http://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html) ('where',' joins', 'Group', etc.) . Es funktioniert NICHT mit [ActiveRecord :: FinderMethods] (http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html) ('first',' find', 'find_by', etc.). Die 'FinderMethods' führen die Abfrage sofort aus, unabhängig vom '; keine Syntax. – jhirsch

+1

@Crazydog ja, aber das ist, weil die sind nicht faul belasteten Methoden. Diese Methoden werden sofort geladen, unabhängig davon, wo sie ausgeführt werden. – nzifnab