Class: RuboCop::Cop::DevDoc::Migration::RequirePrimaryKey

Inherits:
Base
  • Object
show all
Defined in:
lib/rubocop/cop/dev_doc/migration/require_primary_key.rb

Overview

Every ‘create_table` migration must have a primary key.

## Rationale A table without a primary key is hard to reference, hard to debug, and hard to migrate later. ‘id: false` is rarely the right answer; `has_many :through` with an explicit join model is preferred for many-to-many relationships, and that join model has its own `id`.

❌
create_table :products_categories, id: false do |t|
  t.belongs_to :product
  t.belongs_to :category
end

✔️  Use an explicit join model with has_many :through instead
create_table :product_categories do |t|
  t.belongs_to :product, null: false, foreign_key: true
  t.belongs_to :category, null: false, foreign_key: true
  t.timestamps
end

Examples:

# bad
create_table :products_categories, id: false do |t|
  t.belongs_to :product
end

# good
create_table :product_categories do |t|
  t.belongs_to :product, null: false, foreign_key: true
end

Constant Summary collapse

MSG =
'Every table must have a primary key. Avoid `id: false` — ' \
'use an explicit join model with `has_many :through` instead.'.freeze
RESTRICT_ON_SEND =
%i[create_table].freeze

Instance Method Summary collapse

Instance Method Details

#on_send(node) ⇒ Object



45
46
47
48
49
50
# File 'lib/rubocop/cop/dev_doc/migration/require_primary_key.rb', line 45

def on_send(node)
  id_false = node.each_descendant(:pair).find { |pair| id_false_pair?(pair) }
  return unless id_false

  add_offense(id_false)
end