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



Так как последний релиз Rails 3 больше не является автоматической загрузкой модулей и классов из 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);

795   12  

12 ответов:

по состоянию на рельсы 2.3.9, есть настройка в config/application.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 в режиме разработки. Имейте в виду, что это не предназначено для производственной среды, так как постоянная перезагрузка замедляет машина.

магия автоматической загрузки вещей

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

поэтому, когда дело доходит до загрузки материала из подкаталогов, есть gotcha или соглашение вы должны быть в курсе. Иногда магия 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" и это будет работать точно так же.

P. S. Я чувствую себя обязанным добавить еще одну важную вещь. В последнее время, когда я хочу иметь что-то в каталоге lib, которое должно быть загружено автоматически, я, как правило, начинаю думать, что если это то, что я на самом деле разрабатываю специально для этого проект (как правило, он может когда-нибудь превратиться в "статический" фрагмент кода, используемый во многих проектах или подмодуле git и т. д.. в этом случае он определенно должен быть в папке lib), то, возможно, его место вообще не находится в папке lib. Возможно, он должен быть в подпапке под папкой приложения· у меня есть ощущение, что это новый способ rails делать вещи. Очевидно, что та же магия работает везде, где в вас загружаются пути, в которые вы помещаете свои вещи, поэтому это хорошо для этих вещей. В любом случае, это просто мои мысли на эту тему. Вы можете не соглашаться. :)


обновление: о типе магии..

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

внимание: если вы хотите загрузить "monkey patch" или "open class" из папки "lib", не используйте подход' autoload'!!!

  • " config.autoload_paths" подход: работает только если вы загружаете класс, который определен только в одном месте. Если какой-то класс уже определен где-то в другом месте, то вы не можете загрузить его снова с помощью этого подхода.

  • "config / initializer / load_rb_file.РБ" подход: всегда работает! независимо от того, какой целевой класс является новым классом или" открытым классом "или" патчем обезьяны " для существующего класса, он всегда работает!

Подробнее см.:https://stackoverflow.com/a/6797707/445908

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

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

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

в рамках приложения.рубидий...

require '/lib/this_file.rb' 

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

require './lib/this_file.rb' 

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

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

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

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

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

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

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

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

require 'mymodule'

в верхней части модели.rb файл.

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

  • исправить путь автоматической загрузки
  • многопотоковое исполнение, связанных с
  • именования отношении
  • ...

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

пожалуйста, проверьте это GitHub Обсуждение Ссылка как хорошо.

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

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

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

Comments

    Ничего не найдено.