Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: with_foreign_key modifier fails with wrong error message #1376

Merged
merged 1 commit into from Nov 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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