Reputation: 1955
I have a pair of ActiveRecord objects that have a belongs_to ... has_many association, with the has_many association being custom-made. Example:
First AR object:
class Car < Vehicle
has_many :wheels, class_name: "RoundObject", foreign_key: :vehicle_id, conditions: "working = 1"
validates_presence_of :wheels
...
end
Second AR object:
class RoundObject < ActiveRecord::Base
belongs_to :vehicle
...
end
Please note that the above is not indicative of my app's function, simply to outline the association between my two AR objects.
The issue I'm having is that, when I reset the cache (and thus my Rails app re-caches all AR objects in the database), when it comes time for the RoundObject
object to get re-cached, it makes multiple calls to the database, one for each unique vehicle_id
associated with the collection of RoundObject
s. The SQL commands being run are output to the console, so this is what my output looked like:
RoundObject Load (2.0ms) SELECT `round_objects`.* FROM `round_objects` WHERE `round_objects`.`vehicle_id` = 28 AND (active = 1)
RoundObject Load (1.0ms) SELECT `round_objects`.* FROM `round_objects` WHERE `round_objects`.`vehicle_id` = 29 AND (active = 1)
RoundObject Load (2.0ms) SELECT `round_objects`.* FROM `round_objects` WHERE `round_objects`.`vehicle_id` = 30 AND (active = 1)
My app has several other AR objects that use the built-in has_many
association without any modifications, and I notice that they only hit the database once when resetting the cache. For instance:
Micropost Load (15.0ms) SELECT `microposts`.* FROM `microposts` INNER JOIN `posts` ON `posts`.`id` = `microposts`.`post_id` WHERE `microposts`.`active` = 1 AND `posts`.`active` = 1
My question is, how can I make my AR object only hit the database once on cache reset, while still maintaining the custom has_many
association I need? Can I manually force a join on the SQL query being called, and will this help?
Thank you!
Upvotes: 3
Views: 314
Reputation: 1202
You can use includes method while calling your Vehicle object to include the RoundObject.
It will go like this:
Vehicle.where(conditions_for_getting_data).includes(:round_object)
Upvotes: 3