Jaka jest różnica między pluck i collect in Rails?

123

Oto dwa przykładowe kody.

Pierwsza z collect:

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

Drugi z pluck:

User.first.gifts.pluck(:id)

Czy jest jakaś różnica między nimi w działaniu, czy coś innego?

Mohit Jain
źródło

Odpowiedzi:

230

pluckjest na poziomie db. Będzie sprawdzać tylko określone pole. Zobacz to .

Kiedy robisz:

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

Masz obiekty z załadowanymi wszystkimi polami i po prostu otrzymujesz idpodziękowania dzięki metodzie opartej na Enumerable.

Więc:

  • jeśli potrzebujesz tylkoid z Rails 4, użyj ids:User.first.gifts.ids

  • jeśli potrzebujesz tylko niektórych pól w Rails 4, użyj pluck:User.first.gifts.pluck(:id, :name, ...)

  • jeśli potrzebujesz tylko jednego pola z Rails 3, użyj pluck:User.first.gifts.pluck(:id)

  • jeśli potrzebujesz wszystkich pól, użyjcollect

  • jeśli potrzebujesz pól w Rails 4, nadal używaj pluck

  • jeśli potrzebujesz pól z Railsami 3, użyj selecticollect

bezdechu
źródło
„jeśli potrzebujesz niektórych pól, użyj funkcji select and collect” - czy nie możesz po prostu użyć pluckwielu atrybutów, na przykład pluck(:id, :name)?
Alexander
@AlexPopov - Rails 4+ obsługują pluckwiele pól, Rails 3 nie, chyba że użyjesz obejścia Ryana
Lefevre'a
3
W Rails 4, jeśli potrzebujesz tylkoid , użyj .idsRef doc: api.rubyonrails.org/classes/ActiveRecord/…
Ivan Chau
30

Tak. Zgodnie z przewodnikami Railsów , pluckbezpośrednio konwertuje wynik bazy danych na plik array, bez konstruowania ActiveRecordobiektów. Oznacza to lepszą wydajność w przypadku dużych lub często wykonywanych zapytań.

Oprócz odpowiedzi @ apneadiving pluckjako argument może przyjmować zarówno nazwy jednej, jak i wielu kolumn:

Client.pluck(:id, :name)
# SELECT clients.id, clients.name FROM clients
# => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']]
Kolega nieznajomy
źródło
3

Podstawowa i główna różnica polega na tym, że Pluck działa na poziomie db i zbieraj, pobierz wszystkie dane, a następnie zwróć rekordy, gdy potrzebujesz wszystkich rekordów, użyj zbierania, a gdy kilka pól, użyj pluck

Thorin
źródło
2

Jeśli jest przypadek, w którym używasz kilku atrybutów pobranego rekordu. W takich przypadkach powinieneś użyć pluck.

User.collect(&:email)

W powyższym przykładzie, jeśli potrzebujesz tylko atrybutu e-mail, to marnujesz pamięć i czas. Ponieważ pobierze wszystkie kolumny z tabeli użytkowników w bazie danych, przydziela pamięć dla każdego atrybutu (w tym atrybutów, których nigdy nie użyjesz)

UWAGA: plucknie zwraca ActiveRecord_Relation użytkownika

Chimed Palden
źródło