Skip to content

Instantly share code, notes, and snippets.

@jrafanie
Created June 28, 2019 21:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jrafanie/1924432d3508239299bb8afb69acf29a to your computer and use it in GitHub Desktop.
Save jrafanie/1924432d3508239299bb8afb69acf29a to your computer and use it in GitHub Desktop.
Hacky fix for rails 5.0.0-5.0.6 bloated serialized notification options with no longer existing constants causing bugs in rails 5.1
require_relative 'config/environment'
Notification.includes(:subject).all.each do |n|
begin
# Options could have no longer available activerecord/activemodel classes from rails 5.0.0 -> 5.0.6, which will raise an ArgumentError on deserialization
# Fixing these to use 5.0.7+ smaller serialization format without all the private attributes is too hard, especailly since you can only read their YAML strings
# and make changes as a string, not as a Hash.
opts = n.options
rescue ArgumentError
new_value = n.subject.try(:name) || n.subject.try(:description)
# We have no option but to blow away whatever was in options and set the subject information to what's in the associated subject object, even if it's been removed.
puts "Notification: #{n.id} options are not loadable, setting options[:subject] from subject association: #{n.subject_type}: #{n.subject_id} with value: #{new_value}"
# Must use update_all to avoid callbacks and checks on this instance.
n.class.where(:id => n.id).update_all(:options => {:subject => new_value})
next
else
begin
opts_subject = opts[:subject]
opts_subject.reload if opts_subject.respond_to?(:reload)
rescue ActiveRecord::RecordNotFound
# Options are readable. Options[:subject] is a AR::Base object but has been deleted, set the options[:subject] to the name or description
# from the association subject or the serialized options[:subject] object.
new_value = n.subject.try(:name) || n.subject.try(:description) || opts[:subject].name || opts[:subject].description
puts "Notification: #{n.id} subject, #{n.subject_type}: #{n.subject_id}, no longer exists, setting options[:subject] from serialized options: #{opts[:subject].class.name}[#{opts[:subject].id}] with new value: #{new_value}"
n.class.where(:id => n.id).update_all(:options => {:subject => new_value})
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment