Добавление lib в config.autoload_paths в Rails 3 не загружает мой модуль автоматически - PullRequest
73 голосов
/ 02 ноября 2010

Я помещаю имя файла g.rb в папку Rails.root/lib Содержимое файла выглядит так:

module Google
end

Затем я добавляю

config.autoload_paths += %W(#{config.root}/lib #{Rails.root}/app/delayed_jobs)

на мой Rails.root/config/application.rb

Однако, когда я пытаюсь вызвать Google из rails console, возникает исключение. Исключение исчезнет, ​​только если я выполню require 'google'. Зачем? Разве мой файл не должен загружаться автоматически, и не должен ли я получить доступ к модулю без каких-либо дополнительных операторов require?

Ответы [ 6 ]

113 голосов
/ 02 ноября 2010

Хм, я обнаружил интересную вещь.Чтобы Rails автоматически загружал мой класс, имя класса должно соответствовать имени файла и структуре папок.Например, если я хочу, чтобы модуль Google загружался автоматически, я должен поместить его в google.rb, непосредственно в / lib (в случае, если я указываю автозагрузку из / lib).Если я хочу автоматически загрузить Google::Docs, то я либо помещаю его внутрь google.rb, либо google/docs.rb

27 голосов
/ 06 сентября 2011

У меня была похожая проблема с запуском модуля на Heroku. В дополнение к соглашению об именах автозагрузки, установленному Стивеном С, я обнаружил, что код модуля должен быть require 'd из-за предположения threadsafe, сделанного производственной средой Rails на Heroku (даже при том, что threadsafe был прокомментирован в моем production.rb файле конфигурации.) Как только я require сделал файл модуля перед вызовом include на модуле, все начало работать.

require 'mymodule'
include Mymodule

Пожалуйста, ознакомьтесь с этой превосходной статьей на тему правильной загрузки модулей в Heroku (производство).

24 голосов
/ 31 января 2011

Это потому, что точка автозагрузки , а не , чтобы «требовать» все заранее (штраф за запуск). Классы загружаются по мере необходимости / ссылки. Чтобы сделать это, вам нужен способ узнать, где искать класс. В противном случае вам придется заранее загрузить каждый файл в каталоге автозагрузки, чтобы увидеть, какие классы объявлены. Это компромисс, но требовать все заранее (как предлагает marbaq) не является автозагрузкой. Вы можете использовать команду autoload, предоставленную Ruby, которая принимает два аргумента: загружаемый модуль (символизированный, т. Е. Google в вашем случае), а вторым аргументом является имя файла, которое будет g.rb, если lib находится в путь загрузки ($ :). См. Документы Ruby для автозагрузки.

7 голосов
/ 15 июля 2013
1 голос
/ 25 ноября 2010

Я столкнулся с той же проблемой только сейчас, и мое «решение» (или, скорее, обходной путь) состояло в том, чтобы вручную запрашивать каждый необходимый файл из Rails.root / lib в моем application.rb.

require 'lib/message'
require 'lib/store'
require 'lib/vault/vault.rb'
require 'lib/custom_loggers'

module MyApplication
  class Application < Rails::Application

Следующим моим шагом будет классификация файлов в папках модулей, как вы упомянули.

0 голосов
/ 30 марта 2012

я недавно нашел это решение

config / application.rb

module AppName
  class Application < Rails::Application

    # Custom directories with classes and modules you want to be autoloadable.
    config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')]
    config.autoload_paths += Dir[Rails.root.join('app', 'lib', 'extensions')] 

  end
end

первый вызов конфигурации побуждает рельсы автоматически загружать все подкаталогикаталог app / models, так что теперь я могу автоматически загружать /app/models/sub_directory/model.rb (удобно для организации приложения с большой базой кода)

второй вызов config побуждает rails автоматически загружать lib/ extensions каталог

надеюсь, что это поможет

примечание: я считаю, что это рельсы 3 конкретных

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...