Skip to content

Commit

Permalink
check attributes for rails/convert_active_record_dirty_5_0_to_5_1
Browse files Browse the repository at this point in the history
  • Loading branch information
flyerhzm committed Mar 14, 2021
1 parent e1a3b31 commit 69b6680
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 35 deletions.
84 changes: 51 additions & 33 deletions lib/rails/convert_active_record_dirty_5_0_to_5_1.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,68 +75,86 @@ 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
end
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
Expand Down
19 changes: 19 additions & 0 deletions spec/rails/convert_active_record_dirty_5_0_to_5_1_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
4 changes: 2 additions & 2 deletions spec/support/convertable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 69b6680

Please sign in to comment.