Skip to content

Instantly share code, notes, and snippets.

@labocho
Created February 26, 2015 10:34
Show Gist options
  • Select an option

  • Save labocho/085991485a4b75c312e0 to your computer and use it in GitHub Desktop.

Select an option

Save labocho/085991485a4b75c312e0 to your computer and use it in GitHub Desktop.
Synvert snippet to keep foreign key name generated by `foreigner` gem for Rails 4.2 app.
# Synvert snippet to keep foreign key name generated by `foreigner` gem for Rails 4.2 app.
# Usage:
# Save to ~/.synvert/lib/rails/foreigner.rb
# $ cd RAILS_ROOT
# $ synvert --run rails/foreigner
require "active_support/inflector"
load "config/initializers/inflections.rb"
module Synvert::Core
class Rewriter::InsertBeforeAction < Rewriter::Action
def begin_pos
@node.loc.expression.begin_pos - @node.indent
end
def end_pos
begin_pos
end
private
def indent(node)
' ' * node.indent
end
end
end
module Synvert::Core
class Rewriter::Instance
def insert_before(node)
@actions << Rewriter::InsertBeforeAction.new(self, node + "\n")
end
end
end
Synvert::Rewriter.new 'rails', 'foreigner' do
description <<-EOF
It converts rails migrations with foreigner to without foreigner.
EOF
within_file 'db/migrate/*.rb' do
def has_name?(node)
if node.arguments.last.type == :hash
return true if node.arguments.last.has_key?(:name)
end
end
def build_fk(from_table, to_table, hash_node = nil)
if hash_node
if hash_node.has_key?(:column)
column = hash_node.hash_value(:column).to_value
end
end
column ||= to_table.to_s.singularize + "_id"
"#{from_table}_#{column}_fk"
end
def extract_hash(node)
if node.arguments.last.type == :hash
node.arguments.last
end
end
%w(create_table change_table).each do |method_name|
within_node type: 'block', caller: {type: 'send', message: method_name} do
from_table = nil
with_node type: 'send', message: method_name do
from_table = node.arguments.first.to_value
end
lines_before_block = []
lines_after_block = []
with_node type: 'send', receiver: 't', message: :foreign_key do
to_table = node.arguments[0].to_value
hash = extract_hash(node)
name = build_fk(from_table, to_table, hash)
arguments = node.arguments.map(&:to_source)
arguments.push(%(name: "#{name}"))
lines_after_block << "add_foreign_key :#{from_table}, #{arguments.join(", ")}"
remove
end
with_node type: 'send', receiver: 't', message: :remove_foreign_key do
name = node.arguments[0].hash_value(:name).to_value
lines_before_block << "remove_foreign_key :#{from_table}, name: #{name.dump}"
remove
end
unless lines_before_block.empty?
insert_before(lines_before_block.join("\n"))
end
unless lines_after_block.empty?
insert_after(lines_after_block.join("\n"))
end
end
end
with_node type: 'send', message: :add_foreign_key do
next if has_name?(node)
hash = extract_hash(node)
from_table = node.arguments[0].to_value
to_table = node.arguments[1].to_value
name = build_fk(from_table, to_table, hash)
replace_with %(add_foreign_key {{arguments}}, name: #{name.dump})
end
with_node type: 'send', message: :remove_foreign_key do
next if has_name?(node)
hash = extract_hash(node)
from_table = node.arguments[0].to_value
to_table = node.arguments[1].to_value
name = build_fk(from_table, to_table, hash)
replace_with %(remove_foreign_key {{arguments.first}}, name: #{name.dump})
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment