diff --git a/core/lib/spree/deprecation.rb b/core/lib/spree/deprecation.rb
index 449803a3061..e2f1cf976e9 100644
--- a/core/lib/spree/deprecation.rb
+++ b/core/lib/spree/deprecation.rb
@@ -4,4 +4,54 @@
module Spree
Deprecation = ActiveSupport::Deprecation.new('3.0', 'Solidus')
+
+ # This DeprecatedInstanceVariableProxy transforms instance variable to
+ # deprecated instance variable.
+ #
+ # It differs from ActiveSupport::DeprecatedInstanceVariableProxy since
+ # it allows to define a custom message.
+ #
+ # class Example
+ # def initialize(deprecator)
+ # @request = Spree::DeprecatedInstanceVariableProxy.new(self, :request, :@request, deprecator, "Please, do not use this thing.")
+ # @_request = :a_request
+ # end
+ #
+ # def request
+ # @_request
+ # end
+ #
+ # def old_request
+ # @request
+ # end
+ # end
+ #
+ # When someone execute any method on @request variable this will trigger
+ # +warn+ method on +deprecator_instance+ and will fetch @_request
+ # variable via +request+ method and execute the same method on non-proxy
+ # instance variable.
+ #
+ # Default deprecator is Spree::Deprecation.
+ class DeprecatedInstanceVariableProxy < ActiveSupport::Deprecation::DeprecationProxy
+ def initialize(instance, method, var = "@#{method}", deprecator = Spree::Deprecation, message = nil)
+ @instance = instance
+ @method = method
+ @var = var
+ @deprecator = deprecator
+ @message = message
+ end
+
+ private
+
+ def target
+ @instance.__send__(@method)
+ end
+
+ def warn(callstack, called, args)
+ message = @message || "#{@var} is deprecated! Call #{@method}.#{called} instead of #{@var}.#{called}."
+ message = [message, "Args: #{args.inspect}"].join(" ")
+
+ @deprecator.warn(message, callstack)
+ end
+ end
end
diff --git a/frontend/app/controllers/spree/checkout_controller.rb b/frontend/app/controllers/spree/checkout_controller.rb
index 48955c33614..d6f6e86e23b 100644
--- a/frontend/app/controllers/spree/checkout_controller.rb
+++ b/frontend/app/controllers/spree/checkout_controller.rb
@@ -219,9 +219,14 @@ def before_payment
@wallet_payment_sources = try_spree_current_user.wallet.wallet_payment_sources
@default_wallet_payment_source = @wallet_payment_sources.detect(&:default) ||
@wallet_payment_sources.first
- # TODO: How can we deprecate this instance variable? We could try
- # wrapping it in a delegating object that produces deprecation warnings.
- @payment_sources = try_spree_current_user.wallet.wallet_payment_sources.map(&:payment_source).select { |ps| ps.is_a?(Spree::CreditCard) }
+
+ @payment_sources = Spree::DeprecatedInstanceVariableProxy.new(
+ self,
+ :deprecated_payment_sources,
+ :@payment_sources,
+ Spree::Deprecation,
+ "Please, do not use @payment_sources anymore, use @wallet_payment_sources instead."
+ )
end
end
@@ -251,5 +256,22 @@ def insufficient_stock_error
end
end
end
+
+ # This method returns payment sources of the current user. It is no more
+ # used into our frontend. We used to assign the content of this method
+ # into an ivar (@payment_sources) into the checkout payment step. This
+ # method is here only to be able to deprecate this ivar and will be removed.
+ #
+ # DO NOT USE THIS METHOD!
+ #
+ # @return [Array] Payment sources connected to
+ # current user wallet.
+ # @deprecated This method has been added to deprecate @payment_sources
+ # ivar and will be removed. Use @wallet_payment_sources instead.
+ def deprecated_payment_sources
+ try_spree_current_user.wallet.wallet_payment_sources
+ .map(&:payment_source)
+ .select { |ps| ps.is_a?(Spree::CreditCard) }
+ end
end
end