diff --git a/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb b/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb index 882808f42..40eb27f9d 100644 --- a/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +++ b/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb @@ -35,12 +35,12 @@ def join_table_name join_table_name.to_s end - def association_relation + def association_relation(related_instance) relation = associated_class.all if reflection.scope # Source: AR::Associations::AssociationScope#eval_scope - relation.instance_exec(subject, &reflection.scope) + relation.instance_exec(related_instance, &reflection.scope) else relation end diff --git a/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb b/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb index 0d0503c9b..e54bb1e4c 100644 --- a/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +++ b/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb @@ -5,7 +5,7 @@ module AssociationMatchers # @private class ModelReflector delegate :associated_class, :through?, :join_table_name, - :association_relation, :polymorphic?, :foreign_key, + :polymorphic?, :foreign_key, :association_foreign_key, to: :reflection def initialize(subject, name) @@ -13,6 +13,10 @@ def initialize(subject, name) @name = name end + def association_relation + reflection.association_relation(subject) + end + def reflection @reflection ||= reflect_on_association(name) end diff --git a/spec/unit/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb b/spec/unit/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb index 6be807281..d47b0894d 100644 --- a/spec/unit/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb +++ b/spec/unit/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb @@ -95,13 +95,29 @@ person_model = define_model(:person, country_id: :integer) do belongs_to :country, -> { where(mood: 'nice') } end + person_instance = person_model.new(spirit: 'nice') delegate_reflection = person_model.reflect_on_association(:country) reflection = described_class.new(delegate_reflection) - actual_sql = reflection.association_relation.to_sql + actual_sql = reflection.association_relation(person_instance).to_sql expected_sql = Country.where(mood: 'nice').to_sql expect(actual_sql).to eq expected_sql end + + it 'pass instance of association source to block' do + spy = spy('spy') + define_model(:country, mood: :string) + person_model = define_model(:person, country_id: :integer) do + belongs_to :country, ->(person) { spy.who(person) } + end + person_instance = person_model.new(spirit: 'nice') + delegate_reflection = person_model.reflect_on_association(:country) + reflection = described_class.new(delegate_reflection) + + reflection.association_relation(person_instance) + + expect(spy).to have_received(:who).with(person_instance) + end end context 'when the scope is nil' do @@ -113,7 +129,7 @@ delegate_reflection = person_model.reflect_on_association(:country) reflection = described_class.new(delegate_reflection) - actual_sql = reflection.association_relation.to_sql + actual_sql = reflection.association_relation(person_model).to_sql expected_sql = Country.all.to_sql expect(actual_sql).to eq expected_sql end