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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions lib/shoulda/matchers/active_record/association_matcher.rb
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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