Class: RuboCop::Cop::Rails::UniqueValidationWithoutIndex

Inherits:
Base
  • Object
show all
Includes:
ActiveRecordHelper
Defined in:
lib/rubocop/cop/rails/unique_validation_without_index.rb

Overview

When you define a uniqueness validation in Active Record model, you also should add a unique index for the column. There are two reasons. First, duplicated records may occur even if Active Record’s validation is defined. Second, it will cause slow queries. The validation executes a ‘SELECT` statement with the target column when inserting/updating a record. If the column does not have an index and the table is large, the query will be heavy.

Note that the cop does nothing if db/schema.rb does not exist.

Examples:

# bad - if the schema does not have a unique index
validates :account, uniqueness: true

# good - if the schema has a unique index
validates :account, uniqueness: true

# good - even if the schema does not have a unique index
validates :account, length: { minimum: MIN_LENGTH }

Constant Summary collapse

MSG =
'Uniqueness validation should have a unique index on the database column.'
RESTRICT_ON_SEND =
%i[validates].freeze

Constants included from ActiveRecordHelper

ActiveRecordHelper::WHERE_METHODS

Instance Method Summary collapse

Methods included from ActiveRecordHelper

#external_dependency_checksum, #foreign_key_of, #in_where?, #inherit_active_record_base?, #polymorphic?, #resolve_relation_into_column, #schema, #table_name

Instance Method Details

#on_send(node) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
# File 'lib/rubocop/cop/rails/unique_validation_without_index.rb', line 33

def on_send(node)
  return unless schema
  return unless (uniqueness_part = uniqueness_part(node))
  return if uniqueness_part.falsey_literal? || condition_part?(node, uniqueness_part)

  klass, table, names = find_schema_information(node, uniqueness_part)
  return unless names
  return if with_index?(klass, table, names)

  add_offense(node)
end