Class: RuboCop::Cop::Migration::ChangeTableReferences
- Inherits:
-
Base
- Object
- Base
- RuboCop::Cop::Migration::ChangeTableReferences
- Defined in:
- lib/rubocop/cop/migration/change_table_references.rb
Overview
Prevent using ‘t.references` or `t.belongs_to` in a change_table. Internally, `t.references` use multiple `ALTER TABLE` statements. Since Rails cannot transform automatically `t.references` inside a `change_table bulk: true` we can manually create the equivalent `ALTER TABLE` statement using `t.bigint`, `t.index` and `t.foreign_key`.
#bad
change_table :subscriptions, bulk: true do |t|
t.references :user, null: false, foreign_key: true
end
#good
change_table :subscriptions, bulk: true do |t|
t.bigint :user_id, null: false
t.index :user_id
t.foreign_key :users, column: :user_id
end
Constant Summary collapse
- MSG =
'Use a combination of `t.bigint`, `t.index` and `t.foreign_key` in a change_table to add a reference.' \ 'Or `t.remove_foreign_key`, `t.remove` to remove a reference.'
Instance Method Summary collapse
Instance Method Details
#add_references_in_block?(node) ⇒ Object
28 29 30 |
# File 'lib/rubocop/cop/migration/change_table_references.rb', line 28 def_node_matcher :add_references_in_block?, <<~PATTERN (send lvar /references|belongs_to|remove_references|remove_belongs_to/ ...) PATTERN |
#change_table?(node) ⇒ Object
33 34 35 |
# File 'lib/rubocop/cop/migration/change_table_references.rb', line 33 def_node_matcher :change_table?, <<~PATTERN (block (send nil? :change_table ...) ...) PATTERN |
#on_block(node) ⇒ Object
37 38 39 40 41 42 43 44 45 46 |
# File 'lib/rubocop/cop/migration/change_table_references.rb', line 37 def on_block(node) return unless change_table?(node) references_node = node.child_nodes[2].each_node.detect { |n| add_references_in_block?(n) } return unless references_node arguments = references_node.child_nodes[1] references_methods_range = references_node.source_range.with(end_pos: arguments.source_range.begin_pos - 1) add_offense(references_methods_range) end |