0

Rails 4.2.0 / Ruby 2.2.1

I am facing inconsistent behaviour when using defined? to check if a class having given name exists or not. I want to avoid rescuing exceptions thus using the predicate method. But as can be seen below it is returning inconsistent results. This behaviour causes some of my code written in a controller to fail.

$ rails c 
Loading development environment (Rails 4.2.0) 
2.2.1 :001 > defined?(User) 
=> "constant" 

2.2.1 :002 > defined?(AuthenticationToken) 
=> nil 

2.2.1 :003 > AuthenticationToken 
=> AuthenticationToken (call 'AuthenticationToken.connection' to establish a connection) 

2.2.1 :004 > defined?(AuthenticationToken) 
=> "constant"

I also tried using Kernel.const_defined? but same inconsistent behaviour is found.

$ rails c
Loading development environment (Rails 4.2.0)
2.2.1 :001 > Kernel.const_defined?('Role')
 => false 
2.2.1 :002 > Kernel.const_defined?('AuthenticationToken')
 => false 
2.2.1 :003 > AuthenticationToken
 => AuthenticationToken (call 'AuthenticationToken.connection' to establish a connection) 
2.2.1 :004 > Kernel.const_defined?('AuthenticationToken')
 => true 

Is there any standard way to make that code behave in consistent manner?

Thanks.

Jignesh Gohel
  • 6,236
  • 6
  • 53
  • 89

1 Answers1

0

The root issue is that in development mode rails loads your application code on demand - these constants are genuinely not defined.

This is done via the const_missing hook and const_defined? is explicitly documented as not triggering const_missing. Actually using the constant will trigger const_missing.

You could try turning on config.eager_load to cause rails to load all of your code at startup but this will make starting the rails console, running take tasks etc slower. I'm also not sure how it combines with the development mode code reloading.

Frederick Cheung
  • 83,189
  • 8
  • 152
  • 174