How to Force Rails to Load All Models

How can I force Rails to load all models?

rails 2:

Dir[Pathname(RAILS_ROOT) + 'app/models/**/*.rb'].each do |path|
require path
end

rails 3:

Dir[Rails.root + 'app/models/**/*.rb'].each do |path|
require path
end

another way:

(ActiveRecord::Base.connection.tables - %w[schema_migrations]).each do |table|
table.classify.constantize rescue nil
end

Rails force models to eager load

With Rails 6, Zeitwerk became the default code loader.

Try the following for eager loading:

Zeitwerk::Loader.eager_load_all

How to manually load all classes inside rails application?

The problem with Ruby is that "all classes" is a somewhat difficult thing to ascertain. Some of them may be generated dynamically and conditionally.

Sometimes you can just load what's present in app/models:

Dir.glob(File.expand_path("app/models/*.rb", Rails.root)).each do |model_file|
require model_file
end

If there's other locations that may contain models you'll need to include those, too.

You might have dependencies, though, and that can preclude model A from loading before model B. This is why the autoloader is used by default and things just aren't loaded in.

The only reliable way to get them all loaded is to somehow exercise them all at least once.

How do I force a Rails query to return potentially two models per result?

I would recommend to search for an alternative, but with the information that you provided and looking to avoid the potential 10001 queries mentioned in your comment, if you have the has_many 'user_my_object_time_matches' setup you could do:

@results = MyObjectTime.joins(:my_object,
"LEFT JOIN user_my_object_time_matches on my_object_times.id = user_my_object_time_matches.my_object_time_id #{additional_left_join_clause}")
.where( search_criteria.join(' and '), *search_values )
.limit(1000)
.order("my_objects.day DESC, my_objects.name")
.paginate(:page => params[:page])
.includes(:user_my_object_time_matches)
.map{|t| [t, t.user_my_object_time_matches]}

Rails model does not load properly

Something looks buggy with respect to Rails 3.2.22 schema loading and STI.
The best workaround I found so far is to force schema reloading for this model using :

Task.connection.schema_cache.clear!
Task.reset_column_information

But then Rails looses track of STI and will miss adding the "type" field to the newly created records. So to force this fields, in every controller required, I added :

@task = (...).becomes(Task)

This feels hacky, but I could not find any better way. Maybe this tip will help someone else. In my case it was not an option to upgrade Rails further or to refactor all the code to get rid of STI.

Eager load all classes before routes.rb being loaded

At this point when routes.rb file is loaded, Widget.available_types is
empty.

I'm not seeing that. Your code seems to work fine for me once I change the name of the class from Widget::a to Widget::Dog to prevent a couple of errors. I also found that I had to kill my terminal window between code changes or else rails c would not reflect my code changes and sometimes would show that Widget.available_types was empty.

If I add a line to your namespace block in routes.rb:

  namespace :widgets do
puts "[ME]: #{Widget.available_types}" #<==== HERE

Widget.available_types.keys.each do |widget_type|
resources widget_type.to_s.pluralize
end

end

then do rails s, I see the following output in the server window :

~/rails_projects/myapp2018$ rails s
=> Booting Puma
=> Rails 5.1.4 application starting in development
=> Run `rails server -h` for more startup options
[ME]: {:dog=>Widget::Dog (call 'Widget::Dog.connection' to establish a connection)}
...
...

That shows that Widgets.available_types is not empty. And in fact, if I enter the following url in my browser:

http://0.0.0.0:3000/widgets/dogs/show

I am taken to the view views/widgets/dogs/show.html.erb. And if I comment out your namespace block in routes.rb, I get a routing error. I think that demonstrates that your code successfully creates dynamic routes.

If I kill my terminal window, and then do rails c, I also see that Widgets.available_types is not empty:

$ rails c
[ME] Widgets.availabe_types: {:dog=>Widget::Dog (call 'Widget::Dog.connection' to establish a connection)}
Running via Spring preloader in process 22753
Loading development environment (Rails 5.1.4)
2.4.0 :001 >

On the other hand, if I do:

$ rake routes

I get:

[ME] Widgets.availabe_types: {}
Prefix Verb URI Pattern Controller#Action
GET /support(/*all)(.:format) redirect(301, path: /contact/%{all})
GET /contact(/*path)(.:format) contacts#show

That does show that Widgets.available_types is empty. I'm not sure why that is.

Rails 4.2: How to force to reload model definition?

@Mariah suggested you a way to reload an instance of a model class, but in case your intention was to really reload the definition of a class, you could do it with this trick:

before_action :reload_model

def reload_model
Object.send(:remove_const, :PaymentRequest)
load 'app/models/payment_request.rb'
end

Beware of side effects like impossibility to access a PaymentRequest from other parts of same instance of your application during that class is reloading. Actually I doubt if doing this in your controller code is a right thing.

Reloading a class may be useful when some constant value should be updated (as it is filled upon first class loading and changed during time). But in case this situation occurs during your application is live, you'd better consider changing constant-based solution to something more appropriate.

Force full object load with eager loading and nested objects

This is going to be difficult to do in only one query. The most straightforward I could get using just ActiveRecord methods was this:

Order.includes(:transactions, line_items: [:product])
.where(id: LineItem.where(product: product).pluck(:order_id))

I don't know much about Arel, but I think it might be able to accomplish this in one query rather than two.



Related Topics



Leave a reply



Submit