Kohanz
Kohanz

Reputation: 1562

Rails unable to autoload constant only on first attempt

In my Rails 4 app, I have a base model, let's call it Badge, which lives in /app/models/badge.rb.

Then, I have a large number of specific badges that inherit from Badge, let's say GoldBadge and SilverBadge (and many more, in reality). All of these files live in /app/model/badge/<name>_badge.rb. For example, /app/model/badge/gold_badge.rb.

The class declaration for GoldBadge would look like this

class GoldBadge < Badge
  ...

However, the Rails (or Ruby, I don't really know) auto-loader, has trouble locating these files only on the first attempt. What I mean by that is when I first access a page that needs to use GoldBadge, for example, I get the following error:

Unable to autoload constant Badge::GoldBadge, expected /path_to_my_rails_app/app/models/badge/gold_badge.rb to define it

Which is weird, because the class is defined in that file. However, even stranger, is that if I then refresh the page, everything works - the class is found!

On a page where I reference multiple different types of these badges, I have to refresh the page once for each different type, before it will work. For example, if I had a page that used GoldBadge, SilverBadge, and BronzeBadge, I would refresh the page 3 times, with that error being shown once for each badge type, before it would finally work.

This happens in development mode. From what I've read, this might go away in production, but it's still very annoying in development mode. Any way to fix it (preferably without caching classes)?

Upvotes: 2

Views: 1419

Answers (1)

Felix Borzik
Felix Borzik

Reputation: 1230

If you put it under namespace, like app/models/badge folder, you have do define your class like:

class Badge::GoldBadge < Badge
  #...
end

to autoload it and to be able to access it in the way like Badge::GoldBadge. If you want to access it by just calling GoldBadge, then move it to app/models directory.

Upvotes: 2

Related Questions