Alan Oliveira

Joined

60 Experience
0 Lessons Completed
0 Questions Solved

Activity

It seems not to be possible,
The best I could find is described below, but both are terrible.

Create a scope overriding preload_associations to force the preloader get the data from the cache

def preload_associations(records)
  ActiveRecord::Associations::Preloader.new(records: records, associations: :category, available_records: Category.all_from_my_awesome_cache).call
  super
end

Override association to manually load the record before it tries to fetch from db

def association(name)
  super.tap do |assoc|
    next if assoc.loaded? || assoc.reflection.class_name != "Category"
    assoc.target = Category.all_from_my_awesome_cache.find { it.id == assoc.owner.category_id }
    assoc.loaded!
  end
end

After all, the best way is the simplest one, just override category method on Book class

class Category < ActiveRecord::Base
  # columns: name
  has_many :books
end

class Book < ActiveRecord::Base
  # columns: title, category_id
  belongs_to :category
end

Given the above example, let's suppose Category rarely changes and categories table is quite small but it can't be an enum.
Is there any way to cache Category.all and use it in all future Book.includes(:category)?