"Unable to autoload constant User" error when changed code in development
Same problem but in an engine w/ namespaces. No issues in production or in development until a code-change / autoload.
The solution was to
- checking for double definitions (there were none)
- checking if the module nesting strictly follows rails conventions in the filesystem.
I've had myns
under myengine/app/myns/subns/obj.rb
but myns
is being ignored as it is at the root of the app folder, so moving the myns
folder into a subfolder myengine/app/lib/myns
solved the issue.
Note: the rails error message was very explicit about the module nesting (while still pointing to the wrong .rb file in the filesystem) so look closely at the error. The error was 'Unable to autoload constant subns/obj.rb in .../myns/subns/obj.rb'. Rails suggesting the incorrect file-location (which exists) is misleading in this case.
You don't need include app/models/concerns
and app/controllers/concerns
in your autoload/ eagerload paths as they are included by default in Rails 4: https://signalvnoise.com/posts/3372-put-chubby-models-on-a-diet-with-concerns
Also make sure that your concerns are defined as modules, extend ActiveSupport::Concern
and with the appropriate file name
#taggable.rb
module Taggable
extend ActiveSupport::Concern
end
Another cause of your problem might be that some modules/ classes in app/decorators/concerns
, lib
, lib/shared
are using the User
class
which is not loaded yet or some of it's dependencies are not loaded so try adding require_relative path_to_user.rb
at the top of those files
-----Edit-------
Try adding at the top of lib/auth/user_proxy.rb
require_dependency 'app/models/user'
This way you'll remove any ambiguity in autoloading the User
class and you won't mess around with Rails autoloading see more here: http://guides.rubyonrails.org/autoloading_and_reloading_constants.html#require-dependency , http://guides.rubyonrails.org/autoloading_and_reloading_constants.html#common-gotchas
1 See if you have any multiple-level class or module declaration done one one line and change them to be declared in several lines.
Instead of
class Parent::Sub::Child
end
Do
module Parent
module Sub
class Child
end
end
end
2 Check your model association definitions, and ensure you are never using constant. Use string instead.
Instead of
belongs_to :manager, class_name: User
Do
belongs_to :manager, class_name: 'User'
3 Just saw your edit. Can you refactor like this?
# 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 Not a good idea to serialize an active record object in the Thread storage. Change it to store the user id instead, like this:
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