นี่คือรหัสตัวอย่างสองรหัส
คนแรกกับcollect
:
User.first.gifts.collect(&:id)
อันที่สองกับpluck
:
User.first.gifts.pluck(:id)
มีความแตกต่างระหว่างประสิทธิภาพหรืออย่างอื่นหรือไม่?
นี่คือรหัสตัวอย่างสองรหัส
คนแรกกับcollect
:
User.first.gifts.collect(&:id)
อันที่สองกับpluck
:
User.first.gifts.pluck(:id)
มีความแตกต่างระหว่างประสิทธิภาพหรืออย่างอื่นหรือไม่?
คำตอบ:
pluck
อยู่ในระดับฐานข้อมูล มันจะสอบถามเฉพาะฟิลด์ใดฟิลด์หนึ่ง เห็นนี้
เมื่อคุณทำ:
User.first.gifts.collect(&:id)
คุณมีวัตถุที่โหลดทุกช่องและคุณจะได้รับไฟล์ id
ขอบคุณจากวิธีการที่อิงจาก Enumerable
ดังนั้น:
หากคุณต้องการเพียงid
Rails 4 ให้ใช้ids
:User.first.gifts.ids
หากคุณต้องการเพียงบางฟิลด์ที่มี Rails 4 ให้ใช้pluck
:User.first.gifts.pluck(:id, :name, ...)
ถ้าคุณเพียงต้องการข้อมูลหนึ่งที่มีทางรถไฟที่ 3 การใช้งานpluck
:User.first.gifts.pluck(:id)
หากคุณต้องการทุกช่องให้ใช้collect
หากคุณต้องการบางฟิลด์ที่มี Rails 4 ให้ใช้ไฟล์ pluck
หากคุณต้องการบางฟิลด์ที่มี Rails 3 ให้ใช้select
และcollect
pluck
ข้อมูลหลายช่อง Rails 3 ไม่ทำเว้นแต่คุณจะใช้วิธีแก้ปัญหาของ Ryan Lefevre
id
ใช้.ids
Ref doc: api.rubyonrails.org/classes/ActiveRecord/…
ใช่. ตามคำแนะนำของทางรถไฟ , pluck
โดยตรงแปลงผลฐานข้อมูลเป็นarray
โดยไม่มีการสร้างActiveRecord
วัตถุ ซึ่งหมายถึงประสิทธิภาพที่ดีขึ้นสำหรับแบบสอบถามขนาดใหญ่หรือที่เรียกใช้บ่อย
นอกจากคำตอบของ @ apneadiving แล้วpluck
ยังสามารถใช้ชื่อคอลัมน์เดียวและหลายคอลัมน์เป็นอาร์กิวเมนต์ได้:
Client.pluck(:id, :name)
# SELECT clients.id, clients.name FROM clients
# => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']]
ความแตกต่างพื้นฐานและหลักคือ Pluck ใช้กับระดับฐานข้อมูลและรวบรวมรับข้อมูลทั้งหมดจากนั้นส่งคืนบันทึกให้คุณเมื่อคุณต้องการบันทึกทั้งหมดใช้การรวบรวมและเมื่อไม่กี่ฟิลด์ให้ใช้การถอน
หากมีบางกรณีที่คุณกำลังใช้แอตทริบิวต์เพียงไม่กี่รายการของเรกคอร์ดที่ดึงมา pluck
ในกรณีดังกล่าวที่คุณควรใช้
User.collect(&:email)
ในตัวอย่างข้างต้นหากคุณต้องการเพียงแอตทริบิวต์อีเมลมากกว่าที่คุณจะเสียหน่วยความจำและเวลา เนื่องจากจะดึงข้อมูลคอลัมน์ทั้งหมดจากตารางผู้ใช้ในฐานข้อมูลจัดสรรหน่วยความจำสำหรับแต่ละแอตทริบิวต์ (รวมถึงแอตทริบิวต์ที่คุณจะไม่ใช้)
หมายเหตุ: pluck
ไม่ส่งคืน ActiveRecord_Relation ของผู้ใช้
pluck
กับหลายแอตทริบิวต์pluck(:id, :name)
ไม่ได้หรือ?