当我在开发模式下启动服务器后浏览页面时,一切都很好.
但是在单个代码更改(甚至添加空格)之后,每个页面请求都会显示以下错误.
Unable to autoload constant User,expected
/path/to/my/rails-app/app/models/user.rb to define it
该文件完全存在于那里并定义了类:
class User < ActiveRecord::Base …
我在application.rb中用config.autoload_paths和config.eager_load_paths尝试了很多东西,但没有运气.
停用弹簧也没有帮助.
开发应用程序并在每次更改后必须重新启动服务器才能显示90秒.
$rails -v Rails 4.2.4 $ruby -v ruby 2.1.7p400 (2015-08-18 revision 51632) [x86_64-linux]
一些相关的配置:
development.rb
MyApp::Application.configure do # Settings specified here will take precedence over those in config/application.rb # In the development environment your application's code is reloaded on # every request. This slows down response time but is perfect for development # since you don't have to restart the webserver when you make code changes. config.cache_classes = false # Do not eager load code on boot. This avoids loading your whole application # just for the purpose of running a single test. If you are using a tool that # preloads Rails for running tests,you may have to set it to true. config.eager_load = false # Show full error reports and disable caching config.consider_all_requests_local = true config.action_controller.perform_caching = false # Don't care if the mailer can't send config.action_mailer.raise_delivery_errors = false # Print deprecation notices to the Rails logger config.active_support.deprecation = :log # Only use best-standards-support built into browsers config.action_dispatch.best_standards_support = :builtin # Do not compress assets config.assets.compress = false # Expands the lines which load the assets config.assets.debug = true config.action_mailer.delivery_method = :test config.action_mailer.default_url_options = { host: 'localhost',port: 3000 } end
application.rb中
module Serviceportal class Application < Rails::Application # 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' [… some asset precompile stuff …] # Configure the default encoding used in templates for Ruby 1.9. config.encoding = 'utf-8' # Custom directories with classes and modules you want to be autoloadable. config.autoload_paths += Dir["#{config.root}/app/mailers","#{config.root}/app/controllers/concerns","#{config.root}/app/models/concerns","#{config.root}/app/decorators/concerns","#{config.root}/lib","#{config.root}/lib/shared" ] config.eager_load_paths += Dir["#{config.root}/app/mailers","#{config.root}/lib/shared"] # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. config.time_zone = 'Berlin' # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. # config.i18n.load_path += Dir[Rails.root.join('my','locales','*.{rb,yml}').to_s] config.i18n.default_locale = :de [… some sql and active support stuff …] config.action_controller.include_all_helpers = false config.action_controller.action_on_unpermitted_parameters = :raise # Do not swallow errors in after_commit/after_rollback callbacks. config.active_record.raise_in_transactional_callbacks = true end end
编辑:错误主要出现在以下函数的lib / auth / user_proxy.rb中.也许这有助于缩小可能原因的范围.
def self.usertype_allowed?(type) [ User,TempCustomer ].include? type.classify.safe_constantize rescue false end
编辑2:将编辑1中的类名称字符串化(感谢@Benjamin Sinclaire).但只会导致下一个错误.我也可以避免使用类.但是在app / controllers / concerns / security.rb中出现以下错误时,没有什么可以改变?
Unable to autoload constant User,expected
/path/to/my/rails-app/app/models/user.rb to define it
码:
def set_current_user User.current = current_user end
当前用户保存在线程中(代码来自/path/to/my/rails-app/app/models/user.rb
def self.current Thread.current['current_user'] end def self.current=(user) Thread.current['current_user'] = user end
只是再次说清楚:它在服务器重新开发之后工作,直到我在某处更改某些代码.
解决方法
代替
class Parent::Sub::Child end
做
module Parent module Sub class Child end end end
2检查模型关联定义,确保永远不会使用常量.请改用字符串.
代替
belongs_to :manager,class_name: User
做
belongs_to :manager,class_name: 'User'
3刚看到你的编辑.你能这样重构吗?
# I assume `type` is a string or such,so we can compare classes # names instead of constants,and get rid of `safe_constantize` def self.usertype_allowed?(type) ['User','TempCustomer'].include? type.classify rescue false end
4在Thread存储中序列化活动记录对象不是一个好主意.将其更改为存储用户ID,如下所示:
def set_current_user User.current = current_user.id end def self.current Thread.current['current_user_id'] end def self.current=(user_id) Thread.current['current_user_id'] = user_id end