2016-04-21 3 views
0

In meinem Verständnis sollten die folgenden Ruby-Ausdrücke das gleiche Ergebnis liefern.
offenbar etwas, was ich bin fehlt, ist dies eine viel zu ernste Fehler unbemerkt zu gehen ...Array-Elemente in Ruby zählen (unerwartete Ergebnisse durch die Funktion count())

# returns the number of ALL elements in the array 
count = @quotation.quotation_items.count { |x| x.placement == current_placement} 

# Does what I expect 
count = (@quotation.quotation_items.find_all { |x| x.placement == current_placement }).length 

quotation_items oben ist ein has_many Active Verein

Antwort

2

#count einen Block wie das nicht nehmen.

Wenn Sie auf einer Zählung Bedingungen verwenden möchten, würden Sie tun:

@quotation.quotation_items.count(:conditions => "placement = #{current_placement}") 

http://apidock.com/rails/ActiveRecord/Calculations/ClassMethods/count

+0

Ich dachte ActiveRecords Verbände implementieren das Enumerable Protokoll ... –

+1

ist es CollectionAssociation Methode, nicht Berechnung (siehe Link) – Ilya

+0

Die ActiveRecord Anzahl löst immer eine SELECT COUNT (...) auf der db - es ist nicht das gleiche wie Die Enumerable # count – mccalljt

0

Ihre Nutzung von #count falsch ist.

Ich glaube, es akzeptiert keinen Block. Ich bin mir nicht sicher, warum es keinen Fehler zurückgegeben hat.

können Sie es wie folgt verwenden:

count = @quotation.quotation_items.map{ |x| x.placement == current_placement}.count(true)

1

Wenn Sie Active verwenden Sie im Auge behalten müssen, dass es einen Punkt gibt, wo es Bedingungen und Klauseln für eine Abfrage und einen Punkt zusammenzustellen, wo Sie habe ein Ergebnis gesetzt. Bestimmte Dinge funktionieren nur in dem einen oder dem anderen Modus, obwohl es versucht, die Dinge ziemlich konstant zu halten.

In Ihrem Fall erwarten Sie count wie Enumerable arbeiten, aber das ist immer noch ein Operator auf Datenbankebene.

das beheben:

@quotation.quotation_items.where(placement: current_placement).count 

, dass eine Abfrage komponiert, die nur die Dinge, zählt man braucht, etwas annähernde:

SELECT COUNT(*) FROM quotation_items WHERE quotation_id=? AND placement=? 

Das ist etwas, das eine einzige Zahl ergibt und ist wesentlich anders als die Auswahl Jeder Datensatz wird in Modelle instanziiert und dann mit Enumerable gezählt.