From eb8329c9d4f7b4efe82fd15a48dcabfa2ef59852 Mon Sep 17 00:00:00 2001 From: Tony Spataro Date: Wed, 27 Jul 2022 17:02:36 -0700 Subject: [PATCH 1/2] Faithfully proxy keyword and block args. Closes #571. --- .../associations/single_association.rb | 9 +++++++-- spec/app/models/magazine.rb | 6 ++++++ spec/dynamoid/associations/belongs_to_spec.rb | 20 +++++++++++++++---- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/lib/dynamoid/associations/single_association.rb b/lib/dynamoid/associations/single_association.rb index 7d862595..6430012d 100644 --- a/lib/dynamoid/associations/single_association.rb +++ b/lib/dynamoid/associations/single_association.rb @@ -68,14 +68,19 @@ def ==(other) # # @private # @since 0.2.0 - def method_missing(method, *args) + def method_missing(method, *args, **kwargs, &block) if target.respond_to?(method) - target.send(method, *args) + target.send(method, *args, **kwargs, &block) else super end end + # @private + def respond_to_missing?(method_name, include_private = false) + target.respond_to?(method_name, include_private) || super + end + # @private def nil? target.nil? diff --git a/spec/app/models/magazine.rb b/spec/app/models/magazine.rb index ea2e24b5..bc534999 100644 --- a/spec/app/models/magazine.rb +++ b/spec/app/models/magazine.rb @@ -12,4 +12,10 @@ class Magazine has_one :sponsor belongs_to :owner, class_name: 'User', inverse_of: :books + + def publish(advertisements:, free_issue: false) + result = advertisements * (free_issue ? 2 : 1) + result = yield(result) if block_given? + result + end end diff --git a/spec/dynamoid/associations/belongs_to_spec.rb b/spec/dynamoid/associations/belongs_to_spec.rb index 35454725..cc723de2 100644 --- a/spec/dynamoid/associations/belongs_to_spec.rb +++ b/spec/dynamoid/associations/belongs_to_spec.rb @@ -30,11 +30,23 @@ expect(user.books).to include magazine end - it 'behaves like the object it is trying to be' do - expect(magazine.subscriptions).to include subscription - subscription.magazine.update_attribute(:size, 101) + context 'proxied behavior' do + let(:proxy) do + expect(magazine.subscriptions).to include(subscription) + subscription.magazine + end + + it 'forwards dynamoid methods' do + proxy.update_attribute(:size, 101) - expect(Magazine.first.size).to eq 101 + expect(Magazine.first.size).to eq 101 + end + + it 'forwards business-logic methods' do + expect(proxy.respond_to?(:publish)).to eq true + expect(proxy.publish(advertisements: 10)).to eq 10 + expect(proxy.publish(advertisements: 10, free_issue: true) { |c| c *= 42 }).to eq 840 + end end end From 28c04e784fe524ab45e60ccd68c17ccc6e053a01 Mon Sep 17 00:00:00 2001 From: Tony Spataro Date: Thu, 28 Jul 2022 07:26:43 -0700 Subject: [PATCH 2/2] Support older Ruby versions per https://bugs.ruby-lang.org/issues/16157 --- .../associations/single_association.rb | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/lib/dynamoid/associations/single_association.rb b/lib/dynamoid/associations/single_association.rb index 6430012d..80a5a579 100644 --- a/lib/dynamoid/associations/single_association.rb +++ b/lib/dynamoid/associations/single_association.rb @@ -64,15 +64,29 @@ def ==(other) target == other end - # Delegate methods we don't find directly to the target. - # - # @private - # @since 0.2.0 - def method_missing(method, *args, **kwargs, &block) - if target.respond_to?(method) - target.send(method, *args, **kwargs, &block) - else - super + if ::RUBY_VERSION < '2.7' + # Delegate methods we don't find directly to the target. + # + # @private + # @since 0.2.0 + def method_missing(method, *args, &block) + if target.respond_to?(method) + target.send(method, *args, &block) + else + super + end + end + else + # Delegate methods we don't find directly to the target. + # + # @private + # @since 0.2.0 + def method_missing(method, *args, **kwargs, &block) + if target.respond_to?(method) + target.send(method, *args, **kwargs, &block) + else + super + end end end