Skip to content

Commit

Permalink
fix: with_foreign_key modifier fails with wrong error message (#1376)
Browse files Browse the repository at this point in the history
  • Loading branch information
vsppedro committed Nov 20, 2020
1 parent 8772cd4 commit 64376a0
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 9 deletions.
27 changes: 18 additions & 9 deletions lib/shoulda/matchers/active_record/association_matcher.rb
Expand Up @@ -1394,19 +1394,28 @@ def touch_correct?
end

def class_has_foreign_key?(klass)
if options.key?(:foreign_key)
option_verifier.correct_for_string?(
:foreign_key,
options[:foreign_key],
)
elsif column_names_for(klass).include?(foreign_key)
true
else
@missing = "#{klass} does not have a #{foreign_key} foreign key."
if options.key?(:foreign_key) && !foreign_key_correct?
@missing = foreign_key_failure_message(klass, options[:foreign_key])
false
elsif !column_names_for(klass).include?(foreign_key)
@missing = foreign_key_failure_message(klass, foreign_key)
false
else
true
end
end

def foreign_key_correct?
option_verifier.correct_for_string?(
:foreign_key,
options[:foreign_key],
)
end

def foreign_key_failure_message(klass, foreign_key)
"#{klass} does not have a #{foreign_key} foreign key."
end

def primary_key_correct?(klass)
if options.key?(:primary_key)
if option_verifier.correct_for_string?(
Expand Down
Expand Up @@ -1414,6 +1414,20 @@ def having_many_non_existent_class(model_name, assoc_name, options = {})
expect(having_one_non_existent(:person, :detail, class_name: 'Detail')).not_to have_one(:detail)
end

it 'rejects an association with a valid :class_name and a bad :primary_key option' do
define_model :person_detail
define_model :person do
has_one :detail, class_name: 'PersonDetail', foreign_key: :person_detail_id
end

expected_message = 'Expected Person to have a has_one association called detail ' \
'(PersonDetail does not have a custom_primary_id foreign key.)'

expect { have_one(:detail).class_name('PersonDetail').with_foreign_key(:custom_primary_id) }.
not_to match_against(Person.new).
and_fail_with(expected_message)
end

it 'adds error message when rejecting an association with non-existent class' do
message = 'Expected Person to have a has_one association called detail (Detail2 does not exist)'
expect {
Expand Down

0 comments on commit 64376a0

Please sign in to comment.