activerecord_cache 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []