Я собираюсь обновить одну из моих любимых CMS до Rails 7, которая заархивирована на github (PushType). Только я не писал код для Rails со времен Rails 6. Судя по всему, в Rails 7 что-то изменилось в методах автозагрузки. Я получаю эту ошибку:
NameError: uninitialized constant PushType::ApplicationControllerMethods
include PushType::ApplicationControllerMethods
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
для этой строки в движке:
initializer 'push_type.application_controller' do
ActiveSupport.on_load :action_controller do
# ActionController::Base.send :include, PushType::ApplicationControllerMethods
include PushType::ApplicationControllerMethods
end
end
Я не знаю, что делаю, учитывая перерыв в изучении языка. но, пытаясь решить эту проблему, я попробовал автозагрузку, касающуюся каталога в движке драгоценного камня, следующим образом:
config.autoload_paths << File.expand_path("../../../app/controllers/concerns", __FILE__) <<
# File.expand_path("../../../app/controllers/concerns/push_type", __FILE__)
File.expand_path("../../../app/helpers", __FILE__)
полный файл engine.rb выглядит так:
module PushType
module Core
class Engine < ::Rails::Engine
isolate_namespace PushType
engine_name 'push_type'
config.autoload_paths << File.expand_path("../../../app/controllers/concerns", __FILE__) <<
# File.expand_path("../../../app/controllers/concerns/push_type", __FILE__)
File.expand_path("../../../app/helpers", __FILE__)
# config.autoload_paths << "#{root}/app/controllers/concerns" <<
# "#{root}/app/controllers/concerns/push_type" <<
# "#{root}/app/helpers"
# lib = root.join("lib")
# config.autoload_once_paths.ignore(
# lib.join("assets"),
# lib.join("tasks"),
# lib.join("generators")
# )
config.generators do |g|
g.assets false
g.helper false
g.test_framework :test_unit, fixture: false
g.hidden_namespaces << 'push_type:dummy' << 'push_type:field'
end
config.assets.precompile += %w(
*.gif *.jpg *.png *.svg *.eot *.ttf *.woff *.woff2
)
config.to_prepare do
Rails.application.eager_load! unless Rails.application.config.cache_classes
end
initializer 'push_type.dragonfly_config' do
PushType.config.dragonfly_secret ||= Rails.application.secrets.secret_key_base
PushType.dragonfly_app_setup!
end
initializer 'push_type.application_controller' do
ActiveSupport.on_load :action_controller do
# ActionController::Base.send :include, PushType::ApplicationControllerMethods
include PushType::ApplicationControllerMethods
end
end
initializer 'push_type.menu_helpers' do
ActiveSupport.on_load :action_view do
include PushType::MenuBuilder::Helpers
end
end
end
end
end
Еще слишком рано, автозагрузка перезагружаемого кода еще не готова в Rails 7.
Однако, как оказалось, это ловушка. Вот почему Rails 7 не позволяет так рано получить доступ к перезагружаемым классам. Поскольку модуль включен в неперезагружаемый класс (AC::Base
), нет смысла перезагружать его, поскольку перезагрузка не будет иметь никакого эффекта для этого включенного модуля.
Пожалуйста, удалите пользовательскую конфигурацию autoload_paths
и добавьте каталоги задач и помощников движка в autoload_once_paths
. Неперезагружаемые классы и модули в этой коллекции доступны ранее.
так что в основном редактирование строки config.autoload_paths
так, чтобы она была config.autoload_once_paths
в движке, как указано выше, у меня не сработало.
есть ли проблема в том, что это находится в инициализаторе движка, который когда-то был в порядке?
Я бы предложил использовать root
в файле конфигурации вместо expand_path
и ..
. Можете ли вы включить ведение журнала (Rails.autoloaders.log!
), вызвать ошибку и поделиться трассировками и текущей конфигурацией?
ок, пути все еще могут быть неправильными. я постараюсь.
Да, оказывается, что root для движка находился внутри директора под названием core. и я имел в виду «#{root}/core/app… бла-бла», все, что мне нужно было сделать, это вынуть /core. совершенно раздражает. Я тоже дам тебе 100 баллов... я перехожу к следующей ошибке.
Потрясающий. Здесь не ради очков, но цените это! Я подписываюсь на SO только для того, чтобы помочь с вопросами, связанными с Zeitwerk (я автор). Пожалуйста, не стесняйтесь следить за ним или открывать новый, если я могу помочь со следующими ошибками, просто упомяните «Zeitwerk», и я его увижу.
Чувак, я ценю тебя, но у меня проблемы с Zeitwerk... какое-то время я был вдали от Rails. очистка этой ошибки сменилась Zeitwerk::Error: loader
этим wants to manage directory /Users/bigchief/Dropbox/Code/Rails/Gems/push_type/core/app/controllers, which is already managed by
бла-бла. но этот каталог даже не включен в набор первого загрузчика Zeitwerk.
Единственное совпадение, по-видимому, заключается в следующем. Загрузчик "rails.main" включает каталоги ``` {"/Users/bigchief/Dropbox/Code/Rails/Gems/push_type/core/app/controllers/concerns/push_type/filterable.rb"=> "/Users/bigchief/Dropbox/Code/Rails/Gems/push_type/core/app/helpers/push_type/application_helper.rb"=> и рельсы.once имеют следующие каталоги {"/Users/bigchief /Dropbox/Code/Rails/Gems/push_type/core/app/controllers/concerns"=> "/Users/bigchief/Dropbox/Code/Rails/Gems/push_type/core/app/helpers"=> ```
О да, это имеет смысл. Это крайний случай, потому что main
теперь рассматривает их как подкаталоги корневого каталога, и библиотека обнаруживает конфликт. Давайте настроим автозагрузчик main
так, чтобы он игнорировал эти подкаталоги: Rails.autoloaders.main.ignore(full path to concerns, full path to helpers)
.
Что бы было в проекте или в драгоценном камне? Есть ли способ сделать это из драгоценного камня, чтобы у любого, кто включит драгоценный камень, не болела голова?
В драгоценном камне просто убедитесь, что вы указали полный путь к каталогам. Как вы знаете, root
в теле класса движка указывает корневой путь движка. Также приятно знать, что config.autoload_*
относится к каждому двигателю. Затем Rails объединяет их все позже, во время процесса загрузки.
к сожалению, выдает ту же ошибку.