Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find old records that fail a new validation?

I recently found a problem in a Rails app related to duplicate entries in a join table. The app is educational, and includes models for Students and Exercises. The join table keeps track of which exercises have been assigned to which students. It doesn't make sense for an exercise to be assigned to a student more than once (i.e. duplicate entries in the join table shouldn't be allowed).

I partially fixed the problem by adding a uniqueness validation to the join table (see the last line of code, below). This validation will prevent any new duplicate entries from being created in the future. I'm still faced with the problem, however, of addressing the existing duplicates in the table.

Is there a way to run the new validation against the entire existing database, to retrieve all the records that are no longer valid?

class Student < ActiveRecord::Base
  has_many :student_exercise_assignments
  has_many :exercises, :through => :student_exercise_assignments
end

class Exercise < ActiveRecord::Base
  has_many :student_exercise_assignments
  has_many :students, :through => :student_exercise_assignments
end

class StudentExerciseAssignment < ActiveRecord::Base
    belongs_to :student
    belongs_to :exercise
    validates :exercise_id, :uniqueness => { :scope => :student_id, :message => "An exercise can only be assigned to a student once" }

UPDATE

Shioyama's answer below gives exactly the information I was looking for. Being a Rails newbie, though, I was a bit confused by his use of & in &:invalid?. If anyone needs an primer of the & operator in Ruby, there's a good one here.

like image 308
dB' Avatar asked Jan 27 '13 12:01

dB'


1 Answers

How about just:

invalid_assignments = StudentExerciseAssignment.select(&:invalid?)

This will select all assignments which return true when called with the invalid? method. You can then do whatever you need to do to fix them.

As a side note, I would also suggest adding a uniqueness constraint to your database. See this answer for reasons why: Rails: Validation in model vs migration

like image 116
Chris Salzberg Avatar answered Sep 21 '22 01:09

Chris Salzberg