Лучший способ загрузить модуль / class из папки lib в Rails 3?

Поскольку последняя версия Rails 3 не является автоматическим загрузкой модhive и classов из lib больше, что было бы лучшим способом загрузить их?

Из github:

A few changes were done in this commit: Do not autoload code in *lib* for applications (now you need to explicitly require them). This makes an application behave closer to an engine (code in lib is still autoloaded for plugins); 

Начиная с Rails 2.3.9 , в config/application.rb в котором вы можете указать каталоги, содержащие файлы, которые вы хотите загрузить.

Из приложения.rb:

 # Custom directories with classes and modules you want to be autoloadable. # config.autoload_paths += %W(#{config.root}/extras) 
 # Autoload lib/ folder including all subdirectories config.autoload_paths += Dir["#{config.root}/lib/**/"] 

Источник: Rails 3 Quicktip: каталог Autoload lib, включающий все подкаталоги, избегайте ленивой загрузки

Имейте в виду, что файлы, содержащиеся в папке lib, загружаются только при запуске сервера. Если вам нужен комфорт для автозагрузки этих файлов, прочитайте: Rails 3 Quicktip: автоматическая перезагрузка папок lib в режиме разработки . Имейте в виду, что это не предназначено для производственной среды, поскольку постоянная перезагрузка замедляет работу машины.

Магия автозагрузки

Я думаю, что опция, управляющая папками, из которых делается загрузка автозагрузки, была достаточно освещена в других ответах. Однако, если у кого-то есть проблемы с загруженными материалами, хотя у них были изменены пути автозагрузки, тогда этот ответ пытается объяснить, какова магия этой автозагрузки.

Поэтому, когда дело доходит до загрузки файлов из подкаталогов, есть информация о том, что вы хотите получить. Иногда магия Ruby / Rails (на этот раз в основном Rails) может затруднить понимание, почему что-то происходит. Любой модуль, объявленный в пути автозагрузки, будет загружен только в том случае, если имя модуля соответствует имени родительского каталога. Поэтому, если вы попытаетесь добавить в lib/my_stuff/bar.rb что-то вроде:

 module Foo class Bar end end 

Он не будет загружен автоматически. Затем снова, если вы переименуете родительский каталог в foo таким образом разместив свой модуль по пути: lib/foo/bar.rb Он будет там для вас. Другой вариант – назвать файл, который вы хотите загрузить с помощью имени модуля. Очевидно, что тогда может быть только один файл. Если вам нужно разделить свои материалы на многие файлы, вы, конечно, можете использовать этот файл для других файлов, но я не рекомендую это, потому что тогда, когда в режиме разработки и вы изменяете эти другие файлы, Rails не может автоматически перезагрузите их для вас. Но если вы действительно хотите, чтобы у вас мог быть один файл по имени модуля, который затем указывает фактические файлы, необходимые для использования модуля. Таким образом, у вас может быть два файла: lib/my_stuff/bar.rb и lib/my_stuff/foo.rb а первый – тот же, что и выше, и последний содержит одну строку: require "bar" и это будет работать одинаково.

PS Я вынужден добавить еще одну важную вещь. В последнее время, когда я хочу иметь что-то в каталоге lib, которое должно получить автозагрузку, я, как правило, начинаю думать, что если это то, что я действительно разрабатываю специально для этого проекта (как правило, это может быть когда-нибудь превратитесь в «статический» fragment кода, используемый во многих проектах или подмодуль git и т. д., и в этом случае он определенно должен быть в папке lib), возможно, его место вообще не находится в папке lib. Возможно, это должно быть в подпапке под папкой приложения. У меня такое ощущение, что это новый способ делать rails. Очевидно, что та же магия находится в работе везде, где у вас есть автозагрузка путей, в которые вы вкладываете свои вещи, так что это хорошо для этих вещей. Во всяком случае, это только мои мысли по этому вопросу. Вы можете не согласиться. 🙂


ОБНОВЛЕНИЕ: О типе магии ..

Как отметил Серин в своем комментарии, kernel ​​«автозагрузка модуля» уверенно является частью Ruby, но это не относится к автозагрузкам. Вам не нужны Rails для autoload :Foo, File.join(Rails.root, "lib", "my_stuff", "bar") . И когда вы попытаетесь впервые ссылаться на модуль Foo, он будет загружен для вас. Однако, что делает Rails, это дает нам возможность автоматически загружать материал из зарегистрированных папок, и это было реализовано таким образом, что ему нужно что-то принять в соглашениях об именах. Если бы это не было реализовано так, то каждый раз, когда вы ссылаетесь на то, что в настоящее время не загружено, ему придется пройти через все файлы во всех папках автозагрузки и проверить, содержит ли какой-либо из них то, что вы пытались ссылаться. Это, в свою очередь, победит идею автозагрузки и автозагрузки. Тем не менее, с этими соглашениями на месте он может вычитать из модуля / classа, что вы пытаетесь загрузить там, где это может быть определено, и просто загружать его.

Предупреждение: если вы хотите загрузить «патч обезьяны» или «открыть class» из своей папки «lib», не используйте подход «автозагрузка» !!!

  • Подход « config.autoload_paths »: работает только если вы загружаете class, который определен только в ОДНОМ месте. Если какой-то class уже определен где-то в другом месте, то вы не можете загрузить его снова этим подходом.

  • Подход « config / initializer / load_rb_file.rb » всегда работает! независимо от того, какой class-class является новым classом или «открытым classом» или «патчем обезьяны» для существующего classа, он всегда работает!

Для получения дополнительной информации см. https://stackoverflow.com/a/6797707/445908

Очень похоже, но я думаю, что это немного более элегантно:

 config.autoload_paths += Dir["#{config.root}/lib", "#{config.root}/lib/**/"] 

В моем случае я пытался просто загрузить файл непосредственно в каталоге lib.

В приложении application.rb …

 require '/lib/this_file.rb' 

не работал, даже в консоли, а затем, когда я попытался

 require './lib/this_file.rb' 

и rails загружают файл отлично.

Я все еще довольно нооб, и я не уверен, почему это работает, но это работает. Если кто-то хотел бы объяснить это мне, я был бы признателен: я надеюсь, что это поможет кому-то в любом случае.

У меня такая же проблема. Вот как я это решил. Решение загружает каталог lib и все подкаталоги (а не только прямые). Конечно, вы можете использовать это для всех каталогов.

 # application.rb config.autoload_paths += %W(#{config.root}/lib) config.autoload_paths += Dir["#{config.root}/lib/**/"] 

config.autoload_paths не работает для меня. Я решаю это другим способом

Ruby on rails 3 не выполняет автоматический перезагрузку (автозагрузка) кода из папки / lib. Я решаю его, помещая в ApplicationController

 Dir["lib/**/*.rb"].each do |path| require_dependency path end 

Если только определенные файлы нуждаются в доступе к модулям в lib, просто добавьте инструкцию require к файлам, которые в ней нуждаются. Например, если одной модели требуется доступ к одному модулю, добавьте:

 require 'mymodule' 

в верхней части файла model.rb.

Есть несколько причин, по которым у вас могут возникнуть проблемы с загрузкой из lib – см. Здесь для деталей – http://www.williambharding.com/blog/technology/rails-3-autoload-modules-and-classes-in-production/

  • исправить путь автозагрузки
  • Связанные темы
  • присвоение имен

Начиная с Rails 5 , рекомендуется поместить папку lib в каталог приложения или вместо этого создать другие значащие пространства имен для папки в качестве services , presenters , features т. Д. И поместить их в каталог приложения для автоматической загрузки по рельсам.

Пожалуйста, проверьте также эту дискуссию GitHub .

Заполните имя файла правильно.

Шутки в сторону. Я сражался с classом в течение часа, потому что class был Governance :: ArchitectureBoard, и файл был в lib / management / architecture_baord.rb (транспонированный O и A в «доске»)

Кажется очевидным в ретроспективе, но это было отслеживание дьявола. Если class не определен в файле, который Rails ожидает, что он будет основан на изменении имени classа, он просто не найдет его.

  • TypScript ReferenceError: экспорт не определен
  • Может ли служба / модуль по умолчанию в приложении Google App Engine быть дочерним элементом нестандартного по структуре папок?
  • Использовать requirejs и jquery, не сбивая глобальный jquery?
  • Быстрый способ вычисления n! mod m, где m - простое число?
  • ImportError на python 3, отлично работал на python 2.7
  • Как проверить, есть ли у меня модуль Perl перед его использованием?
  • Как я могу использовать новый модуль Perl без разрешения на установку?
  • Удалить , равное удалению?
  • Android Studio: модуль не будет отображаться в «Редактирование конфигурации»
  • Как работает оператор модуля?
  • Что такое модуль в .NET?
  • Давайте будем гением компьютера.