join_cache
Faster ActiveRecord associations using Rails cache.
What?
Let's say you scaffolded your Rails app and ended up with this:
class Employee < ActiveRecord::Base
has_and_belongs_to_many :teams
end
Retrieving the teams of one employee generates an inner join:
bob.teams
=> Team Load SELECT "teams".* FROM "teams" INNER JOIN "employees_teams" ON "teams"."id" = "employees_teams"."team_id" WHERE "employees_teams"."employee_id" = ? [["employee_id", 1]]
The gem join_cache generates methods to store the team ids in cache:
bob.cached_team_ids
=> [4, 8, 15, 16, 23, 42]
bob.cached_teams
=> Team.where(id: [4, 8, 15, 16, 23, 42])
=> Team Load SELECT "teams".* FROM "teams" WHERE "teams"."id" IN (4, 8, 15, 16, 23, 42)
Usage
In your gemfile:
gem 'join_cache'
In your model:
class Employee < ActiveRecord::Base
has_and_belongs_to_many :teams
include JoinCache # make sure to add this *after* listing the associations
end
It also works with has_many :through
associations!
class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients, through: :appointments
include JoinCache
end
freud.patients
=> Patient Load SELECT "patients".* FROM "patients" INNER JOIN "appointments" ON "patients"."id" = "appointments"."patient_id" WHERE "appointments"."physician_id" = ? [["physician_id", 1]]
freud.cached_patient_ids
=> [4, 8, 15, 16, 23, 42]
freud.cached_patients
=> Patient.where(id: [4, 8, 15, 16, 23, 42])
=> Patient Load SELECT "patients".* FROM "patients" WHERE "patients"."id" IN (4, 8, 15, 16, 23, 42)
Take a look at this example app.
Performance
I ran a very scientific study using Heroku, PostgreSQL, the example app, its seeds.rb and speed.rake files. Shorter means better:
See? 30% faster!
TODO
Contributing to join_cache
- Fork the project.
- Start a feature/bugfix branch.
- Commit and push until you are happy with your contribution.
I came here looking for Johnny Cash
Here you go:
Copyright
Copyright (c) 2013 Kevin Bongart. See LICENSE.txt for further details.