Skip to content

Commit 73b6947

Browse files
authored
Merge pull request #635 from eugeneius/bulk_change_table_remove_multiple_columns
Handle t.remove with multiple columns in Rails/BulkChangeTable
2 parents 7bbc675 + d66dd9f commit 73b6947

File tree

3 files changed

+63
-6
lines changed

3 files changed

+63
-6
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* [#635](https://github.com/rubocop/rubocop-rails/pull/635): Handle `t.remove` with multiple columns in `Rails/BulkChangeTable`. ([@eugeneius][])

lib/rubocop/cop/rails/bulk_change_table.rb

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -155,17 +155,31 @@ def on_send(node)
155155
return if include_bulk_options?(node)
156156
return unless node.block_node
157157

158-
send_nodes = node.block_node.body.each_child_node(:send).to_a
158+
send_nodes = send_nodes_from_change_table_block(node.block_node.body)
159159

160-
transformations = send_nodes.select do |send_node|
161-
combinable_transformations.include?(send_node.method_name)
162-
end
163-
164-
add_offense_for_change_table(node) if transformations.size > 1
160+
add_offense_for_change_table(node) if count_transformations(send_nodes) > 1
165161
end
166162

167163
private
168164

165+
def send_nodes_from_change_table_block(body)
166+
if body.send_type?
167+
[body]
168+
else
169+
body.each_child_node(:send).to_a
170+
end
171+
end
172+
173+
def count_transformations(send_nodes)
174+
send_nodes.sum do |node|
175+
if node.method?(:remove)
176+
node.arguments.count { |arg| !arg.hash_type? }
177+
else
178+
combinable_transformations.include?(node.method_name) ? 1 : 0
179+
end
180+
end
181+
end
182+
169183
# @param node [RuboCop::AST::SendNode] (send nil? :change_table ...)
170184
def include_bulk_options?(node)
171185
# arguments: [{(sym :table)(str "table")} (hash (pair (sym :bulk) _))]

spec/rubocop/cop/rails/bulk_change_table_spec.rb

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,48 @@ def change
387387
end
388388
RUBY
389389
end
390+
391+
it 'registers an offense for a single `t.remove` with multiple columns' do
392+
expect_offense(<<~RUBY)
393+
def change
394+
change_table :users do |t|
395+
^^^^^^^^^^^^^^^^^^^ You can combine alter queries using `bulk: true` options.
396+
t.remove :name, :metadata
397+
end
398+
end
399+
RUBY
400+
end
401+
402+
it 'does not register an offense for a single `t.remove` with one column' do
403+
expect_no_offenses(<<~RUBY)
404+
def change
405+
change_table :users do |t|
406+
t.remove :name
407+
end
408+
end
409+
RUBY
410+
end
411+
412+
it 'registers an offense for a single `t.remove` with multiple columns and options' do
413+
expect_offense(<<~RUBY)
414+
def change
415+
change_table :users do |t|
416+
^^^^^^^^^^^^^^^^^^^ You can combine alter queries using `bulk: true` options.
417+
t.remove :name, :metadata, type: :string
418+
end
419+
end
420+
RUBY
421+
end
422+
423+
it 'does not register an offense for a single `t.remove` with one column and options' do
424+
expect_no_offenses(<<~RUBY)
425+
def change
426+
change_table :users do |t|
427+
t.remove :name, type: :string
428+
end
429+
end
430+
RUBY
431+
end
390432
end
391433

392434
context 'when database is PostgreSQL' do

0 commit comments

Comments
 (0)