Created
February 26, 2015 10:34
-
-
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.
This file contains hidden or 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
| # 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