activerecord_cache 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +4 -0
- data/README.md +22 -0
- data/Rakefile +2 -0
- data/activerecord_cache.gemspec +21 -0
- data/lib/activerecord_cache/base.rb +57 -0
- data/lib/activerecord_cache/belongs_to_association.rb +21 -0
- data/lib/activerecord_cache/errors.rb +9 -0
- data/lib/activerecord_cache/finder_methods.rb +65 -0
- data/lib/activerecord_cache/railtie.rb +14 -0
- data/lib/activerecord_cache/version.rb +10 -0
- data/lib/activerecord_cache.rb +8 -0
- metadata +69 -0
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# activerecord_cache
|
2
|
+
|
3
|
+
Basic caching for ActiveRecord models using the Rails low-level cache (`Rails.cache`).
|
4
|
+
|
5
|
+
### Installation
|
6
|
+
|
7
|
+
In your Gemfile, add this line:
|
8
|
+
|
9
|
+
gem "activerecord_cache"
|
10
|
+
|
11
|
+
### Usage
|
12
|
+
|
13
|
+
To enable caching for a model:
|
14
|
+
|
15
|
+
class User < ActiveRecord::Baes
|
16
|
+
self.use_activerecord_cache = true
|
17
|
+
end
|
18
|
+
|
19
|
+
Or:
|
20
|
+
|
21
|
+
User.use_activerecord_cache = true
|
22
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'lib/activerecord_cache/version')
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'activerecord_cache'
|
5
|
+
s.version = ActiveRecordCache::VERSION::STRING
|
6
|
+
s.platform = Gem::Platform::RUBY
|
7
|
+
s.authors = ['David Doan']
|
8
|
+
s.email = ['davedoan@gmail.com']
|
9
|
+
s.homepage = 'https://github.com/davedoan/activerecord_cache'
|
10
|
+
s.summary = 'A basic caching plugin for ActiveRecord'
|
11
|
+
s.description = 'Caches ActiveRecord models for simple finds using the Rails low-level cache'
|
12
|
+
|
13
|
+
# s.rubyforge_project = 'activerecord_cache'
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.require_paths = ['lib']
|
17
|
+
|
18
|
+
s.licenses = ['MIT']
|
19
|
+
|
20
|
+
s.add_dependency 'rails', ['~> 3.1.3']
|
21
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module ActiveRecordCache
|
2
|
+
module Base
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
|
7
|
+
class_attribute :use_activerecord_cache, :instance_writer => false
|
8
|
+
self.use_activerecord_cache = false
|
9
|
+
|
10
|
+
extend ActiveRecordCache::Base::CacheMethods
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module CacheMethods
|
16
|
+
def cache_key(id_or_record)
|
17
|
+
unless use_activerecord_cache
|
18
|
+
message = "ActiveRecord cache is not enabled for #{self.name}"
|
19
|
+
raise ActiveRecordCache::CachingNotEnabled, message
|
20
|
+
end
|
21
|
+
|
22
|
+
if id_or_record.is_a?(ActiveRecord::Base)
|
23
|
+
id = id_or_record[id_or_record.class.primary_key]
|
24
|
+
else
|
25
|
+
id = id_or_record
|
26
|
+
end
|
27
|
+
|
28
|
+
"#{name}:#{id}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def find_through_cache(id)
|
32
|
+
unless use_activerecord_cache
|
33
|
+
message = "ActiveRecord cache is not enabled for #{self.name}"
|
34
|
+
raise ActiveRecordCache::CachingNotEnabled, message
|
35
|
+
end
|
36
|
+
|
37
|
+
Rails.cache.fetch(cache_key(id)) { where(primary_key => id).first }
|
38
|
+
end
|
39
|
+
|
40
|
+
def write_to_cache(record)
|
41
|
+
unless use_activerecord_cache
|
42
|
+
message = "ActiveRecord cache is not enabled for #{self.name}"
|
43
|
+
raise ActiveRecordCache::CachingNotEnabled, message
|
44
|
+
end
|
45
|
+
|
46
|
+
unless record.class == self
|
47
|
+
message = "Instance of #{self} expected, got #{record.class}"
|
48
|
+
raise ActiveRecordCache::RecordTypeMismatch, message
|
49
|
+
end
|
50
|
+
|
51
|
+
Rails.cache.write(cache_key(record), record)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ActiveRecordCache
|
2
|
+
module BelongsToAssociation
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
alias_method_chain :find_target, :caching
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
protected
|
11
|
+
|
12
|
+
def find_target_with_caching
|
13
|
+
if klass.use_activerecord_cache
|
14
|
+
klass.find_through_cache(owner[reflection.foreign_key])
|
15
|
+
else
|
16
|
+
find_target_without_caching
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module ActiveRecordCache
|
2
|
+
module FinderMethods
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.module_eval do
|
6
|
+
alias_method_chain :find_by_attributes, :caching
|
7
|
+
alias_method_chain :find_some, :caching
|
8
|
+
alias_method_chain :find_one, :caching
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
def find_by_attributes_with_caching(match, attributes, *args)
|
15
|
+
unless cached_lookup_allowed? && attributes == Array(@klass.primary_key) # must only be finding by primary key
|
16
|
+
return find_by_attributes_without_caching(match, attributes, *args)
|
17
|
+
end
|
18
|
+
|
19
|
+
ids = Array(args.first)
|
20
|
+
|
21
|
+
results = case match.finder
|
22
|
+
when :all then ids.map {|id| @klass.find_through_cache(id)}.compact
|
23
|
+
when :first then @klass.find_through_cache(ids.first)
|
24
|
+
when :last then @klass.find_through_cache(ids.last)
|
25
|
+
end
|
26
|
+
|
27
|
+
results
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def find_some_with_caching(ids)
|
32
|
+
return find_some_without_caching(ids) unless cached_lookup_allowed?
|
33
|
+
|
34
|
+
results = ids.map {|id| @klass.find_through_cache(id)}.compact
|
35
|
+
|
36
|
+
if results.size != ids.size
|
37
|
+
error = "Couldn't find all #{@klass.name.pluralize} with IDs "
|
38
|
+
error << "(#{ids.join(", ")}) (found #{result.size} results, but was looking for #{ids.size})"
|
39
|
+
raise ActiveRecord::RecordNotFound, error
|
40
|
+
end
|
41
|
+
|
42
|
+
results
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def find_one_with_caching(id)
|
47
|
+
return find_one_without_caching(id) unless cached_lookup_allowed?
|
48
|
+
|
49
|
+
record = @klass.find_through_cache(id)
|
50
|
+
|
51
|
+
unless record
|
52
|
+
raise ActiveRecord::RecordNotFound, "Couldn't find #{@klass.name} with #{primary_key}=#{id}"
|
53
|
+
end
|
54
|
+
|
55
|
+
record
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
# only support the most basic lookups through the cache
|
60
|
+
def cached_lookup_allowed?
|
61
|
+
@klass.use_activerecord_cache && arel.where_sql.nil? && @limit_value.nil? && @offset_value.nil?
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'activerecord_cache'
|
2
|
+
require 'rails'
|
3
|
+
|
4
|
+
class ActiveRecordCache::Railtie < Rails::Railtie
|
5
|
+
|
6
|
+
initializer "activerecord_cache.initialize" do
|
7
|
+
ActiveSupport.on_load(:active_record) do
|
8
|
+
ActiveRecord::Base.send(:include, ActiveRecordCache::Base)
|
9
|
+
ActiveRecord::FinderMethods.send(:include, ActiveRecordCache::FinderMethods)
|
10
|
+
ActiveRecord::Associations::BelongsToAssociation.send(:include, ActiveRecordCache::BelongsToAssociation)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module ActiveRecordCache
|
2
|
+
end
|
3
|
+
|
4
|
+
require File.join(File.dirname(__FILE__), 'activerecord_cache/base')
|
5
|
+
require File.join(File.dirname(__FILE__), 'activerecord_cache/finder_methods')
|
6
|
+
require File.join(File.dirname(__FILE__), 'activerecord_cache/belongs_to_association')
|
7
|
+
|
8
|
+
require 'activerecord_cache/railtie.rb' if defined?(Rails)
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: activerecord_cache
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- David Doan
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-02-14 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: &2167650840 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.1.3
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2167650840
|
25
|
+
description: Caches ActiveRecord models for simple finds using the Rails low-level
|
26
|
+
cache
|
27
|
+
email:
|
28
|
+
- davedoan@gmail.com
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- Gemfile
|
34
|
+
- README.md
|
35
|
+
- Rakefile
|
36
|
+
- activerecord_cache.gemspec
|
37
|
+
- lib/activerecord_cache.rb
|
38
|
+
- lib/activerecord_cache/base.rb
|
39
|
+
- lib/activerecord_cache/belongs_to_association.rb
|
40
|
+
- lib/activerecord_cache/errors.rb
|
41
|
+
- lib/activerecord_cache/finder_methods.rb
|
42
|
+
- lib/activerecord_cache/railtie.rb
|
43
|
+
- lib/activerecord_cache/version.rb
|
44
|
+
homepage: https://github.com/davedoan/activerecord_cache
|
45
|
+
licenses:
|
46
|
+
- MIT
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options: []
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
requirements: []
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 1.8.15
|
66
|
+
signing_key:
|
67
|
+
specification_version: 3
|
68
|
+
summary: A basic caching plugin for ActiveRecord
|
69
|
+
test_files: []
|