2

I'm using a Ruby on Rails 5.2.8 and Ruby 2.7.8 version and I have found a bug in code. The code should check at runtime if a model is defined. At first I tried to use the defined? method, but because the development environment lazy loads the modules I have encountered unexpected (for me) behaviour:

defined?(ModelToCheck) #=> nil
ModelToCheck
defined?(ModelToCheck) #=> true

so only after using the model it appears to be defined. What is the best way to check if it is defined?

P.S.

the option which configures the lazy loading is:

# config/environments/development.rb
ExampleApp::Application.configure do
  config.eager_load = false

  # rest of the config
  # ...
end

For now I tried to use also Object.const_defined? method, but the same story again.

I have two ideas:

  • don't check at runtime if the model is defined at all
  • use a begin rescue blocks to handle NameError when it is not defined, however it is ugly and I wouldn't like to use it if I could
2
  • Why do you need to check it? What is use case? Commented Apr 25, 2024 at 8:40
  • Please give a minimal example to reproduce this behavior Commented Apr 25, 2024 at 8:56

1 Answer 1

1

Since the author of the questions did not want to use #defined? or Object.const_defined? due to autoloading issues, I came up with another solution.

Yet the best solution would be to fix the autoloading issue, but it's hard to judge that without knowing the internals of the project.


A way to achieve this is is using #missing_name or #missing_name? and rescuing the thrown NameError:

begin
  HelloWorld
rescue NameError => e
  e.missing_name
end
# => "HelloWorld"

See the docs for more details.

Since you find that ugly you can also wrap this into a method something like this:

def check_defined(constant)
  !!Oject.const_get(constant)

rescue NameError => e
  !e.missing_name?(constant)
end
Sign up to request clarification or add additional context in comments.

2 Comments

@engineersmnky Yes only #missing_name? takes a name argument. I corrected that. The point of the question was the the author did not want to use #const_defined? because of autoloading issues. That is why I used it as shown in my answer.
Thank you for your answer It is the answer I was afraid to find, however I guess it's the only one which solves the problem!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.