Ruby on Rails. Uninitialized constant

carrierwave, ruby, ruby-on-rails

Solution

A general answer

You have a chicken or egg case as far as rails autoloader is concerned, the "rails way" of solving this in a general sense would be to refactor the metacode so that the class names get passed as string values rather than classes, for example:

belongs_to :manager, class_name: "Employee"

`belongs_to` will call `constantize` on `class_name` hopefully at a time when all classes have been loaded so the chicken and egg issue is circumvented "the rails way".

What @Stoic suggested is essentially a variation of this theme of circumventing the evaluation of `image.rb` at `image_uploader.rb` load time:

model.class.const_get("THUMB_WIDTH")

could also have been phrased as:

'Image'.constantize.const_get("THUMB_WIDTH")

and result is the same and the general lesson to take from this is: avoid using another class name literals in class load-time code or in other words `belongs_to :manager, class_name: "Employee"` is good and `belongs_to :manager, class_name: Employee` would be bad.

It's not pretty, but its probably the most elegant universal way to avoid these headaches

A problem specific answer

A different way of looking at the problem is that thumbnail icon width is actually a concern of the uploader and not of the model and that you're in fact seeing a fringe case of inappropriate intimacy code smell (http://www.codinghorror.com/blog/2006/05/code-smells.html).

Watch out for classes that spend too much time together, or classes that interface in inappropriate ways. Classes should know as little as possible about each other.

So, if you are of this school of thought (I'm leaning in this direction) the solution would be to make `THUMB_WIDTH` a constant of the `ImageUploader` class and the problem goes away.

It's generally a good idea to separate different domain concerns out of the models anyway as the models like to get bloated and unmanageable - you could view the uploader class as a service class of your model designed to extract a particular domain problem much in the same way value objects, form objects etc get handled in http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/

Plan C would be to switch places of `config.autoload_paths` in your `application.rb` and cross fingers :)

Problem

This is odd, but: Uploader class (app/uploaders): ``` class ImageUploader < CarrierWave::Uploader::Base include CarrierWave::RMagick # .... version :thumb, from_version: :preview do process resize_to_limit: [Image::THUMB_WIDTH] end ``` Image class (app/models): ``` class Image < ActiveRecord::Base include Rails.application.routes.url_helpers mount_uploader :image, ImageUploader THUMB_WIDTH = 220 PREVIEW_WIDTH = 460 MAX_WIDTH = 960 ``` The application says: `uninitialized constant Image::THUMB_WIDTH` ``` version :thumb, from_version: :preview do process resize_to_limit: [Image::THUMB_WIDTH] #<<<---- end version :preview, from_version: :fullsize do ``` What's wrong? UPDATE: Agis pointed out the reason. Bounty for the best solution to this problem will be applied in 2 days. I don't like code separation, e.g. making a new class holding all the constants for the Image class in initializers etc. This solutions is bad because it it brings inconsistency and code fragmentation.

Original source