Skip to content

Commit

Permalink
Add Migration/AlwaysBulkChangeTable (#46)
Browse files Browse the repository at this point in the history
  • Loading branch information
Bhacaz authored May 19, 2023
1 parent 4f236d6 commit 7057dc6
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

# main

* Added cop `Migration/AlwaysBulkChangeTable` ([#46](https://github.com/petalmd/rubocop-petal/pull/46))

# v1.0.0 (2023-05-15)

* Unified cops to be reused by others projects. ([#41](https://github.com/petalmd/rubocop-petal/pull/41))
Expand Down
6 changes: 6 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ Grape/PreferNamespace:
Include:
- app/api/**/*

Migration/AlwaysBulkChangeTable:
Description: 'Suggest to always use `bulk: true` when using `change_table`.'
Enabled: true
Include:
- db/migrate/**

Migration/ForeignKeyOption:
Description: 'Specify the foreign key option to create the constraint.'
Enabled: true
Expand Down
48 changes: 48 additions & 0 deletions lib/rubocop/cop/migration/always_bulk_change_table.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true

module RuboCop
module Cop
module Migration
# Using `bulk: true` with `change_table` is recommended.
# Without `bulk: true`, `change_table` generates multiple
# `ALTER TABLE` statements and the migration process will
# be duplicated.
#
# @bad
# change_table :users do |t|
# t.string :first_name
# t.string :last_name
# end
#
# @good
# change_table :users, bulk: true do |t|
# t.string :first_name
# t.string :last_name
# end
#
class AlwaysBulkChangeTable < Rails::BulkChangeTable
MSG = 'Add `bulk: true` when using change_table.'
RESTRICT_ON_SEND = %i[change_table].freeze

def on_send(node)
return unless node.command?(:change_table)

unless include_bulk_options?(node)
add_offense(node)
return
end

add_offense(node) unless bulk_options_true?(node)
end

def bulk_options_true?(node)
options = node.arguments[1]
options.each_pair do |key, value|
return true if key.value == :bulk && value.true_type?
end
false
end
end
end
end
end
27 changes: 27 additions & 0 deletions spec/rubocop/cop/migration/always_bulk_change_table_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::Migration::AlwaysBulkChangeTable, :config do
it 'registers an offense when not using bulk: true' do
expect_offense(<<~RUBY)
change_table :users do |t|
^^^^^^^^^^^^^^^^^^^ Add `bulk: true` when using change_table.
t.string :name
end
RUBY

expect_offense(<<~RUBY)
change_table :users, bulk: false do |t|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Add `bulk: true` when using change_table.
t.string :name
end
RUBY
end

it 'does not register an offense when using change_table and bulk true' do
expect_no_offenses(<<~RUBY)
change_table :users, bulk: true do |t|
t.string :name
end
RUBY
end
end

0 comments on commit 7057dc6

Please sign in to comment.