Reputation: 5435
I've got the following models:
class Grade
belongs_to :student
end
class Student
has_many :grades
end
How can I find out which grades have students which have been deleted? In other words, I want to make a query which returns basically what I'm doing in the next line of code
Grade.all - Grade.joins(:student)
Is it possible? Thanks!
Upvotes: 1
Views: 692
Reputation: 18672
You're looking for this query:
Grade.includes(:student).references(:student).where('students.id IS NULL')
This seems very cumbersome from a data integrity perspective though. Either grades.student_id
should be nullified when a student is deleted, or it should be deleted altogether.
This can be managed easily by setting foreign keys constraints in your database. A nifty gem for this is foreigner. Foreign keys will also be part of the upcoming Rails 4.2 release.
If grades should still continue to exist even though a student is deleted, you can set a foreign key which sets grades.student_id
for that student to NULL
:
# Foreigner
add_foreign_key :grades, :students, dependent: :nullify
# Rails 4.2
add_foreign_key :grades, :students, on_delete: :nullify
You don't need to do anything special for this, the database will take care of cleaning up. If you then want to find grades without students, you can simply run this query:
Grade.where(student: nil)
If grades should be deleted when a student is being deleted, you can add this foreign key:
# Foreigner
add_foreign_key :grades, :students, dependent: :delete
# Rails 4.2
add_foreign_key :grades, :students, on_delete: :cascade
Upvotes: 2