Was ist der Unterschied zwischen Zupfen und Sammeln in Rails?

123

Hier sind zwei Beispielcodes.

Erster mit collect:

User.first.gifts.collect(&:id)

Zweiter mit pluck:

User.first.gifts.pluck(:id)

Gibt es einen Unterschied zwischen ihnen in der Leistung oder etwas anderem?

Mohit Jain
quelle

Antworten:

230

pluckist auf der DB-Ebene. Es wird nur das bestimmte Feld abgefragt. Sehen Sie das .

Wenn Sie das tun:

 User.first.gifts.collect(&:id)

Sie haben Objekte mit allen Feldern geladen und erhalten iddank der auf Enumerable basierenden Methode einfach den Dank.

So:

  • Wenn Sie nur die idmit Rails 4 benötigen , verwenden Sie ids:User.first.gifts.ids

  • Wenn Sie nur einige Felder mit Rails 4 benötigen, verwenden Sie pluck:User.first.gifts.pluck(:id, :name, ...)

  • Wenn Sie nur ein Feld mit Rails 3 benötigen, verwenden Sie pluck:User.first.gifts.pluck(:id)

  • Wenn Sie alle Felder benötigen , verwenden Siecollect

  • Wenn Sie einige Felder mit Rails 4 benötigen, verwenden Sie diese weiterhin pluck

  • Wenn Sie einige Felder mit Rails 3 benötigen, verwenden Sie selectundcollect

apneadiving
quelle
"Wenn Sie einige Felder benötigen, verwenden Sie selectand collect" - können Sie nicht einfach pluckmehrere Attribute verwenden, z pluck(:id, :name).
Alexander
@AlexPopov - Rails 4+ unterstützt pluckmehrere Felder, Rails 3 nicht, es sei denn, Sie verwenden die
Problemumgehung von
3
Wenn Sie in Rails 4 nur das benötigen id, verwenden Sie .idsRef doc: api.rubyonrails.org/classes/ActiveRecord/…
Ivan Chau
30

Ja. Nach Rails Guides , pluckwandelt direkt eine Datenbank Ergebnis in ein array, ohne die Konstruktion ActiveRecordObjekte. Dies bedeutet eine bessere Leistung für eine große oder häufig ausgeführte Abfrage.

Zusätzlich zur Antwort von @ apneadiving pluckkönnen sowohl einzelne als auch mehrere Spaltennamen als Argument verwendet werden:

Client.pluck(:id, :name)
# SELECT clients.id, clients.name FROM clients
# => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']]
Fremder
quelle
3

Der grundlegende und Hauptunterschied besteht darin, dass das Zupfen auf DB-Ebene angewendet wird und das Sammeln alle Daten abruft und dann den Datensatz an Sie zurückgibt, wenn Sie alle Datensätze benötigen, sammeln und wenn nur wenige Felder dann das Zupfen verwenden

Thorin
quelle
2

Wenn Sie in einem Fall nur wenige Attribute des abgerufenen Datensatzes verwenden. In solchen Fällen sollten Sie verwenden pluck.

User.collect(&:email)

Im obigen Beispiel, wenn Sie nur ein E-Mail-Attribut benötigen, verschwenden Sie Speicher und Zeit. Da alle Spalten aus der Benutzertabelle in der Datenbank abgerufen werden, wird der Speicher für alle Attribute zugewiesen (einschließlich der Attribute, die Sie niemals verwenden werden).

HINWEIS: Gibt pluckActiveRecord_Relation des Benutzers nicht zurück

Chimed Palden
quelle