Is there any reason to use rails’ constantize instead of ruby’s const_get to look up a class given its name? Constantize is more complicated, and the documentation didn’t make it clear what that complexity is for.
The docs refer to the fact that:
The name is assumed to be the one of a top-level constant
class Thing end class User class Thing end const_get("Thing") # => returns User::Thing "Thing".constantize # => returns ::Thing end
Which is usually what you want when dealing with strings that represent models.
Another way in which it is useful is that it’s a method on String, so it fits nicely with the other methods that you can chain:
"user/things".singularize.camelize.constantize # => User::Thing
Thanks for the explanation. Would sticking “::” on the front of the string to const_get, if not already present, then be equivalent (except for the chaining)?
Looking at the code there’s actually another edge case that is covered by
const_get's behavior is a bit weird:
Object.const_get("::User::User::User") => User "::User::User::User" => NameError: uninitialized constant User
Odd, I get the NameError from both cases.
Did you have a
User class, though?
Try the following:
class Example end Object.const_get("::Example::Example::Example").name # => "Example"
This does not raise for me using Ruby 2.5.7.
Must be different in 2.6.
$ cat test.rb class Example end Object.const_get("::Example::Example::Example").name $ ruby test.rb Traceback (most recent call last): 1: from test.rb:4:in `<main>' test.rb:4:in `const_get': uninitialized constant Example::Example (NameError) $ ruby --version ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-darwin19]
Indeed! I also get an exception on 2.6 & 2.7. Didn’t know that this changed, good to know