Join table check for habtm w/ custom foreign keys should still work
If the habtm association in question specifies a custom foreign_key or association_foreign_key, when the habtm matcher checks that the join table has the correct columns, it should use the specified column names instead of the defaults.
This commit is contained in:
parent
0695c8647b
commit
48f45e814a
|
@ -957,7 +957,8 @@ module Shoulda
|
|||
end
|
||||
|
||||
def join_table_matcher
|
||||
@join_table_matcher ||= AssociationMatchers::JoinTableMatcher.new(self)
|
||||
@join_table_matcher ||=
|
||||
AssociationMatchers::JoinTableMatcher.new(self, reflector)
|
||||
end
|
||||
|
||||
def class_exists?
|
||||
|
|
|
@ -4,7 +4,8 @@ module Shoulda
|
|||
module AssociationMatchers
|
||||
# @private
|
||||
class JoinTableMatcher
|
||||
attr_reader :association_matcher, :failure_message
|
||||
attr_reader :failure_message
|
||||
|
||||
alias :missing_option :failure_message
|
||||
|
||||
delegate :model_class, :join_table, :associated_class,
|
||||
|
@ -12,8 +13,9 @@ module Shoulda
|
|||
|
||||
delegate :connection, to: :model_class
|
||||
|
||||
def initialize(association_matcher)
|
||||
def initialize(association_matcher, reflector)
|
||||
@association_matcher = association_matcher
|
||||
@reflector = reflector
|
||||
end
|
||||
|
||||
def matches?(subject)
|
||||
|
@ -39,8 +41,14 @@ module Shoulda
|
|||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
attr_reader :association_matcher, :reflector
|
||||
|
||||
private
|
||||
|
||||
delegate :foreign_key, :association_foreign_key, to: :reflector
|
||||
|
||||
def missing_columns
|
||||
@missing_columns ||= expected_join_table_columns.select do |key|
|
||||
!actual_join_table_columns.include?(key)
|
||||
|
@ -48,10 +56,7 @@ module Shoulda
|
|||
end
|
||||
|
||||
def expected_join_table_columns
|
||||
[
|
||||
"#{model_class.name.underscore}_id",
|
||||
"#{associated_class.name.underscore}_id"
|
||||
]
|
||||
[foreign_key, association_foreign_key]
|
||||
end
|
||||
|
||||
def actual_join_table_columns
|
||||
|
|
|
@ -45,6 +45,25 @@ module Shoulda
|
|||
end
|
||||
end
|
||||
|
||||
def foreign_key
|
||||
if has_and_belongs_to_many_reflection
|
||||
has_and_belongs_to_many_reflection.foreign_key
|
||||
elsif reflection.respond_to?(:primary_key_name)
|
||||
reflection.primary_key_name
|
||||
else
|
||||
reflection.foreign_key
|
||||
end
|
||||
end
|
||||
|
||||
def association_foreign_key
|
||||
if has_and_belongs_to_many_reflection
|
||||
join_model = has_and_belongs_to_many_reflection.options[:class]
|
||||
join_model.right_reflection.foreign_key
|
||||
else
|
||||
reflection.association_foreign_key
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
attr_reader :reflection, :subject
|
||||
|
|
|
@ -5,7 +5,8 @@ module Shoulda
|
|||
# @private
|
||||
class ModelReflector
|
||||
delegate :associated_class, :through?, :join_table,
|
||||
:association_relation, :polymorphic?, to: :reflection
|
||||
:association_relation, :polymorphic?, :foreign_key,
|
||||
:association_foreign_key, to: :reflection
|
||||
|
||||
def initialize(subject, name)
|
||||
@subject = subject
|
||||
|
|
|
@ -732,6 +732,44 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
|||
end.to fail_with_message_including('missing columns: person_id, relative_id')
|
||||
end
|
||||
|
||||
context 'using a custom foreign key' do
|
||||
it 'rejects an association with a join table with incorrect columns' do
|
||||
define_model :relative
|
||||
define_model :person do
|
||||
has_and_belongs_to_many :relatives,
|
||||
foreign_key: :custom_foreign_key_id
|
||||
end
|
||||
|
||||
define_model :people_relative,
|
||||
id: false,
|
||||
custom_foreign_key_id: :integer,
|
||||
some_crazy_id: :integer
|
||||
|
||||
expect do
|
||||
expect(Person.new).to have_and_belong_to_many(:relatives)
|
||||
end.to fail_with_message_including('missing columns: custom_foreign_key_id, relative_id')
|
||||
end
|
||||
end
|
||||
|
||||
context 'using a custom association foreign key' do
|
||||
it 'rejects an association with a join table with incorrect columns' do
|
||||
define_model :relative
|
||||
define_model :person do
|
||||
has_and_belongs_to_many :relatives,
|
||||
association_foreign_key: :custom_association_foreign_key_id
|
||||
end
|
||||
|
||||
define_model :people_relative,
|
||||
id: false,
|
||||
custom_association_foreign_key_id: :integer,
|
||||
some_crazy_id: :integer
|
||||
|
||||
expect do
|
||||
expect(Person.new).to have_and_belong_to_many(:relatives)
|
||||
end.to fail_with_message_including('missing columns: person_id, custom_association_foreign_key_id')
|
||||
end
|
||||
end
|
||||
|
||||
it 'rejects an association of the wrong type' do
|
||||
define_model :relative, person_id: :integer
|
||||
define_model :person do
|
||||
|
|
Loading…
Reference in New Issue