0

I am working on a Ruby on Rails 6 project, and I am trying to use a class instance variable on an ActiveRecord model. Here is a basic example:

class Model << ApplicationRecord
  @var = AnotherClass.new
  
  class << self
    attr_reader :var
  end
  
  # ...
end

I would then like to be able to use Model.var to access Model's instance of AnotherClass. There are multiple such models, each of them referring to a different AnotherClass, with all the AnotherClasses being subclasses of some BaseClass.

However, I am encountering the following error:

uninitialized constant Model::AnotherClass

Because of the class << self, Ruby seems to be looking for a nested class.

Is there a way to access AnotherClass directly, or is there a better way in general to set this up?

Edit: I solved this with a completely different approach, however I'm still interested to see how you would get around this issue.

2
  • The error you encounter is telling you that the constant AnotherClass is not found. Are you sure that is is loaded? Where is AnotherClass located? Anything in lib/ is not covered by the autoloader and you will need to require 'another_class' first in those scenarios (or add it to the autoload path). Commented Feb 7, 2021 at 22:00
  • @3limin4t0r Thanks, I discovered this about ten 10 seconds before you posted the comment. ;) If you post an answer, I will accept it. Commented Feb 7, 2021 at 22:02

1 Answer 1

2

The error you receive:

uninitialized constant Model::AnotherClass

Tells you that AnotherClass is not initialized (not loaded/found). Let me use the following context as an example:

class Model
  AnotherClass
end

Ruby will start a constant lookup. This will start from the current namespace (Model) and and if nothing is found move up into the namespace tree. In the above example it will first look for Model::AnotherClass if that cannot be found it will look for AnotherClass, if that cannot be found it will throw the exception you receive.

This error simply tells you that AnotherClass is not loaded.

Anything in th app/ directory is loaded by the autoloader of Rails, however if you use the lib/ directory you have to manually require 'another_class' or add the relevant path to the autoload paths.

Sign up to request clarification or add additional context in comments.

3 Comments

This explains a lot. I didn't realize that Ruby will first look for Model::AnotherClass before AnotherClass. I solved this by moving the lib/ directory to app/lib/ as suggested here.
@JacobLockard alternatively, you can precede a constant with :: to make Ruby look for it at the top-level, i.e. ::AnotherClass
@Stefan That would normally work, but it didn't in my case because another_class.rb was not being loaded by Rails at all.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.