2013-07-23 88 views
6

我为我的网上商店使用Spree Commerce。我想在结账过程中更改一些行为,这在冒险宝石里面的app/models/spree/order/checkout.rb中定义。所以我在我的应用程序的同一点做了一个checkout_decorator.rbSpree模块装饰器

问题是,我的更改没有加载。另一个问题是,模块内的所有内容都在一种方法中,即方法def self.included(klass)。所以我认为我不得不覆盖整个文件,而不是一个方法。这里是我的装饰看起来像:

checkout_decorator.rb

Spree::Order::Checkout.module_eval do 
    def self.included(klass) 
    klass.class_eval do 
     class_attribute :next_event_transitions 
     class_attribute :previous_states 
     class_attribute :checkout_flow 
     class_attribute :checkout_steps 

     def self.define_state_machine! 
     # here i want to make some changes 
     end 

     # and the other methods are also include here 
     # for readability, i don't show them here 
    end 
    end 
end 

从大礼包宝石原始文件checkout.rb看起来是这样的:

module Spree 
    class Order < ActiveRecord::Base 
    module Checkout 
     def self.included(klass) 
     klass.class_eval do 
      class_attribute :next_event_transitions 
      class_attribute :previous_states 
      class_attribute :checkout_flow 
      class_attribute :checkout_steps 

      def self.checkout_flow(&block) 
      if block_given? 
       @checkout_flow = block 
       define_state_machine! 
      else 
       @checkout_flow 
      end 
      end 

      def self.define_state_machine! 
      # some code 
      end 

      # and other methods that are not shown here 
     end 
     end 
    end 
    end 
end 

所以我的问题是:为什么这个不行?是module_eval正确的方法来做到这一点?我试过class_eval,但它也不起作用。我该如何解决这个问题?

回答

1

module_eval方法不适用于您。

有关如何自定义结帐流程的一些很好的示例,您应该看Spree Checkout Flow Documentation。这是自定义结帐流程的推荐方式,因为您不需要复制/粘贴大量代码。

1

命名空间不正确。

尝试Spree::Order::Checkout.class_eval do

0

TL;博士:覆盖您在施普雷:: Order类,而不是狂欢::订购::结帐模块所需的方法。

您提到在原始文件(spree_core-3.2.0.rc3/app/models/spree/order/checkout.rb)中有一个包装整个模块的方法。

def self.included(klass) 
    klass.class_eval do 

这种方法时,该模块包含在一个类被调用,并执行自己的class_eval到模块的方法添加到类,包括它的实例。

如此以来(spree_core-3.2.0.rc3 /应用/型号/大礼包/ order.rb)有这样一行:

include Spree::Order::Checkout 

我们可以在装饰添加到Order类本身(应用程序/模型/spree/order_decorator.rb)