Moduły Rails / lib oraz
Piszę Niestandardowy wrapper dla open_flash_chart
plugin. Jest umieszczony w /lib
i załadowany jako moduł w ApplicationController
.
Jednak mam pewien problem z hierarchią klas lub smth.
Z dowolnego kontrolera mogę uzyskać dostęp do funkcji open_flash_chart
jako OpenFlashChart
, Line
etc
Jednak w klasie w module /lib
to nie działa!
5 answers
Są dwa sposoby ładowania plików w Rails:
- jest rejestrowany w procesie autoload i odwołujesz się do stałej odpowiadającej nazwie pliku. Na przykład, jeśli masz
app/controllers/pages_controller.rb
i reference PagesController,app/controllers/pages_controller.rb
zostanie automatycznie załadowany. Dzieje się tak w przypadku wstępnie ustawionej listy katalogów w ścieżce ładowania. Jest to cecha Rails i nie jest częścią normalnego procesu ładowania Ruby. - pliki są jawnie
require
d. Jeśli plik jestrequire
d, Ruby wygląda przejrzyj całą listę ścieżek w ścieżkach ładowania i znajdź pierwszy przypadek, w którym plikrequire
d znajduje się w ścieżce ładowania. Możesz zobaczyć całą ścieżkę ładowania, sprawdzając $LOAD_PATH (alias dla $:).
Ponieważ lib
znajduje się w twojej ścieżce ładowania, masz dwie opcje: albo nazwij swoje pliki tymi samymi nazwami co stałe, więc Rails automatycznie je odbierze, gdy odwołasz się do danej stałej, albo wyraźnie wymaga modułu.
Zauważam również, że możesz być zmieszany z inną sprawą. ApplicationController jest Nie głównym obiektem w systemie. Obserwuj:
module MyModule
def im_awesome
puts "#{self} is so awesome"
end
end
class ApplicationController < ActionController::Base
include MyModule
end
class AnotherClass
end
AnotherClass.new.im_awesome
# NoMethodError: undefined method `im_awesome' for #<AnotherClass:0x101208ad0>
Będziesz musiał dołączyć moduł do dowolnej klasy, w której chcesz go użyć.
class AnotherClass
include MyModule
end
AnotherClass.new.im_awesome
# AnotherClass is so awesome
Oczywiście, aby móc dołączyć moduł w pierwszej kolejności, musisz mieć go dostępnego (przy użyciu jednej z powyższych technik).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-02 17:11:41
W Rails 3 / lib Moduły nie są ładowane automatycznie.
To dlatego, że linia:
# config.autoload_paths += %W(#{config.root}/extras)
Wewnątrz config / aplikacji.rb jest komentowany.
Możesz spróbować odkomentować ten wiersz lub, (dla mnie to działało jeszcze lepiej), zostawić ten komentarz (dla przyszłych odniesień) i dodać te dwie linijki:
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-20 11:01:07
To, co u mnie zadziałało, poza tym, że Config nie działa.autoload_paths (I ' m on Rails 3.1.3), było stworzenie inicjalizatora takiego jak:
#config/initializers/myapp_init.rb
require 'my_module'
include MyModule
W ten sposób mogę wywoływać metody mymodule z dowolnego miejsca i jako metody klas Model.mymodule_method
lub jako metody instancji mymodel.mymodule_method
Może jakiś ekspert może wyjaśnić konsekwencje tego. Do tej pory używaj go na własne ryzyko.
Edit: potem myślę, że lepszym rozwiązaniem byłoby:
Utwórz inicjalizator jak to:
#config/initializers/myapp_init.rb
require ‘my_module’
Dołącz moduł w razie potrzeby, w następujący sposób:
1) jeśli chcesz użyć go jako "metody klasy" użyj "extend":
class Myclass < ActiveRecord::Base
extend MyModule
def self.method1
Myclass.my_module_method
end
end
2) jeśli chcesz użyć go jako "metody instancji", dodaj go do definicji klasy:
class Myclass < ActiveRecord::Base
include MyModule
def method1
self.my_module_method
end
end
3) pamiętaj, że include MyModule
odnosi się do pliku my_module.rb
w ścieżce ładowania, który musi być najpierw wymagany
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-19 09:11:32
Aby używać modułu lib/my_module.rb
w modelach i kontrolerach:
W config/application.rb
:
config.watchable_dirs['lib'] = [:rb]
W twoim modelu (podobny pomysł na kontroler):
require_dependency 'my_module'
class MyModel < ActiveRecord::Base
include MyModule
MyModule.some_method
end
Metoda ta jest opisana bardziej szczegółowo w http://hakunin.com/rails3-load-paths
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-12 16:27:08
Może się zdarzyć, że podczas inicjalizacji aplikacji będziesz chciał jawnie załadować pliki w katalogu lib.
w moim config / aplikacji.rb, mam wpis jako, config.autoload_paths += %W(#{config.root}/lib)
może się również zdarzyć, że nazwa / hierarchia modułu nie jest taka sama jak w pliku lub lokalizacja / nazwa pliku nie jest taka sama jak w tej hierarchii, więc automatyczne ładowanie tego pliku również nie jest możliwe. Więc kiedy dodałem wpis na dole config / application.rb as, require "./lib/file_name_without_extention
zadziałało dobrze.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-12 08:11:16