如何解决on_file_autoloaded':预期文件invitations_controller.rb 定义常量InvitationsController,但没有Zeitwerk::NameError
我的 ctrlpanel 应用程序又回来了。
我将它 100% 投入开发,并完成了将其加载到 Heroku 并启动应用程序、安装 gems 的过程。 DB 在那里(主要是),但我什至在 DB 之前就遇到了问题。我在处理 devise_invitable 时遇到错误,我没有进入开发阶段。令我惊讶的是,当我在我的笔记本电脑上启动生产时,我确实遇到了同样的错误,这对我来说至少是令人震惊的,因为在开发过程中一切都很完美。所以我知道这不是 Heroku 问题,我很高兴至少我可以重现它。完整错误如下,但专门处理错误的行是:
"C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/zeitwerk-2.4.2/lib/zeitwerk/loader/callbacks.rb:18:in `on_file_autoloaded': expected file D:/rails/ctrlpanel/app/controllers/invitations_controller.rb to define constant InvitationsController,but didn't (Zeitwerk::NameError)C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/zeitwerk-2.4.2/lib/zeitwerk/loader/callbacks.rb:18:in `on_file_autoloaded': expected file D:/rails/ctrlpanel/app/controllers/invitations_controller.rb to define constant InvitationsController,but didn't (Zeitwerk::NameError)"
我在网上做了一些搜索(实际上很多),我唯一能找到的建议是将invitations_controller.rb 文件复制到controllers 文件夹下名为users 的文件夹中,我确实尝试过,我做了一个实际上是它的副本,我也尝试移动它。两者都没有帮助。这在开发中正常工作。所以我开始比较 2 个环境文件。
我通过更改这 2 个条目克服了它:
config.cache_classes = false in production.rb
config.eager_load = false in production.rb
然而,我看到到处都有帖子说关闭这 2 个选项非常糟糕,它会以某种方式影响视图,而且我的引导程序都是 caddywhompused,我只能假设是由于这 2 个选项被关闭。我敢肯定其他人以前一定见过这个,但我似乎找不到任何东西。我检查了 devise_invitable 文档,将其更新为 v .02 更高(无效)。
错误太长了,我很难找到合适的搜索词来获得结果。
我很困惑,因为一切都必须正确,否则在开发中就无法正常工作,或者我不会这么认为?如果有任何其他文件需要查看,请告诉我,我很乐意显示。
预先感谢您提供的任何帮助或建议。
斯科特
这里是错误:
scottm@RED-IT-LAP-0001 MINGW64 /d/rails/ctrlpanel (master)
$ rails server -e production
=> Booting Puma
=> Rails 6.1.3.2 application starting in production
=> Run `bin/rails server --help` for more startup options
Exiting
Traceback (most recent call last):
67: from bin/rails:14:in `<main>'
66: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
65: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
64: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
63: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
62: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
61: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/railties-6.1.3.2/lib/rails/commands.rb:18:in `<main>'
60: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/railties-6.1.3.2/lib/rails/command.rb:50:in `invoke'
59: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/railties-6.1.3.2/lib/rails/command/base.rb:69:in `perform'
58: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/thor-1.1.0/lib/thor.rb:392:in `dispatch'
57: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/thor-1.1.0/lib/thor/invocation.rb:127:in `invoke_command'
56: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/thor-1.1.0/lib/thor/command.rb:27:in `run'
55: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/railties-6.1.3.2/lib/rails/commands/server/server_command.rb:135:in `perform'
54: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/railties-6.1.3.2/lib/rails/commands/server/server_command.rb:135:in `tap'
53: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/railties-6.1.3.2/lib/rails/commands/server/server_command.rb:144:in `block in perform'
52: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/railties-6.1.3.2/lib/rails/commands/server/server_command.rb:39:in `start'
51: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/rack-2.2.3/lib/rack/server.rb:311:in `start'
50: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/rack-2.2.3/lib/rack/server.rb:379:in `handle_profiling'
49: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/rack-2.2.3/lib/rack/server.rb:312:in `block in start'
48: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/rack-2.2.3/lib/rack/server.rb:422:in `wrapped_app'
47: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/rack-2.2.3/lib/rack/server.rb:249:in `app'
46: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/rack-2.2.3/lib/rack/server.rb:349:in `build_app_and_options_from_config'
45: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/rack-2.2.3/lib/rack/builder.rb:66:in `parse_file'
44: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/rack-2.2.3/lib/rack/builder.rb:105:in `load_file'
43: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/rack-2.2.3/lib/rack/builder.rb:116:in `new_from_string'
42: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/rack-2.2.3/lib/rack/builder.rb:116:in `eval'
41: from config.ru:3:in `block in <main>'
40: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/activesupport-6.1.3.2/lib/active_support/dependencies.rb:332:in `require'
39: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/activesupport-6.1.3.2/lib/active_support/dependencies.rb:299:in `load_dependency'
38: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/activesupport-6.1.3.2/lib/active_support/dependencies.rb:332:in `block in require'
37: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/zeitwerk-2.4.2/lib/zeitwerk/kernel.rb:34:in `require'
36: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
35: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
34: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
33: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
32: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
31: from D:/rails/ctrlpanel/config/environment.rb:5:in `<main>'
30: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/railties-6.1.3.2/lib/rails/railtie.rb:207:in `method_missing'
29: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/railties-6.1.3.2/lib/rails/railtie.rb:207:in `public_send'
28: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/railties-6.1.3.2/lib/rails/application.rb:384:in `initialize!'
27: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/railties-6.1.3.2/lib/rails/initializable.rb:60:in `run_initializers'
26: from C:/Ruby27-x64/lib/ruby/2.7.0/tsort.rb:205:in `tsort_each'
25: from C:/Ruby27-x64/lib/ruby/2.7.0/tsort.rb:226:in `tsort_each'
24: from C:/Ruby27-x64/lib/ruby/2.7.0/tsort.rb:347:in `each_strongly_connected_component'
23: from C:/Ruby27-x64/lib/ruby/2.7.0/tsort.rb:347:in `call'
22: from C:/Ruby27-x64/lib/ruby/2.7.0/tsort.rb:347:in `each'
21: from C:/Ruby27-x64/lib/ruby/2.7.0/tsort.rb:349:in `block in each_strongly_connected_component'
20: from C:/Ruby27-x64/lib/ruby/2.7.0/tsort.rb:431:in `each_strongly_connected_component_from'
19: from C:/Ruby27-x64/lib/ruby/2.7.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
18: from C:/Ruby27-x64/lib/ruby/2.7.0/tsort.rb:228:in `block in tsort_each'
17: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/railties-6.1.3.2/lib/rails/initializable.rb:61:in `block in run_initializers'
16: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/railties-6.1.3.2/lib/rails/initializable.rb:32:in `run'
15: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/railties-6.1.3.2/lib/rails/initializable.rb:32:in `instance_exec'
14: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/railties-6.1.3.2/lib/rails/application/finisher.rb:133:in `block in <module:Finisher>'
13: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/zeitwerk-2.4.2/lib/zeitwerk/loader.rb:508:in `eager_load_all'
12: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/zeitwerk-2.4.2/lib/zeitwerk/loader.rb:508:in `each'
11: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/zeitwerk-2.4.2/lib/zeitwerk/loader.rb:393:in `eager_load'
10: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/zeitwerk-2.4.2/lib/zeitwerk/loader.rb:393:in `synchronize'
9: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/zeitwerk-2.4.2/lib/zeitwerk/loader.rb:404:in `block in eager_load'
8: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/zeitwerk-2.4.2/lib/zeitwerk/loader.rb:725:in `ls'
7: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/zeitwerk-2.4.2/lib/zeitwerk/loader.rb:725:in `foreach'
6: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/zeitwerk-2.4.2/lib/zeitwerk/loader.rb:733:in `block in ls'
5: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/zeitwerk-2.4.2/lib/zeitwerk/loader.rb:409:in `block (2 levels) in eager_load'
4: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/zeitwerk-2.4.2/lib/zeitwerk/loader.rb:409:in `const_get'
3: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/zeitwerk-2.4.2/lib/zeitwerk/kernel.rb:26:in `require'
2: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/zeitwerk-2.4.2/lib/zeitwerk/kernel.rb:26:in `tap'
1: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/zeitwerk-2.4.2/lib/zeitwerk/kernel.rb:27:in `block in require'
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/zeitwerk-2.4.2/lib/zeitwerk/loader/callbacks.rb:18:in `on_file_autoloaded': expected file D:/rails/ctrlpanel/app/controllers/invitations_controller.rb to define constant InvitationsController,but didn't (Zeitwerk::NameError)
这里是 routes.rb 文件:
Catalog::Application.routes.draw do
resources :redline_filters
resources :certifications
resources :routes do
resources :waypoints,only: [:show,:destroy]
end
resources :dealerships do
collection do
get 'index_public'
get 'deduplicate'
end
resources :visits
end
resources :items do
resources :variants,except: :index do
resources :snapshots
end
end
resources :crosses do
collection do
get 'index_public'
end
end
root to: 'static_pages#home'
devise_for :users,controllers: { invitations: 'users/invitations' }
resources :locations,:categories,:gfe_users,:trips,:vendors,:work_orders
resources :attachments,only: [:destroy]
get '/gfe_reporting',to: 'gfe_users#reporting'
resources :users do
get 'toggle_suspend'
end
resources :charges do
collection do
post 'import'
end
end
resources :products do
match 'submit' => 'products#submit',via: [:get,:post]
match 'publish' => 'products#publish',:post]
match 'in_progress' => 'products#in_progress',:post]
# collection { post :search,to: 'products#index' } ## ransack crap.
end
resources :devices do
resources :trips
end
# match "/home" => 'static_pages#home'
match "/catalog" => 'static_pages#catalog',:post]
match "product/:name" => "products#index",:post]
get "static_pages/products"
get "static_pages/catalog"
get "static_pages/help"
get "static_pages/roi"
get "/roi",to: "static_pages#roi"
match 'device_lookup',to: 'devices#lookup',:post]
match 'device_first_avaiable_serial',to: 'devices#first_available_serial',:post]
match 'device_battery_is_dead' => 'devices#update_status_to_dead_battery',:post]
match 'device_is_missing' => 'devices#is_missing',:post]
match 'device_has_water_damage' => 'devices#update_status_to_water_damage',:post]
match 'device_is_rma' => 'devices#update_status_to_rma',:post]
match 'device_is_healthy' => 'devices#is_healthy',:post]
match 'pending_trip' => 'trips#pending_trip',:post]
match 'complete_trip' => 'trips#complete_trip',:post]
# The priority is based upon order of creation:
# first created -> highest priority.
# Sample of regular route:
# match 'products/:id' => 'catalog#view'
# Keep in mind you can assign values other than :controller and :action
# Sample of named route:
# match 'products/:id/purchase' => 'catalog#purchase',:as => :purchase
# This route can be invoked with purchase_url(:id => product.id)
# Sample resource route (maps HTTP verbs to controller actions automatically):
# resources :products
# Sample resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Sample resource route with sub-resources:
# resources :products do
# resources :comments,:sales
# resource :seller
# end
# Sample resource route with more complex sub-resources
# resources :products do
# resources :comments
# resources :sales do
# get 'recent',:on => :collection
# end
# end
# Sample resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
# You can have the root of your site routed with "root"
# just remember to delete public/index.html.
# root :to => 'welcome#index'
# See how all your routes lay out with "rake routes"
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
# match ':controller(/:action(/:id))(.:format)'
end
这是invitations_controller.rb 文件:
class User::InvitationsController < Devise::InvitationsController
def new
if cannot?(:invite,User)
raise CanCan::AccessDenied
else
super
end
end
def create
if cannot?(:invite,User)
raise CanCan::AccessDenied
else
self.resource = resource_class.invite!(resource_params,current_inviter)
unless resource.role.present?
resource.role = "creator"
resource.save
end
if resource.errors.empty?
set_flash_message :notice,:send_instructions,:email => self.resource.email
respond_with resource,:location => after_invite_path_for(resource)
else
respond_with_navigational(resource) { render :new }
end
end
end
private
def resource_params
params.permit(user: [:name,:email,:invitation_token,:location_id])[:user]
end
end
这是 application_controller.rb 文件:
class ApplicationController < ActionController::Base
protect_from_forgery prepend: true
#before_filter :configure_permitted_parameters,if: :devise_controller?
before_action :configure_permitted_parameters,if: :devise_controller?
#before_filter :authenticate_user!
before_action :authenticate_user!
#check_authorization :unless => :devise_controller?
after_action :unless => :devise_controller?
before_action :set_paper_trail_whodunnit
rescue_from CanCan::AccessDenied do |exception|
redirect_to root_url,:alert => exception.message
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up,keys: [ :first_name,:last_name,:email] )
devise_parameter_sanitizer.permit(:account_update,:phone,:email ] )
devise_parameter_sanitizer.permit(:invite,keys: [ :name,:location_id ] )
end
end
以防万一这里还有 application.rb 文件
require_relative "boot"
require "rails/all"
# Require the gems listed in Gemfile,including any gems
# you've limited to :test,:development,or :production.
Bundler.require(*Rails.groups)
module Catalog #Ctrlpanel
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 6.1
config.before_configuration do
env_file = File.join(Rails.root,'config','local_env.yml')
YAML.load(File.open(env_file)).each do |key,value|
ENV[key.to_s] = value
end if File.exists?(env_file)
end
config.autoload_paths += %W(#{config.root}/lib)
config.encoding = "utf-8"
config.time_zone = 'Pacific Time (US & Canada)'
config.active_record.default_timezone = :local
config.filter_parameters += [:password]
config.active_support.escape_html_entities_in_json = true
# Enable pdf.css precompiling for wicked_pdf
config.assets.precompile += %w( pdf.css print.css awesome-bootstrap-checkBox.css jquery.dataTables.min.css )
# Force Heroku to not access the DB or load models when precompiling your assets.
config.assets.initialize_on_precompile = false
# Use sql instead of Active Record's schema dumper when creating the database.
# This is necessary if your schema can't be completely dumped by the schema dumper,# like if you have constraints or database-specific column types
# config.active_record.schema_format = :sql
# Enforce whitelist mode for mass assignment.
# This will create an empty whitelist of attributes available for mass-assignment for all models
# in your app. As such,your models will need to explicitly whitelist or blacklist accessible
# parameters by using an attr_accessible or attr_protected declaration.
# This breaks the application 3/30/2021 Scott Milella
config.active_record.whitelist_attributes = true
# Enable the asset pipeline
config.assets.enabled = true
# Version of your assets,change this if you want to expire all your assets
config.assets.version = '1.0'
# Configuration for the application,engines,and railties goes here.
#
# These settings can be overridden in specific environments using the files
# in config/environments,which are processed later.
#
# config.time_zone = "Central Time (US & Canada)"
# config.eager_load_paths << Rails.root.join("extras")
# No Method Error message 3/31/2021 Scott Milella
#config.active_record.raise_in_transactional_callbacks = true
end
end
解决方法
将 invitations_controller.rb
移动到 app/controllers/users
文件夹的建议是正确的。这是与您的路线匹配的路径:
devise_for :users,controllers: { invitations: 'users/invitations' }
以及您的控制器命名空间:
class User::InvitationsController < Devise::InvitationsController
这里的关键词是移动 - 如果您在 app/controllers/invitations_controller.rb
中留下了此文件的副本,Zeitwerk 可能仍会由于命名空间而在尝试在生产中预加载您的代码时遇到问题/文件系统不匹配。
如果您将文件移动到其预期位置,但仍然出现错误,则说明其他原因正在发生,值得进一步调查。
,今天早上我想通了。
我了解了一个名为: rails zeitwerk:检查 --trace
当我运行它时,它给了我这个特定的错误: 等等,我很想加载应用程序。 预期文件 app/controllers/users/invitations_controller.rb 定义常量 Users::InvitationsController
当我查看我的用户模型时,主类声明是这样写的: class User::InvitationsController
模型的名称是 user.rb,因此根据我使用其他语言的经验,我假设类名和模型名必须匹配,但我尝试将其重命名为: 类用户::邀请控制器 我在 Users::InvitationsController 中添加了 s,然后我再次运行了 zeitwerk:check --trace 并且它通过了,然后我尝试将应用程序加载到生产中,你知道它有什么作用?
因此,在我的情况下,解决方案分为两部分:
1 谢谢@Scott Matthewman,他告诉我实际上需要将invitations_contoller.rb 移动到名为users 的控制器下的文件夹中
/app/controllers/users.
2 我必须在类声明中将 User 重命名为 Users(如果这是 Ruby/Rails 中的术语)。
从:
User::InvitationsController
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。