Skip to content

Instantly share code, notes, and snippets.

@seven1m
Last active August 29, 2015 14:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seven1m/52528473f6de4eddc032 to your computer and use it in GitHub Desktop.
Save seven1m/52528473f6de4eddc032 to your computer and use it in GitHub Desktop.
Fix old Rails 1.x finder syntax.
#!/usr/bin/env ruby
# A script to convert old Rails 1.x finder syntax, e.g. find(:all, ...) and find(:first, ...)
# to use where() and friends.
# gem install parser unparser
# cd path/to/rails_app
# ruby fix_find_by.rb
require 'parser/current'
require 'unparser'
require 'pry'
class RewriteFindBy < Parser::Rewriter
def on_send(node)
method_name = node.location.selector.source
if method_name == 'find'
args = node.to_a[2..-1].map { |a| Unparser.unparse(a) }
final = "#{Unparser.unparse(node.to_a[0])}"
if [":all", ":first"].include?(args.first)
node.to_a[3..-1].each do |arg|
arg.children.each do |pair|
begin
(key, val) = [Unparser.unparse(pair.children.first), Unparser.unparse(pair.children.last)]
rescue NoMethodError
next
end
case key.to_s
when ":conditions"
final << ".where(#{val.gsub(/^\[|\]$/, '')})"
when ":order"
final << ".order(#{val})"
when ":include"
final << ".includes(#{val})"
when ":limit"
final << ".limit(#{val})"
when ":offset"
final << ".offset(#{val})"
when ":join"
final << ".join(#{val})"
when ":select"
final << ".select(#{val})"
when ":page"
final << ".page(#{val})"
when ":per_page"
final << ".paginate(per_page: #{val})"
end
end
end
final << ".first" if args.first == ":first"
replace(node.location.expression, final)
end
end
node.to_a.each do |n|
if n.respond_to?(:type) and n.type
send("on_#{n.type}".to_sym, n) rescue nil
end
end
end
%w(on_argument on_casgn on_const on_def on_defs on_op_asgn on_var on_vasgn
process_argument_node process_regular_node process_var_asgn_node process_variable_node).each do |event|
define_method(event) do |node|
node.to_a.each do |n|
if n.respond_to?(:type) and n.type
ev = "on_#{n.type}".to_sym
send(ev, n) if respond_to?(ev)
end
end
end
end
end
Dir['**/*.rb', '**/*.rake'].each do |path|
puts path
buffer = Parser::Source::Buffer.new(path)
buffer.source = File.read(path)
parser = Parser::CurrentRuby.new
begin
ast = parser.parse(buffer)
rescue Parser::SyntaxError
puts "could not parse #{path}"
else
rewriter = RewriteFindBy.new
source = rewriter.rewrite(buffer, ast)
File.open(path, 'w') { |f| f.write(source) }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment