dostałem zadanie upgrade’u aplikacji na najnowse wersje gemów i tak z rails 2.3.5 i hobo 1.0.1 zacząłem przechodzić na rails 3.0.9 i hobo 1.3.0.RC
Po drodze pojawił mi się jednak pewien problem.
Otóż, po starcie aplikacji i próbie zalogowania do niej użytkownika w modelu user.rb zgłaszany jest NoMethodError w procedurze:
def method_missing(method, *args, &block)
str = method.to_s
if(str.length < 11)
return super
end
if(str[0,10] == 'calls_week')
week = str[10, str.length - 10].to_i
return super if (week == nil)
return calls_week(week)
end
if(str[0,10] == 'leads_week')
week = str[10, str.length - 10].to_i
return super if (week == nil)
return leads_week(week)
end
if(str[0,10] == 'projs_week')
week = str[10, str.length - 10].to_i
return super if (week == nil)
return projs_week(week)
end
super
end
konkretnie w pierwszym ‘return super’
Czy wiecie może jak ten błąd wyrugować?
Próbowałem znaleźć jakieś informacje o tym ‘super’, ale nieszczególnie znalazłem cokolwiek
Dla próby zbudowałem nową, pustą aplikację są w niej dwa wystąpienia (dla aplikacji hobo1.3.0 trzy) słowka ‘super’, ale tylko w plikach .js
W aplikacji, którą mam upgradować, są 142 wystąpienia w 76 plikach.
Szczerze mówiąc nie wiem czego oczekiwać.
Na rails 2.3.5 nigdy nie wystąpił taki błąd - przynajmniej od czasu kiedy dostałem tą aplikację do opieki.
Czyli jeśli dobrze rozumiem, mechanizm logowania do aplikacji wywołuje jakąś metodę usera, której nie ma, wtedy zgłasza się method_missing i superem wywołuje bład ogólny, tak?
W railsach 3 przepisano sposób generowania metod atrybutów, wydaje mi się, że teraz są leiniwie ładowane podczas pierwszego odwołania, być może to jest przyczyną. Nie miałem jeszcze czasu się dokładnie temu przyjrzeć, więc niestety żadnych konkretów nie podam
piotroslav: Tak sądzę. Spróbuj dojść do miejsca, które wywołuje tę nieistniejącą metodę. Na pewno będzie to w backtrace.
Co do tego ‘super’, to to jest część języka ruby a nie specjalna metoda Railsów. W tym przypadku (zgaduję, że klasa User dziedziczy z ActiveRecord::Base), super w metodzie zdefiniowanej w klasie User wywoła metodę ‘method_missing’ z klasy ActiveRecord::Base, a tamta zapewne też ma gdzieś w swojej treści jakieś ‘super’, które z kolei wywoła metodę z kolejnej klasy rodzica, aż dojdzie toto do klasy Object, który nie ma już żadnego ‘super’, tylko rzuca wyjątkiem.
Przyznam, że jak analizowałem co będzie łatwiejsze - przekonwertować program (średniej jakości - NIE MÓJ!) z railsów 2 na railsy 3, to zdecydowałem się napisać go na nowo. Ale trzymam kciuki
O samym ‘super’ znalazłem tylko informację, ze to z Ruby’iego i że do konstruktorów czesto używane może być - sta moje dociekanie
Co do samego pomysłu przenosin na rails3 - jakies dziwne rzeczy zaczęły się dziać przy deployach na heroku - środowisko przestało ogarniać, ze ma tylko pliki do odczytu i próbowało odswierzać jakieś template’y, przez co crashowało aplikację - my nic nie zmienialiśmy w konfiguracji - heroku twierdzi, że tez nic nie robili.
W efekcie poświęciliśmy bezowocnie dużo czasu na wymuszenie w naszej konfiguracji trybu read-only i wciąż mamy zablokowaną możliwość releasowania nowych wersji.
Może łatwiej będzie stworzyć nową aplikację, a potem przenosić po kolei modele, później kontrolery? (pamiętając o zmianie mechanizmu escapowania w widokach - chyba najbardziej uciążliwa rzecz)
Z backtrace widzę, że problemem jest nie ‘super’ tylko ‘generated_methods’. Google ma trochę wyników na to, ale nie wiem, które jest rozwiązaniem. No i jeszcze Windows może być problematycznym środowiskiem, ale to już zupełnie inna bajka.
Mam kolejny problem (w zasadzie to jest ich sporo, ale po kolei…)
W starej wersji aplikacji używany był gem hobo w postaci pluginu.
UserMailer w dowolnej metodzie miał dwie poniższe linie:
host = Hobo::Controller.request_host
app_name = Hobo::Controller.app_name || host
a w /vendor/plugins/… …/hobo/controller.rb były zdefiniowane:
[code]def request_host
Thread.current[‘Hobo.current_controller’].request.host_with_port
end
def app_name
Thread.current[‘Hobo.current_controller’].send(:call_tag, :app_name)
end[/code]
Hobo 1.3.0 jest w postaci gemu i dostaje bład nieznanem metody w >> Hobo::Controller.request_host
Nie znalazłem informacji o instalowaniu hobo 1.3.0 w postaci pluginu, dlatego chciałbym zapytać w jaki sposób mógłbym rozwiązać (nie rezygnując z hobo) powyższy problem?
te zmienne podejrzewam nie zmieniają się dla danego środowiska, np. development, więc możesz je wrzucić do jakiegos configa i stamtąd wczytać, nie używam Hobo, więc tak tylko strzelam
Jeśli się zastanowić, to Thread.current[] zwraca thread, więc Thread.current[].request to powinna byc metoda Thread’a, ale takiej metody nie ma… więc jak to mogło wcześniej działać?