9

I'm having a problem with a module name and the folder structure.

I have a model defined as

module API
  module RESTv2
    class User
    end
  end
end

The folder structure looks like

models/api/restv2/user.rb

When trying to access the class, I get an uninitialized constant error. However, if I change the module name to REST and the folder to /rest, I don't get the error.

I assume the problem has to do with the naming of the folder, and I've tried all different combos of /rest_v_2, /rest_v2, /restv_2, etc.

Any suggestions?

1
  • 3
    By Rails convention, you've named your module incorrectly. RESTv2 should be RestV2. Commented Jun 17, 2013 at 14:54

2 Answers 2

12

Rails uses the 'underscore' method on a module or class name to try and figure out what file to load when it comes across a constant it doesn't know yet. When you run your module through this method, it doesn't seem to give the most intuitive result:

"RESTv2".underscore
# => "res_tv2"

I'm not sure why underscore makes this choice, but I bet renaming your module dir to the above would fix your issue (though I think I'd prefer just renaming it to "RestV2 or RESTV2 so the directory name is sane).

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

3 Comments

This actually makes perfect sense, it's the string RESTv2 that doesn't follow convention. The assumption is that the first word is some kind of acronym like "PIN", and the second word is an uppercase word like "Importer": PINImporter => pin_importer, UUIDGenerator => uuid_generator, AESCracker => aes_cracker, RESTv2 => res_tv2, etc etc. In all cases of CamelCase conversion, It's not "CamelC ase", it's "Camel Case". The space is injected before the final uppercase letter, not after.
I suspect the case of "v" is what causes the word break before the "T".
If you're being an exceptional noob like me today, make sure you're using rails console instead of just irb
5

You'll need to configure Rails to autoload in the subdirectories of the app/model directory. Put this in your config/application.rb:

config.autoload_paths += Dir["#{config.root}/app/models/**/"]

Then you should be able to autoload those files.

Also, your likely filename will have to be app/model/api/res_tv2/user.rb, as Rails uses String.underscore to determine the filename. I'd just call it API::V2::User to avoid headaches, unless you have more than one type of API.

Comments

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.