Data migration scripts should take into account recently introduced delegations

This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the databases category.

Last Updated: 2024-03-28

Originally I had NotesFile with sample_text column. I eventually added a new record, ExtractedText which was joined to a NotesFile and would become the new owner of the sample_text column.

# rewritten NotesFile class
has_one :extracted_txt
delegate :sample_text, to: :extracted_text

Now, I came to the problem of actually transitioning the data: The plan was to keep a duplicate copy of the sample_text on the notes file table (its original home) and migrate using this snippet:

NotesFile.all.each do |nf|
  nf.create_extracted_text!(
    sample_text: nf.sample_text,
  )
end

It failed however, saying the extracted_text was nil. Huh!

This error turned out to be spot on. Why? Because I was expecting the sample_text method, which previously just accessed the database on the notes file itself, to continue being able to see that data, even though I had just rewriten it to delegate to the extracted_text object.

The fix was to access the data directly

NotesFile.all.each do |nf|
  nf.create_extracted_text!(
    sample_text: nf.attributes["sample_text"],
  )
end