Add rubocop check for add_reference to require index.

This commit is contained in:
Andreas Brandl 2018-08-01 17:52:54 +02:00
parent 3d2a3e5782
commit e3ff390986
4 changed files with 105 additions and 1 deletions

View File

@ -1,5 +1,5 @@
class AddMovedToToIssue < ActiveRecord::Migration
def change
add_reference :issues, :moved_to, references: :issues
add_reference :issues, :moved_to, references: :issues # rubocop:disable Migration/AddReference
end
end

View File

@ -0,0 +1,49 @@
# frozen_string_literal: true
require_relative '../../migration_helpers'
module RuboCop
module Cop
module Migration
# Cop that checks if a foreign key constraint is added and require a index for it
class AddReference < RuboCop::Cop::Cop
include MigrationHelpers
MSG = '`add_reference` requires `index: true`'
def on_send(node)
return unless in_migration?(node)
name = node.children[1]
return unless name == :add_reference
opts = node.children.last
add_offense(node, location: :selector) unless opts && opts.type == :hash
index_present = false
opts.each_node(:pair) do |pair|
index_present ||= index_enabled?(pair)
end
add_offense(node, location: :selector) unless index_present
end
private
def index_enabled?(pair)
hash_key_type(pair) == :sym && hash_key_name(pair) == :index && pair.children[1].true_type?
end
def hash_key_type(pair)
pair.children[0].type
end
def hash_key_name(pair)
pair.children[0].children[0]
end
end
end
end
end

View File

@ -11,6 +11,7 @@ require_relative 'cop/migration/add_column'
require_relative 'cop/migration/add_concurrent_foreign_key'
require_relative 'cop/migration/add_concurrent_index'
require_relative 'cop/migration/add_index'
require_relative 'cop/migration/add_reference'
require_relative 'cop/migration/add_timestamps'
require_relative 'cop/migration/datetime'
require_relative 'cop/migration/hash_index'

View File

@ -0,0 +1,54 @@
require 'spec_helper'
require 'rubocop'
require 'rubocop/rspec/support'
require_relative '../../../../rubocop/cop/migration/add_reference'
describe RuboCop::Cop::Migration::AddReference do
include CopHelper
let(:cop) { described_class.new }
context 'outside of a migration' do
it 'does not register any offenses' do
expect_no_offenses(<<~RUBY)
def up
add_reference(:projects, :users)
end
RUBY
end
end
context 'in a migration' do
before do
allow(cop).to receive(:in_migration?).and_return(true)
end
it 'registers an offense when using add_reference without index' do
expect_offense(<<~RUBY)
call do
add_reference(:projects, :users)
^^^^^^^^^^^^^ `add_reference` requires `index: true`
end
RUBY
end
it 'registers an offense when using add_reference index disabled' do
expect_offense(<<~RUBY)
def up
add_reference(:projects, :users, index: false)
^^^^^^^^^^^^^ `add_reference` requires `index: true`
end
RUBY
end
it 'does not register an offense when using add_reference with index enabled' do
expect_no_offenses(<<~RUBY)
def up
add_reference(:projects, :users, index: true)
end
RUBY
end
end
end