diff --git a/lib/rails/convert_active_record_dirty_5_0_to_5_1.rb b/lib/rails/convert_active_record_dirty_5_0_to_5_1.rb index 2f91942b..6e9a9e7d 100644 --- a/lib/rails/convert_active_record_dirty_5_0_to_5_1.rb +++ b/lib/rails/convert_active_record_dirty_5_0_to_5_1.rb @@ -75,11 +75,13 @@ def call_after_create 'changed_attributes' => 'saved_changes.transform_values(&:first)' } - helper_method :convert_callback do |before_name, after_name| + helper_method :convert_callback do |before_name, after_name, attributes| with_node type: 'sym', to_value: before_name do if before_name.is_a?(Regexp) node.to_value =~ before_name - replace_with ":#{after_name.sub('{{attribute}}', $1)}" + if attributes.include?($1) + replace_with ":#{after_name.sub('{{attribute}}', $1)}" + end else replace_with after_name end @@ -87,56 +89,72 @@ def call_after_create with_node type: 'send', receiver: nil, message: before_name do if before_name.is_a?(Regexp) node.message.to_s =~ before_name - replace_with after_name.sub('{{attribute}}', $1) + if attributes.include?($1) + replace_with after_name.sub('{{attribute}}', $1) + end else replace_with after_name end end end + object_attributes = {} + within_file 'db/schema.rb' do + within_node type: 'block', caller: { type: 'send', message: 'create_table' } do + object_name = node.caller.arguments.first.to_value.singularize + object_attributes[object_name] = [] + with_node type: 'send', receiver: 't', message: { not: 'index' } do + if node.arguments.size > 0 + attribute_name = node.arguments.first.to_value + object_attributes[object_name] << attribute_name + end + end + end + end + within_files 'app/models/**/*.rb' do - before_callback_names = [] - - %i[before_create before_update before_save].each do |callback_name| - with_node type: 'send', receiver: nil, message: callback_name do - before_callback_names << node.arguments[0].to_value - if node.arguments[1] && node.arguments[1].type == :hash - goto_node node.arguments[1] do - BEFORE_CALLBACK_CHANGES.each do |before_name, after_name| - convert_callback(before_name, after_name) - end + within_node type: 'class' do + object_name = node.name.to_source.underscore + + before_callback_names = [] + + %i[before_create before_update before_save].each do |callback_name| + with_node type: 'send', receiver: nil, message: callback_name do + if node.arguments[0].type == :sym + before_callback_names << node.arguments[0].to_value + end + BEFORE_CALLBACK_CHANGES.each do |before_name, after_name| + convert_callback(before_name, after_name, object_attributes[object_name]) end end end - end - with_node type: 'def' do - if before_callback_names.include?(node.name) - BEFORE_CALLBACK_CHANGES.each do |before_name, after_name| - convert_callback(before_name, after_name) + with_node type: 'def' do + if before_callback_names.include?(node.name) + BEFORE_CALLBACK_CHANGES.each do |before_name, after_name| + convert_callback(before_name, after_name, object_attributes[object_name]) + end end end - end - after_callback_names = [] + after_callback_names = [] - %i[after_create after_update after_save after_commit after_create_commit after_update_commit after_save_commit].each do |callback_name| - with_node type: 'send', receiver: nil, message: callback_name do - after_callback_names << node.arguments[0].to_value - if node.arguments[1] && node.arguments[1].type == :hash - goto_node node.arguments[1] do - AFTER_CALLBACK_CHANGES.each do |before_name, after_name| - convert_callback(before_name, after_name) - end + %i[after_create after_update after_save after_commit after_create_commit after_update_commit after_save_commit].each do |callback_name| + with_node type: 'send', receiver: nil, message: callback_name do + if node.arguments[0].type == :sym + after_callback_names << node.arguments[0].to_value + end + AFTER_CALLBACK_CHANGES.each do |before_name, after_name| + convert_callback(before_name, after_name, object_attributes[object_name]) end end end - end - with_node type: 'def' do - if after_callback_names.include?(node.name) - AFTER_CALLBACK_CHANGES.each do |before_name, after_name| - convert_callback(before_name, after_name) + with_node type: 'def' do + if after_callback_names.include?(node.name) + AFTER_CALLBACK_CHANGES.each do |before_name, after_name| + convert_callback(before_name, after_name, object_attributes[object_name]) + end end end end diff --git a/spec/rails/convert_active_record_dirty_5_0_to_5_1_spec.rb b/spec/rails/convert_active_record_dirty_5_0_to_5_1_spec.rb index 95231cd8..40330ecb 100644 --- a/spec/rails/convert_active_record_dirty_5_0_to_5_1_spec.rb +++ b/spec/rails/convert_active_record_dirty_5_0_to_5_1_spec.rb @@ -5,6 +5,18 @@ RSpec.describe 'Convert ActiveRecord::Dirty 5.0 to 5.1' do let(:rewriter_name) { 'rails/convert_active_record_dirty_5_0_to_5_1' } let(:fake_file_path) { 'app/models/post.rb' } + let(:schema_content) { + <<~EOS + ActiveRecord::Schema.define(version: 20140211112752) do + create_table "posts", force: true do |t| + t.string "title" + t.string "summary" + t.boolean "status" + t.timestamps + end + end + EOS + } let(:test_content) { <<~EOS class Post < ActiveRecord::Base @@ -54,5 +66,12 @@ def call_after_create EOS } + before do + FakeFS do + FileUtils.mkdir('db') + File.write('db/schema.rb', schema_content) + end + end + include_examples 'convertable' end diff --git a/spec/support/convertable.rb b/spec/support/convertable.rb index fd4ef59c..c67cc893 100644 --- a/spec/support/convertable.rb +++ b/spec/support/convertable.rb @@ -6,7 +6,7 @@ def load_snippet(snippet_name) end def load_sub_snippets(sub_snippets) - sub_snippets.each do |sub_snippet| require(sub_snippet)end + sub_snippets.each { |sub_snippet| require(sub_snippet) } end shared_examples 'convertable' do @@ -36,7 +36,7 @@ def load_sub_snippets(sub_snippets) describe 'with fakefs', fakefs: true do before do - file_paths.each do |file_path| FileUtils.mkdir_p(File.dirname(file_path))end + file_paths.each { |file_path| FileUtils.mkdir_p(File.dirname(file_path)) } end it 'converts' do