2010-12-16 8 views
14

jestem małpa-łatanie silnik szynach z czymś takim:W jaki sposób poprawiać kod małp, który jest automatycznie ładowany w Railsach?

SomeClass.class_eval do 
    # ... 
end 

pierwszy raz, kiedy uderzył w witrynę internetową, na trybie rozwoju przynajmniej to działa, ale drugi raz to jak mój plaster nigdy nie istniał . Przypuszczam, że to Rails automatycznie przeładowuje silnik (który jest zainstalowany w dostawcy /) i nie przeładowuje mojego kodu. To jest Rails 2.3.

Jakieś pomysły, jak to zrobić, aby mój kod został ponownie załadowany?

+0

Raz uderzyłem w podobny problem i jedynym sposobem, w jaki mogłem to naprawić, było uruchomienie szyn w trybie produkcyjnym na mojej maszynie dev :(. Jestem również zainteresowany tym. – kikito

+0

@egarcia: ouch, mam nadzieję, że tym razem znajdziemy lepsze rozwiązanie. – Pablo

+0

jak uruchomić swój kod, czy to webbrick, kundel czy pasażer? proszę opublikuj szyny i wersje serwerowe. – mpapis

Odpowiedz

0

Niestety, nie ma sposobu, aby podłączyć mechanizm przeładowania Rails 2.x. Co możesz zrobić, to umieścić łatkę gdzieś w katalogu aplikacji lub lib. (lib/core_ext to prawdopodobnie preferowana lokalizacja). Następnie dodaj katalog do ścieżek autoload w twojej konfiguracji.

Konieczne może być również otwarcie klasy, a nie użycie parametru class_eval.

+0

Poprawka małpy znajduje się już na lib /, która jest już na ścieżkach autoload na Rails 2. Nie jestem pewien dlaczego, ale otwarcie klasy słowem kluczowym class zamiast class_eval powoduje błąd, wyjątek wyrzucony później. – Pablo

4

Jeśli umieścisz łatkę w pliku .rb wewnątrz/config/inicjalizatory, powinna działać.

+0

jaka jest różnica między używaniem class_eval i to_prepare? – montrealmike

0

To jest brzydkie, ale odkryłem, że jeśli umieściłem ten kod na dole environment.rb, zawsze gwarantuje on prawidłową kolejność ładunków podczas uruchamiania.

18

EDYCJA: To rozwiązanie działa tylko dla Rails 3+, ponieważ jest zależne od niektórych funkcji w Rails :: Railtie. Umieść ten kod w inicjalizatorze.

To pytanie jest dość stary, ale tutaj jest to rozwiązanie znalazłem:

Rails.configuration.to_prepare do 
    SomeClass.class_eval do 
    # ... 
    end 
end 

Zmusza Rails przeładować klasę na każde żądanie w trybie rozwoju, ale tylko raz w produkcji.

+0

To zadziałało idealnie dla mnie na Rails 3. Dziękuję. –

+0

To również zadziałało dla mnie na Railsach 4 – ABMagil

+1

Praca dla mnie także w Rails 5. – ttotherat

5

Właśnie napisałem swój pierwszy patch-małpa, więc musiałem wymyślić zestaw konwencji wokół niego. Oto co wymyśliłem:

  1. Place rozszerzenia pod lib/ext/. (. Sugerowana przez weterana workmad3 w #rubyonrails pokoju IRC) W moim przypadku, jestem dodanie metody do klasy (z mail klejnot, używany przez ActionMailer) Mail::Message, więc stworzyłem:

    /lib/ext/mail/message.rb

  2. Otwórz klasy lub moduł i dodać kod:

    module Mail class Message def to_is_phone? !!(self.to.first =~ /^\+1\d{10}$/) end end end

  3. Utwórz initalizer aby załadować wszystkie małpy łatki. Railsy automatycznie ładują plik, gdy stała jest odwoływana, ale ponieważ dodajesz metody do istniejących klas/modułów zamiast definiowania nowych, to nie zadziała, więc musisz ręcznie wymagać wszystkich poprawek małpy.Więc stworzyłem:

    /config/initializers/monkey_patches.rb

    który zawiera:

    require 'ext/mail/message'

+0

Należy zauważyć, że obecnie używam Rails 4.1, ale myślę, że to powinno działać również w starszych wersjach. – odigity

+3

'monkey_patches.rb' może być' Dir [Rails.root.join ('lib/ext/*. Rb')]. Each {| file | wymagaj pliku} 'i wszystkie poprawki małpy zostaną pobrane. – dankohn

Powiązane problemy