2009-10-05 13 views
5

Mam pewien kod w wtyczce stylu silnika, która zawiera niektóre modele. W mojej aplikacji chcę rozszerzyć jeden z tych modeli. Udało mi się dodać do tego modelu zarówno metody instancji, jak i klasy, włączając moduł z inicjalizatora.Rozszerz model w wtyczce z "has_many" używając modułu

Jednak nie mogę dodawać asocjacji, wywołań zwrotnych itp. Otrzymuję błąd "nie znaleziono metody".

/libs/qwerty/core.rb

module Qwerty 
    module Core 
    module Extensions 

     module User 
     # Instance Methods Go Here 

     # Class Methods 
     module ClassMethods 
      has_many :hits, :uniq => true # no method found 

      before_validation_on_create :generate_code # no method found 

      def something # works! 
      "something" 
      end 
     end 

     def self.included(base) 
      base.extend(ClassMethods) 
     end 
     end 
    end 
    end 
end 

/initializers/qwerty.rb

require 'qwerty/core/user' 

User.send :include, Qwerty::Core::Extensions::User 

Odpowiedz

6

myślę, że to powinno działać

module Qwerty 
    module Core 
    module Extensions 
     module User 
     # Instance Methods Go Here 

     # Class Methods 
     module ClassMethods 
      def relate 
      has_many :hits, :uniq => true # no method found 

      before_validation_on_create :generate_code # no method found 
      end 

      def something # works! 
      "something" 
      end 
     end 

     def self.included(base) 
      base.extend(ClassMethods).relate 
     end 
     end 
    end 
    end 
end 

Stary kod jest przyczyną złego sprawdzanie poprawności i powiązanie są wywoływane podczas ładowania modułu, a ten moduł nie wie nic o ActiveRecord. Jest to ogólny aspekt Ruby, kod wewnątrz klasy lub ciał modułu jest wywoływany bezpośrednio po załadowaniu. Nie chcesz tego. Aby obejść to, możesz skorzystać z powyższego rozwiązania.

+0

Gotcha: Podczas przeładowywania! w konsoli klasa zostaje przeładowana, ale ponieważ moduł (w moim przypadku) jest wywoływany z inicjalizatora, moduł nie jest ponownie stosowany. – Kris

+0

Ponadto w tej chwili wydaje się, że kod w module jest uwzględniany tylko podczas korzystania z konsoli, gdy ten sam kod jest wywoływany ze sterownika, który nie działa. Chciałbym opublikować przykład kodu, ale odpowiedź nie wydaje się właściwa (to nie jest forum) ... – Kris

+0

KONTROLER: render: text => User.new.respond_to? ('Hits') i return # => false CONSOLE: User.new.respond_to? ('hits') # => true PREEMPT: Uruchomiłem ponownie serwer :) – Kris

14

Powinieneś być w stanie to zrobić. Nieco bardziej zwięzłe IMHO.

module Qwerty::Core::Extensions::User 
    def self.included(base) 
    base.class_eval do 
     has_many :hits, :uniq => true 
     before_validation_on_create :generate_code 
    end 
    end 
end 
+0

To jest całkowicie poprawna odpowiedź. – kikito

4

W Rails 3, to brzmi jak dobry przypadku wykorzystania do ActiveSupport :: dotyczą:

module Qwerty::Core::Extensions::User 

    extend ActiveSupport::Concern 

    included do 
    has_many :hits, :uniq => true 
    before_validation_on_create :generate_code 
    end 
end 

class User 
    include Querty::Core::Extensions::User 
    # ... 
end 

Oto ActiveSupport::Concern docs i najbardziej pomocny blog article na nim znalazłem.

Powiązane problemy