Sự khác biệt giữa pluck và thu thập trong Rails là gì?


123

Đây là hai mã mẫu.

Người đầu tiên với collect:

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

Cái thứ hai với pluck:

User.first.gifts.pluck(:id)

Có sự khác biệt nào giữa chúng về hiệu suất hay điều gì khác không?

Câu trả lời:


230

pluckở mức db. Nó sẽ chỉ truy vấn trường cụ thể. Xem này .

Khi bạn làm:

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

Bạn có các đối tượng với tất cả các trường được tải và bạn chỉ cần nhận được idnhờ vào phương pháp dựa trên Enumerable.

Vì thế:

  • nếu bạn chỉ cần idvới Rails 4, hãy sử dụng ids:User.first.gifts.ids

  • nếu bạn chỉ cần một số trường với Rails 4, hãy sử dụng pluck:User.first.gifts.pluck(:id, :name, ...)

  • nếu bạn chỉ cần một trường với Rails 3, hãy sử dụng pluck:User.first.gifts.pluck(:id)

  • nếu bạn cần tất cả các trường, hãy sử dụngcollect

  • nếu bạn cần một số trường với Rails 4, vẫn sử dụng pluck

  • nếu bạn cần một số trường với Rails 3, hãy sử dụng selectcollect


"nếu bạn cần một số trường, hãy sử dụng select và collect" - bạn không thể chỉ sử dụng pluckvới nhiều thuộc tính, như thế pluck(:id, :name)nào?
Alexander

@AlexPopov - Rails 4+ hỗ trợ plucking nhiều lĩnh vực, Rails 3 không, trừ khi bạn sử dụng workaround Ryan Lefevre của
marksiemers

3
Trong Rails 4, nếu bạn chỉ cần id, hãy sử dụng .idstài liệu Tham khảo: api.rubyonrails.org/classes/ActiveRecord/…
Ivan Chau

30

Đúng. Theo hướng dẫn của Rails , pluckchuyển đổi trực tiếp kết quả cơ sở dữ liệu thành một đối tượng arraymà không cần xây dựng ActiveRecord. Điều này có nghĩa là hiệu suất tốt hơn cho một truy vấn lớn hoặc thường chạy.

Ngoài câu trả lời của @ apneadiving, pluckcó thể lấy cả tên cột và tên cột làm đối số:

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

3

Sự khác biệt cơ bản và chính là Pluck áp dụng ở cấp db và thu thập, lấy tất cả dữ liệu và sau đó trả lại bản ghi cho bạn khi bạn cần tất cả các bản ghi, sử dụng thu thập và khi ít trường thì sử dụng nhổ


2

Nếu có trường hợp bạn đang sử dụng ít thuộc tính của bản ghi đã truy xuất. Trong những trường hợp như vậy bạn nên sử dụng pluck.

User.collect(&:email)

Trong ví dụ trên nếu bạn chỉ cần thuộc tính email hơn là bạn đang lãng phí bộ nhớ và thời gian. Bởi vì nó sẽ truy xuất tất cả các cột từ bảng người dùng trong cơ sở dữ liệu, phân bổ bộ nhớ cho từng thuộc tính (bao gồm cả những thuộc tính mà bạn sẽ không bao giờ sử dụng)

LƯU Ý: pluckkhông trả về ActiveRecord_Relation của người dùng

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.