Created
May 18, 2017 20:03
-
-
Save rzane/6ac18ddaa646a4d2be618e6e06008a7b to your computer and use it in GitHub Desktop.
Fix deprecated ActiveModel::Dirty methods for Active Record 5.1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class After < Struct.new(:text) | |
def call | |
text.gsub(Model::FIXES[0], 'saved_change_to_\1?') | |
.gsub(Model::FIXES[1], '\1_before_last_save') | |
end | |
end | |
class Before < Struct.new(:text) | |
def call | |
text.gsub(Model::FIXES[0], 'will_save_change_to_\1?') | |
.gsub(Model::FIXES[1]) { raise "Failed to convert: #{line}" } | |
end | |
end | |
class Model | |
attr_reader :file | |
FIXES = [ | |
/(\w+)_changed\?/, | |
/(\w+)_was/ | |
] | |
def initialize(file) | |
@file = file | |
end | |
def solve | |
fixed_lines = File.readlines(file).reduce([]) do |acc, line| | |
fixed = fix(line, acc) if needs_fix?(line) | |
if fixed && commit?(line, fixed) | |
acc + [fixed.call] | |
else | |
acc + [line] | |
end | |
end | |
File.open(file, 'w') { |f| f.write(fixed_lines.join) } | |
end | |
def needs_fix?(line) | |
FIXES.any? { |re| line.match? re } | |
end | |
def commit?(line, fixed) | |
puts "FILE: #{file}" | |
puts "CALLBACK: #{fixed.class.to_s.downcase}_*" | |
puts "CHANGE: #{line}" | |
puts "TO: #{fixed.call}" | |
loop do | |
print 'Replace? (y/n): ' | |
answer = $stdin.gets.chomp | |
next unless answer.match?(/[yn]/i) | |
puts "\n" | |
break answer.match?(/y/i) | |
end | |
end | |
def fix(text, previous_lines) | |
find_solution(text, previous_lines) | |
end | |
def find_solution(text, previous_lines) | |
(previous_lines + [text]).reverse.each do |line| | |
case line | |
when /after_(create|update|save|destroy)/ | |
return After.new(text) | |
when /before_(create|update|save|destroy)/ | |
return Before.new(text) | |
when /def ([\w?]+)/ | |
return find_def_solution(Regexp.last_match[1], text, previous_lines) | |
end | |
end | |
nil | |
end | |
def find_def_solution(meth, text, previous_lines) | |
previous_lines.each do |line| | |
case line | |
when /after_(create|update|save|destroy)\s*:#{meth}/ | |
return After.new(text) | |
when /before_(create|update|save|destroy)\s*:#{meth}/ | |
return Before.new(text) | |
end | |
end | |
nil | |
end | |
end | |
Dir.glob(ARGV.first || 'app/models/**/*.rb').each do |f| | |
Model.new(f).solve | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment