Я пишу кастомную оболочку для open_flash_chart
плагина. Он помещен в/lib
и загружается как модуль в ApplicationController
.
Однако у меня есть проблема с иерархией классов или что-то в этом роде.
С любого контроллера я могу получить доступ к таким open_flash_chart
функциям, как OpenFlashChart
,Line
и т.д.
Однако в классе в /lib
модуля это не работает!
Есть идеи?
ruby-on-rails
ruby
class
module
Мантас
источник
источник
Ответы:
Есть два способа загрузки файлов в Rails:
app/controllers/pages_controller.rb
PagesController и вы ссылаетесь на него,app/controllers/pages_controller.rb
он будет загружен автоматически. Это происходит для предустановленного списка каталогов в пути загрузки. Это особенность Rails, которая не является частью обычного процесса загрузки Ruby.require
d. Если это файлrequire
d, Ruby просматривает весь список путей в ваших путях загрузки и находит первый случай, когда файл, который выrequire
d, находится в пути загрузки. Вы можете увидеть весь путь загрузки, проверив $ LOAD_PATH (псевдоним для $ :).Поскольку он
lib
находится в пути загрузки, у вас есть два варианта: либо называть файлы такими же именами, как у констант, чтобы Rails автоматически выбирал их, когда вы ссылаетесь на рассматриваемую константу, либо явно запрашивать модуль.Я также заметил, что вас может смутить еще одна вещь. ApplicationController не является корневым объектом в системе. Обратите внимание:
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>
Вам нужно будет включить модуль в любой класс, в котором вы хотите его использовать.
class AnotherClass include MyModule end AnotherClass.new.im_awesome # AnotherClass is so awesome
Конечно, чтобы иметь возможность включить модуль в первую очередь, вам необходимо, чтобы он был доступен (используя любой из методов, описанных выше).
источник
В Rails 3 / lib модули не загружаются автоматически.
Это потому, что строка:
# config.autoload_paths += %W(#{config.root}/extras)
внутри config / application.rb есть комментарии.
Вы можете попробовать раскомментировать эту строку или, (у меня это сработало даже лучше), оставить комментарий (для справки в будущем) и добавить эти две строки:
config.autoload_paths += %W(#{config.root}/lib) config.autoload_paths += Dir["#{config.root}/lib/**/"]
источник
../lib
путь вApplicationName::Application.config.autoload_paths
массиве.config.autoload_paths += Dir["#{config.root}/lib/**/"]
должно хватить. @ckarbass Вторая строка дает вам свободу организовать ваши утилиты в подпапки и, таким образом, улучшить ваши модули с помощью пространств имен . Это почти все. И вот почему значение по умолчанию было изменено. Лучше поздно, чем никогда :)Что сработало для меня, помимо раскомментирования config.autoload_paths (я использую Rails 3.1.3), так это создание инициализатора, подобного этому:
#config/initializers/myapp_init.rb require 'my_module' include MyModule
Таким образом, я могу вызывать методы mymodule из любого места и как методы класса
Model.mymodule_method
или как методы экземпляраmymodel.mymodule_method
Может быть, какой-нибудь эксперт объяснит, к чему это приведет. К настоящему времени используйте его на свой страх и риск.
Изменить: после этого, я думаю, лучше было бы:
создайте инициализатор вроде этого:
#config/initializers/myapp_init.rb require ‘my_module’
При необходимости включите модуль, например:
1) если вы хотите использовать его как «Методы класса», используйте «extension»:
class Myclass < ActiveRecord::Base extend MyModule def self.method1 Myclass.my_module_method end end
2) если вы хотите использовать его как «Методы экземпляра», включите его в определение класса:
class Myclass < ActiveRecord::Base include MyModule def method1 self.my_module_method end end
3) помните, что это
include MyModule
относится к файлуmy_module.rb
в вашем пути загрузки, который должен быть обязательным в первую очередьисточник
lib
папке, поэтому добавилconfig.autoload_paths += %W(#{config.root}/lib)
вconfig/application.rb
файл. После этого я последовал вашему предложению добавитьconfig/initializers/myapp_init.rb
файл и его содержимое. Все в порядке. Большое спасибо :)require
у меня работает, а автоматическая загрузка - нет (метод undefined module), в этом комментарии говорится, что вы не должны использоватьrequire
.Чтобы использовать модуль
lib/my_module.rb
в ваших моделях и контроллерах:В
config/application.rb
:config.watchable_dirs['lib'] = [:rb]
В вашей модели (аналогичная идея для вашего контроллера):
require_dependency 'my_module' class MyModel < ActiveRecord::Base include MyModule MyModule.some_method end
Более подробно этот метод описан на http://hakunin.com/rails3-load-paths
источник
Возможно, вы захотите явно загрузить файл (ы) в каталог lib во время инициализации приложения.
В моем config / application.rb у меня есть запись как,
config.autoload_paths += %W(#{config.root}/lib)
Также это может быть тот случай, когда имя / иерархия модуля не такие же, как в файле, или расположение / имя файла не такое же, как эта иерархия, поэтому автоматическая загрузка этого файла также невозможно. Поэтому, когда я добавил запись в конец config / application.rb as,
require "./lib/file_name_without_extention
она работала нормально.
источник