Skip to content

Commit

Permalink
Add support for custom indices
Browse files Browse the repository at this point in the history
  • Loading branch information
sirwolfgang committed Feb 7, 2018
1 parent cd96089 commit 464ce78
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 3 deletions.
14 changes: 11 additions & 3 deletions lib/shoulda/matchers/active_record/have_db_index_matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ def have_db_index(columns)
# @private
class HaveDbIndexMatcher
def initialize(columns)
@columns = normalize_columns_to_array(columns)
@options = {}
@columns = normalize_columns_to_array(columns)
@joined_columns = normalize_columns_to_string(columns)
@options = {}
end

def unique(unique = true)
Expand Down Expand Up @@ -124,7 +125,10 @@ def correct_unique?
end

def matched_index
indexes.detect { |each| each.columns == @columns }
indexes.detect do |each|
each.columns == @columns ||
normalize_columns_to_string(each.columns) == @joined_columns
end
end

def model_class
Expand Down Expand Up @@ -154,6 +158,10 @@ def index_type
def normalize_columns_to_array(columns)
Array.wrap(columns).map(&:to_s)
end

def normalize_columns_to_string(columns)
Array.wrap(columns).compact.map(&:to_s).join(', ')
end
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@
end

context 'have_db_index on multiple columns' do
it 'accepts an existing index regardless of order' do
db_connection = create_table 'geocodings' do |table|
table.integer :geocodable_id
table.string :geocodable_type
end
db_connection.add_index :geocodings, [:geocodable_type, :geocodable_id]
expect(define_model_class('Geocoding').new).
to have_db_index([:geocodable_id, :geocodable_type])
end

it 'accepts an existing index' do
db_connection = create_table 'geocodings' do |table|
table.integer :geocodable_id
Expand All @@ -44,6 +54,43 @@
end
end

context 'with a custom sql index' do
it 'accepts an existing index' do
db_connection = create_table 'geocodings' do |table|
table.integer :geocodable_id
table.integer :geocodable_value
end

db_connection.execute(
<<-SQL
CREATE INDEX index_geocodings_on_geocodable_id_and_absolute_value
ON geocodings(geocodable_id, abs(geocodable_value));
SQL
)

expect(define_model_class('Geocoding').new).
to have_db_index(expected_indexed_columns)
end

it 'rejects a nonexistent index' do
create_table 'geocodings' do |table|
table.integer :geocodable_id
table.datetime :geocodable_at
end

expect(define_model_class('Geocoding').new).
not_to have_db_index(expected_indexed_columns)
end

def expected_indexed_columns
if postgresql?
[:geocodable_id, 'abs(geocodable_value)']
else
[:geocodable_id, nil]
end
end
end

it 'join columns with and when describing multiple columns' do
expect(have_db_index([:user_id, :post_id]).description).to match(/on columns user_id and post_id/)
end
Expand Down

0 comments on commit 464ce78

Please sign in to comment.