การทำการรวมภายในกับตาราง has_many รวมกับ a group
หรือuniq
อาจไม่มีประสิทธิภาพมากและใน SQL สิ่งนี้จะนำไปใช้งานได้ดีกว่าในรูปแบบการรวมกึ่งที่ใช้EXISTS
กับเคียวรีย่อยที่สัมพันธ์กัน
สิ่งนี้ช่วยให้เครื่องมือเพิ่มประสิทธิภาพการสืบค้นสามารถตรวจสอบตารางตำแหน่งงานว่างเพื่อตรวจสอบการมีอยู่ของแถวที่มี project_id ที่ถูกต้อง ไม่สำคัญว่าจะมี 1 แถวหรือ 1 ล้านที่มี project_id นั้น
นั่นไม่ตรงไปตรงมาใน Rails แต่สามารถทำได้ด้วย:
Project.where(Vacancies.where("vacancies.project_id = projects.id").exists)
ในทำนองเดียวกันค้นหาโครงการทั้งหมดที่ไม่มีตำแหน่งงานว่าง:
Project.where.not(Vacancies.where("vacancies.project_id = projects.id").exists)
แก้ไข: ใน Rails เวอร์ชันล่าสุดคุณจะได้รับคำเตือนเกี่ยวกับการเลิกใช้งานโดยบอกให้คุณไม่ต้องพึ่งพาexists
การมอบหมายให้ arel แก้ไขปัญหานี้ด้วย:
Project.where.not(Vacancies.where("vacancies.project_id = projects.id").arel.exists)
แก้ไข: หากคุณไม่สบายใจกับ SQL ดิบให้ลอง:
Project.where.not(Vacancies.where(Vacancy.arel_table[:project_id].eq(Project.arel_table[:id])).arel.exists)
คุณสามารถทำให้สิ่งนี้ยุ่งน้อยลงได้โดยการเพิ่ม class method เพื่อซ่อนการใช้งานarel_table
ตัวอย่างเช่น:
class Project
def self.id_column
arel_table[:id]
end
end
... งั้น ...
Project.where.not(
Vacancies.where(
Vacancy.project_id_column.eq(Project.id_column)
).arel.exists
)