2013-07-23 21 views
6

Używam Spree Commerce w moim sklepie internetowym. Chcę zmienić pewne zachowanie podczas procesu kasowania, które jest zdefiniowane w app/models/spree/order/checkout.rb wewnątrz klejnotu spree. Zrobiłem więc checkout_decorator.rb w tym samym punkcie w mojej aplikacji.Dekorator modułów szpulowych

Problem polega na tym, że moje zmiany nie zostały wczytane. Innym problemem jest to, że wszystko wewnątrz modułu znajduje się w jednej metodzie, metodzie def self.included(klass). Więc myślę, że muszę zastąpić cały plik, zamiast tylko jednej metody. Oto co mój dekorator wygląda następująco:

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 

oryginalnego pliku checkout.rb z gem spree wygląda następująco:

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 

Więc moje pytania: Dlaczego to nie działa? Czy module_eval jest właściwym sposobem na zrobienie tego? Próbowałem class_eval, ale to też nie działa. Jak mogę to rozwiązać?

Odpowiedz

1

Metoda module_eval nie będzie działać dla ciebie.

Powinieneś spojrzeć na Spree Checkout Flow Documentation, aby zapoznać się z kilkoma dobrymi przykładami dostosowywania przepływu zamówienia. Jest to zalecany sposób dostosowywania przepływu transakcji, ponieważ nie trzeba kopiować/wklejać całej wiązki kodu.

1

Przestrzeń nazw jest nieprawidłowa.

Spróbuj Spree::Order::Checkout.class_eval do

0

tl; dr: Przepisz metodę, która ma w klasie Spree :: Order zamiast Spree :: Zamówienie :: modułu Checkout.

Wspomniałeś, że w oryginalnym pliku (spree_core-3.2.0.rc3/app/models/spree/order/checkout.rb) jest metoda owijająca cały moduł.

def self.included(klass) 
    klass.class_eval do 

Metoda ta jest wywoływana, gdy moduł jest w klasie, a nie własnej class_eval dodać metody modułu do instancji klasy włączając go.

Więc skoro (spree_core-3.2.0.rc3/app/models/Spree/order.rb) ma ten wiersz:

include Spree::Order::Checkout 

możemy dodać dekorator do klasy samej kolejności (app/models /spree/order_decorator.rb)