Class: RuboCop::Cop::DevDoc::Migration::NoCreateJoinTable

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

Overview

Avoid ‘create_join_table` — define an explicit join model instead.

## Rationale ‘create_join_table` produces a PK-less table tied to `has_and_belongs_to_many`, which has well-known limitations: no timestamps, no per-row callbacks, and no room for extra columns without migration gymnastics.

The preferred Rails idiom is ‘has_many :through` with an explicit join model, which is just a normal table with a PK and timestamps.


create_join_table :products, :categories

✔️ Define an explicit join model
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

# In models:
class Product < ApplicationRecord
  has_many :product_categories
  has_many :categories, through: :product_categories
end

Examples:

# bad
create_join_table :products, :categories

# good
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

Constant Summary collapse

MSG =
'Avoid `create_join_table` — define an explicit join model with `has_many :through` instead.'.freeze
RESTRICT_ON_SEND =
%i[create_join_table].freeze

Instance Method Summary collapse

Instance Method Details

#on_send(node) ⇒ Object



46
47
48
# File 'lib/rubocop/cop/dev_doc/migration/no_create_join_table.rb', line 46

def on_send(node)
  add_offense(node.loc.selector)
end