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 ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in activerecord_cache.gemspec
4
+ gemspec
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,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -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,9 @@
1
+ module ActiveRecordCache
2
+
3
+ class CachingNotEnabled < StandardError
4
+ end
5
+
6
+ class RecordTypeMismatch < StandardError
7
+ end
8
+
9
+ 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,10 @@
1
+ module ActiveRecordCache
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ TINY = 1
6
+ PRE = nil
7
+
8
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
9
+ end
10
+ 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: []