sauronnikko
sauronnikko

Reputation: 5435

Rails 4: Get records which join association record has been deleted

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

Answers (1)

fivedigit
fivedigit

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

Related Questions