Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add improved cache hits for ActiveRecord::Relation collections #25

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ gemfile:
- gemfiles/rails_4.0.0_jbuilder_1.5.0.gemfile
- gemfiles/rails_4.0.0_jbuilder_2.0.0.gemfile
- gemfiles/rails_4.1.0_jbuilder_1.5.0.gemfile
- gemfiles/rails_4.1.0_jbuilder_2.0.0.gemfile
- gemfiles/rails_4.1.0_jbuilder_2.0.0.gemfile
- gemfiles/rails_5.0.0_jbuilder_1.5.0.gemfile
- gemfiles/rails_5.0.0_jbuilder_2.0.0.gemfile
4 changes: 3 additions & 1 deletion Appraisals
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
rails_versions = ["~> 3.0.0", "~> 3.1.0", "~> 3.2.0", "~> 4.0.0", "~> 4.1.0", "~> 5.0.0"]
jbuilder_versions = ["~> 1.5.0", "~> 2.0.0"]

rails_versions.each do |r|
rails_versions.each_with_index do |r,ri|
jbuilder_versions.each do |j|
appraise "rails_#{r.match(/\d.*/)} jbuilder_#{j.match(/\d.*/)}" do
gem "railties", r
gem "actionpack", r
gem "jbuilder", j
gem "activerecord", r
gem "sqlite3", '~> 1.3.11'
end
end
end
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ gemspec
gem "rake"
gem "mocha", require: false
gem "appraisal"
gem "test-unit"
gem "test-unit"
35 changes: 16 additions & 19 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,29 @@ PATH
GEM
remote: https://rubygems.org/
specs:
activesupport (5.1.1)
activesupport (5.2.4.4)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (~> 0.7)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
appraisal (2.1.0)
appraisal (2.2.0)
bundler
rake
thor (>= 0.14.0)
concurrent-ruby (1.0.5)
i18n (0.8.4)
jbuilder (2.7.0)
activesupport (>= 4.2.0)
multi_json (>= 1.2)
metaclass (0.0.4)
minitest (5.10.2)
mocha (1.1.0)
metaclass (~> 0.0.1)
multi_json (1.12.1)
power_assert (0.2.2)
rake (10.4.2)
test-unit (3.0.8)
concurrent-ruby (1.1.7)
i18n (1.5.1)
concurrent-ruby (~> 1.0)
jbuilder (2.10.1)
activesupport (>= 5.0.0)
minitest (5.14.2)
mocha (1.11.2)
power_assert (1.2.0)
rake (13.0.1)
test-unit (3.3.6)
power_assert
thor (0.19.1)
thor (1.0.1)
thread_safe (0.3.6)
tzinfo (1.2.3)
tzinfo (1.2.7)
thread_safe (~> 0.1)

PLATFORMS
Expand All @@ -46,4 +43,4 @@ DEPENDENCIES
test-unit

BUNDLED WITH
1.15.1
1.17.3
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
[![Build Status](https://travis-ci.org/quorak/jbuilder_cache_multi.svg?branch=master)](https://travis-ci.org/quorak/jbuilder_cache_multi)

# JbuilderCacheMulti

Useful when you need to retrieve fragments for a collection of objects from the cache. This plugin gives you method called 'cache_collection!' which uses fetch_multi (new in Rails 4.1) to retrieve multiple keys in a single go.
Expand Down Expand Up @@ -68,6 +70,28 @@ You can also conditionally cache a block by using `cache_collection_if!` like th
json.partial! 'person', :person => person
end

### Usage with ActiveRecord::Relation

Sometimes queries can be very complex and populating models from queries with many includes take
up the majority of time. After checking the cache, it is than obvious populating all these models was not
necessary as we have a hit. Why not checking the cache after just using a simple query to build the cache-key
and only fire the complex query for those models, that do not exist in the cache? Well this is possible.

For these cases you can paste the ActiveRecord::Relation and `cache_collection!` will:
1. unscope all `includes` for the initial query to build all cache_key's (make sure you use `joins` for
statements that are use in `where`)
2. gets the result from cache with `Rails.cache.read_multi` for existing cache_key hits
3. gets all missed hits from the database with complex includes and all fields
4. builds the block with all data
5. uses `Rails.cache.write_multi` if available to populate the cache with the missed values



json.cache_collection! Post.includes(:author) do |post|
json.partial! 'post', :post => post
end


## Todo

- Add support for passing a partial name as an argument (e.g. json.cache_collection! @people, partial: 'person') or maybe even just "json.cache_collection! @people" and infer the partial name from the collection...
Expand Down
7 changes: 6 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@ else
require "rails/version"

test.libs << "test"
test.verbose = false
test.warning = false

if Rails::VERSION::MAJOR == 3
test.test_files = %w[test/jbuilder_template_test.rb]
test.test_files = %w[
test/jbuilder_template_test.rb
test/jbuilder_template_active_record_relation_test.rb
]
else
test.test_files = FileList["test/*_test.rb"]
end
Expand Down
6 changes: 4 additions & 2 deletions gemfiles/rails_3.0.0_jbuilder_1.5.0.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
source "https://rubygems.org"

gem "rake"
gem "mocha", :require => false
gem "mocha", require: false
gem "appraisal"
gem "test-unit"
gem "railties", "~> 3.0.0"
gem "actionpack", "~> 3.0.0"
gem "jbuilder", "~> 1.5.0"
gem "activerecord", "~> 3.0.0"
gem "sqlite3", "~> 1.3.11"

gemspec :path => "../"
gemspec path: "../"
31 changes: 19 additions & 12 deletions gemfiles/rails_3.0.0_jbuilder_1.5.0.gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: ..
specs:
jbuilder_cache_multi (0.0.3)
jbuilder_cache_multi (0.1.0)
jbuilder (>= 1.5.0, < 3)

GEM
Expand All @@ -22,24 +22,28 @@ GEM
activesupport (= 3.0.20)
builder (~> 2.1.2)
i18n (~> 0.5.0)
activerecord (3.0.20)
activemodel (= 3.0.20)
activesupport (= 3.0.20)
arel (~> 2.0.10)
tzinfo (~> 0.3.23)
activesupport (3.0.20)
appraisal (2.1.0)
appraisal (2.2.0)
bundler
rake
thor (>= 0.14.0)
arel (2.0.10)
builder (2.1.2)
erubis (2.6.6)
abstract (>= 1.0.0)
i18n (0.5.4)
jbuilder (1.5.3)
activesupport (>= 3.0.0)
multi_json (>= 1.2.0)
json (1.8.3)
metaclass (0.0.4)
mocha (1.1.0)
metaclass (~> 0.0.1)
multi_json (1.11.2)
power_assert (0.2.2)
json (1.8.6)
mocha (1.11.2)
multi_json (1.15.0)
power_assert (1.2.0)
rack (1.2.8)
rack-mount (0.6.14)
rack (>= 1.0.0)
Expand All @@ -51,26 +55,29 @@ GEM
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (~> 0.14.4)
rake (10.4.2)
rake (13.0.1)
rdoc (3.12.2)
json (~> 1.4)
test-unit (3.0.8)
sqlite3 (1.3.13)
test-unit (3.3.6)
power_assert
thor (0.14.6)
tzinfo (0.3.44)
tzinfo (0.3.57)

PLATFORMS
ruby

DEPENDENCIES
actionpack (~> 3.0.0)
activerecord (~> 3.0.0)
appraisal
jbuilder (~> 1.5.0)
jbuilder_cache_multi!
mocha
railties (~> 3.0.0)
rake
sqlite3 (~> 1.3.11)
test-unit

BUNDLED WITH
1.14.6
1.17.3
6 changes: 4 additions & 2 deletions gemfiles/rails_3.0.0_jbuilder_2.0.0.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
source "https://rubygems.org"

gem "rake"
gem "mocha", :require => false
gem "mocha", require: false
gem "appraisal"
gem "test-unit"
gem "railties", "~> 3.0.0"
gem "actionpack", "~> 3.0.0"
gem "jbuilder", "~> 2.0.0"
gem "activerecord", "~> 3.0.0"
gem "sqlite3", "~> 1.3.11"

gemspec :path => "../"
gemspec path: "../"
31 changes: 19 additions & 12 deletions gemfiles/rails_3.0.0_jbuilder_2.0.0.gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: ..
specs:
jbuilder_cache_multi (0.0.3)
jbuilder_cache_multi (0.1.0)
jbuilder (>= 1.5.0, < 3)

GEM
Expand All @@ -22,24 +22,28 @@ GEM
activesupport (= 3.0.20)
builder (~> 2.1.2)
i18n (~> 0.5.0)
activerecord (3.0.20)
activemodel (= 3.0.20)
activesupport (= 3.0.20)
arel (~> 2.0.10)
tzinfo (~> 0.3.23)
activesupport (3.0.20)
appraisal (2.1.0)
appraisal (2.2.0)
bundler
rake
thor (>= 0.14.0)
arel (2.0.10)
builder (2.1.2)
erubis (2.6.6)
abstract (>= 1.0.0)
i18n (0.5.4)
jbuilder (2.0.8)
activesupport (>= 3.0.0, < 5)
multi_json (~> 1.2)
json (1.8.3)
metaclass (0.0.4)
mocha (1.1.0)
metaclass (~> 0.0.1)
multi_json (1.11.2)
power_assert (0.2.2)
json (1.8.6)
mocha (1.11.2)
multi_json (1.15.0)
power_assert (1.2.0)
rack (1.2.8)
rack-mount (0.6.14)
rack (>= 1.0.0)
Expand All @@ -51,26 +55,29 @@ GEM
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (~> 0.14.4)
rake (10.4.2)
rake (13.0.1)
rdoc (3.12.2)
json (~> 1.4)
test-unit (3.0.8)
sqlite3 (1.3.13)
test-unit (3.3.6)
power_assert
thor (0.14.6)
tzinfo (0.3.44)
tzinfo (0.3.57)

PLATFORMS
ruby

DEPENDENCIES
actionpack (~> 3.0.0)
activerecord (~> 3.0.0)
appraisal
jbuilder (~> 2.0.0)
jbuilder_cache_multi!
mocha
railties (~> 3.0.0)
rake
sqlite3 (~> 1.3.11)
test-unit

BUNDLED WITH
1.14.6
1.17.3
6 changes: 4 additions & 2 deletions gemfiles/rails_3.1.0_jbuilder_1.5.0.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
source "https://rubygems.org"

gem "rake"
gem "mocha", :require => false
gem "mocha", require: false
gem "appraisal"
gem "test-unit"
gem "railties", "~> 3.1.0"
gem "actionpack", "~> 3.1.0"
gem "jbuilder", "~> 1.5.0"
gem "activerecord", "~> 3.1.0"
gem "sqlite3", "~> 1.3.11"

gemspec :path => "../"
gemspec path: "../"
Loading