Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading class descendants in rails development

I need to be able to see all of the class descendants from a controller when I go into the rails console locally. I have this Api::BaseController which all my Api controller inherit from. The issue I have is when I hop in to the rails console to check which Api controller are in the descendants, it comes up empty until I call them. This probably has something to do with how the classes in development aren't eager loaded, and they're not cached locally.

sample_app$ rails c
Loading development environment (Rails 4.2.0)
2.1.5 :001 > Api::BaseController.descendants
 => []
2.1.5 :002 > Api::V1::FoosController
 => Api::V1::FoosController
2.1.5 :003 > Api::BaseController.descendants
 => [Api::V1::FoosController]

From this example, you can see when I call descendants on the Api::BaseController the first time, it's an empty array. After calling one of the controllers that class will be then loaded and will show up as a descendant. In this case, there could be an any number of controllers in V1 as well as V2, V3, etc...

As a stupid ugly hack, I could do

Dir.glob("#{Rails.root.join('app', 'controllers', 'api', 'v1')}/**/*.rb").each(&method(:require_dependency))

but I don't want to have to write that each time I enter the console. I'm also working on a gem, and definitely don't want to put this sort of code in my gem.

The other option is caching classes in development, but that causes a huge issues on it's own. Anyone have any ideas?

Edit Another option would be to call Rails.application.eager_load!. This option would work fine if I could specify only controllers in my API folder. Then I wouldn't have to eager load the entire app, but just a small subset of controllers that I need.

like image 692
jeremywoertink Avatar asked Apr 15 '15 23:04

jeremywoertink


1 Answers

I found the following post: http://avinmathew.com/using-rails-descendants-method-in-development/

In short it says the following:

In enviroments/development.rb add the following:

config.eager_load_paths += Dir['path/to/files/*.rb']
ActionDispatch::Reloader.to_prepare do
  Dir['path/to/files/*.rb'].each {|file| require_dependency file}
end

The first line adds the path that should be loaded when you start your app (or console) and the rest tells rails to reload the classes on each request.

like image 162
Aguardientico Avatar answered Sep 28 '22 07:09

Aguardientico