Chisle
The coding-agent plugin that bills 52% of a bare model across 20 live tasks. Terse persona + tool-output compressor + context diet.
Just the right amount of Rails eager loading
Translation pending
Developer toolsRuby · ShellGitHub @salsifySelf-installOwner unconfirmed
Paste into Claude or ChatGPT for installation instructions suited to your environment.
Have you tried it? One tap is enough. No sign-in needed.
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Wouldn't it be awesome if ActiveRecord didn't make you think about eager loading and it just did the "right" thing by default? With Goldiloader it can!
This branch only supports Rails 7.2+ with Ruby 3.2+. For older versions of Rails/Ruby use release-5.x, release-4.x, release-3.x, release-2.x or release-1.x.
Consider the following models:
class Blog < ActiveRecord::Base
has_many :posts
end
class Post < ActiveRecord::Base
belongs_to :blog
end
Here are some sample queries without the Goldiloader:
> blogs = Blog.limit(5).to_a
# SELECT * FROM blogs LIMIT 5
> blogs.each { |blog| blog.posts.to_a }
# SELECT * FROM posts WHERE blog_id = 1
# SELECT * FROM posts WHERE blog_id = 2
# SELECT * FROM posts WHERE blog_id = 3
# SELECT * FROM posts WHERE blog_id = 4
# SELECT * FROM posts WHERE blog_id = 5
Here are the same queries with the Goldiloader:
> blogs = Blog.limit(5).to_a
# SELECT * FROM blogs LIMIT 5
> blogs.each { |blog| blog.posts.to_a }
# SELECT * FROM posts WHERE blog_id IN (1,2,3,4,5)
Whoa! It automatically loaded all of the posts for our five blogs in a single database query without specifying any eager loads! Goldiloader assumes that you'll access all models loaded from a query in a uniform way. The first time you traverse an association on any of the models it will eager load the association for all the models. It even works with arbitrary nesting of associations.
Read more about the motivation for the Goldiloader in this blog post.
Add this line to your application's Gemfile:
gem 'goldiloader'
And then execute:
$ bundle
Or install it yourself as:
$ gem install goldiloader
By default all associations will be automatically eager loaded when they are first accessed so hopefully most use cases should require no additional configuration. Note you're still free to explicitly eager load associations via eager_load, includes, or preload.
You can disable automatic eager loading with auto_include query scope method:
Blog.order(:name).auto_include(false)
Note this will not disable automatic eager loading for nested associations.
Like the rest of Rails, find_by_sql and async_find_by_sql ignore the current scope, so they take an auto_include
option instead. Their models otherwise share one context and stay in memory as long as any of them does:
Blog.find_by_sql(sql, auto_include: false)
Automatic eager loading can be disabled for specific associations by customizing the association's scope:
class Blog < ActiveRecord::Base
has_many :posts, -> { auto_include(false) }
end
Automatic eager loading can be disabled globally disabled for all threads:
# config/initializers/goldiloader.rb
Goldiloader.globally_enabled = false
Automatic eager loading can then be selectively enabled for particular sections of code:
# Using a block form
Goldiloader.enabled do
# Automatic eager loading is enabled for the current thread
# ...
end
# Using a non-block form
Goldiloader.enabled = true
# Automatic eager loading is enabled for the current thread
# ...
Goldiloader.enabled = false
Similarly, you can selectively disable automatic eager loading for particular sections of code in a thread local manner:
# Using a block form
Goldiloader.disabled do
# Automatic eager loading is disabled for the current thread
# ...
end
# Using a non-block form
Goldiloader.enabled = false
# Automatic eager loading is disabled for the current thread
# ...
Goldiloader.enabled = true
Note Goldiloader.enabled=, Goldiloader.enabled, and Goldiloader.disabled are thread local to ensure
proper thread isolation in multi-threaded servers like Puma.
Models dumped with ActiveRecord.marshalling_format_version = 7.1 (the default under config.load_defaults 7.1
and later), or with the ActiveRecord::MessagePack cache serializer, no longer know which models they were
loaded with once read back from a cache, so each association loads one model at a time. Goldiloader::Cache.fetch
reads them from Rails.cache and, on a cache hit, restores automatic eager loading for them and for the models of
their loaded associations. Its block must return a model, an array of models or nil:
blogs = Goldiloader::Cache.fetch('blogs', expires_in: 1.hour) { Blog.includes(:posts).to_a }
blogs.each { |blog| blog.posts.each { |post| post.author } } # One query for all authors
This is the beginning of the README. Read the rest at the original. Read the full README ↗