使用装饰器与原始代码时的狂欢错误

时间:2014-10-09 19:56:50

标签: ruby-on-rails spree

需要一点帮助: - )

我正在尝试使用装饰器扩展Order类,但是即使我使用源代码完全相同的代码,我也会收到错误。例如:

order_decorator.rb (该方法与源码完全相同,我只是使用装饰器)

Spree::Order.class_eval do

def update_from_params(params, permitted_params, request_env = {})
  success = false
  @updating_params = params
  run_callbacks :updating_from_params do
    attributes = @updating_params[:order] ? @updating_params[:order].permit(permitted_params).delete_if { |k,v| v.nil? } : {}

    # Set existing card after setting permitted parameters because
    # rails would slice parameters containg ruby objects, apparently
    existing_card_id = @updating_params[:order] ? @updating_params[:order][:existing_card] : nil

    if existing_card_id.present?
      credit_card = CreditCard.find existing_card_id
      if credit_card.user_id != self.user_id || credit_card.user_id.blank?
        raise Core::GatewayError.new Spree.t(:invalid_credit_card)
      end

      credit_card.verification_value = params[:cvc_confirm] if params[:cvc_confirm].present?

      attributes[:payments_attributes].first[:source] = credit_card
      attributes[:payments_attributes].first[:payment_method_id] = credit_card.payment_method_id
      attributes[:payments_attributes].first.delete :source_attributes
    end

    if attributes[:payments_attributes]
      attributes[:payments_attributes].first[:request_env] = request_env
    end

    success = self.update_attributes(attributes)
    set_shipments_cost if self.shipments.any?
  end

  @updating_params = nil
  success
end

end

当我运行此代码时,即使选择现有卡,spree也永远不会找到 @updating_params [:order] [:existing_card] 。因此,我永远无法使用预先存在的卡和虚假网关完成交易(而是给我空空白错误)。

我尝试使用pry绑定 order_decorator.rb 中的方法,并注意到 [:existing_card] @updating_params 的实际情况等级而不是 @updating_params [:order] 的等级。

当我删除装饰器时,原始代码工作正常。

有人可以向我解释我的代码有什么问题吗?

谢谢,

1 个答案:

答案 0 :(得分:0)

您要重新定义的方法实际上不是Order类的方法。它是由Order类中的Checkout模块混合的方法。 你可以在这里看到它:https://github.com/spree/spree/blob/master/core/app/models/spree/order/checkout.rb

尝试以这种方式做你想做的事:

使用代码

创建文件app/models/spree/order/checkout.rb
Spree::Order::Checkout.class_eval do
  def self.included(klass)
    super
    klass.class_eval do
      def update_from_params(params, permitted_params, request_env = {})
        ...
        ...
        ...
      end
    end
  end
end