acts_as_method_cacheable 0.1.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f01e9ffdf60462d98a0e9d5455058695747e9868
4
+ data.tar.gz: 0aeeb3f23e738298155f413a5db56f35f6a027d6
5
+ SHA512:
6
+ metadata.gz: 450aa54f8f59e259f089ae21b5284efde4190ad6113df9f2f6f6a4514e4eba18c0df5f0e41631c181ea32924c00672303694772c2d429a87985d7ff93e69fcfc
7
+ data.tar.gz: dd58518b62a70508fe5512b1281112533e467df3abba958d553143dd2769862fcfdcad20775ad086e5b0a1c09dcd6c59d32cab2871136dc353488d8343f8af45
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ db/*sqlite3
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ #source 'https://rubygems.org'
2
+ source 'http://ruby.taobao.org'
3
+
4
+ # Specify your gem's dependencies in acts_as_method_cacheable.gemspec
5
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Ben Cao
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,67 @@
1
+ ## acts_as_method_cacheable
2
+
3
+ Instead of writing def expensive { @cached_expensive ||= original_expensive }, now you can write instance.cache_method(:expensive) instead. Also support nested cache method for associations.
4
+ *This gem depend on ActiveSupport/ActiveRecord*
5
+
6
+ ## Currernt Limitation
7
+ *ONLY support method with no params*
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'acts_as_method_cacheable'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install acts_as_method_cacheable
22
+
23
+ ## Usage
24
+
25
+ ### cache method in class level, all instances will have the method cached
26
+ *NOTE!! MUST put acts_as_method_cacheable in the last of the class file*
27
+ ```ruby
28
+ class Post < ActiveRecord::Base
29
+ def expensive_method
30
+ # balababa
31
+ end
32
+ acts_as_method_cacheable :methods => :expensive_method
33
+ end
34
+ ```
35
+
36
+ ### cache methods for a instance only
37
+ ```ruby
38
+ post = Post.find(xxx)
39
+ post.cache_method(:expensive_method)
40
+ post.cache_method([:expensive_method1, :expensive_method2])
41
+ ```
42
+
43
+ ### cache methods for a instance and its associations
44
+ ```ruby
45
+ post = Post.find(xxx)
46
+ post.cache_method([:expensive_method3, :comments => :comment_expensive_method])
47
+ ```
48
+
49
+ ### reload - will clear cache of all cached methods(both class/instance level)
50
+ ```ruby
51
+ post = Post.find(xxx)
52
+ post.cache_method(:expensive_method)
53
+ post.expensive_method # expensive
54
+ post.expensive_method # cheap!
55
+ post.reload
56
+ post.expensive_method # expensive
57
+ ```
58
+
59
+ ### reset cached method for a instance
60
+ ```ruby
61
+ post = Post.find(xxx)
62
+ post.cache_method(:expensive_method)
63
+ post.expensive_method # expensive
64
+ post.expensive_method # cheap!
65
+ post.reset_cache(:expensive_method)
66
+ post.expensive_method # expensive
67
+ ```
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'acts_as_method_cacheable/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "acts_as_method_cacheable"
8
+ spec.version = ActsAsMethodCacheable::VERSION
9
+ spec.authors = ["Ben Cao"]
10
+ spec.email = ["benb88@gmail.com"]
11
+ spec.description = "Make cache methods on ActiveRecord easy!"
12
+ spec.summary = "Instead of writing def expensive { @cached_expensive ||= original_expensive }, now you can write instance.cache_method(:expensive) instead. Also support nested cache method for associations."
13
+ spec.homepage = "https://github.com/bencao/acts_as_method_cacheable"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake", "~> 10.0.4"
23
+ spec.add_development_dependency "rspec", "~> 2.13.0"
24
+ spec.add_development_dependency "mocha", "~> 0.13.3"
25
+ spec.add_development_dependency "sqlite3", "~> 1.3.7"
26
+ spec.add_development_dependency "pry"
27
+ spec.add_development_dependency "pry-theme"
28
+ spec.add_development_dependency "pry-nav"
29
+ spec.add_dependency "activesupport", "~> 3.2.13"
30
+ spec.add_dependency "activerecord", "~> 3.2.13"
31
+ end
data/db/database.yml ADDED
@@ -0,0 +1,5 @@
1
+ development:
2
+ adapter: sqlite3
3
+ database: db/data.sqlite3
4
+ pool: 5
5
+ timeout: 5000
@@ -0,0 +1,131 @@
1
+ require "acts_as_method_cacheable/version"
2
+
3
+ module ActsAsMethodCacheable
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ def self.acts_as_method_cacheable(opts = {})
8
+ unless class_variable_defined?(:@@cached_methods)
9
+ cattr_accessor :cached_methods
10
+ self.cached_methods = []
11
+
12
+ attr_accessor :instance_cache_methods
13
+
14
+ define_method "reload_with_cacheable" do |*params|
15
+ cached_methods.each { |method| reset_cache(method) }
16
+ self.instance_cache_methods && self.instance_cache_methods.each { |method| reset_cache(method) }
17
+ reload_without_cacheable(params)
18
+ end
19
+
20
+ alias_method_chain :reload, :cacheable
21
+
22
+ include Internal
23
+ end
24
+ [opts[:methods]].compact.flatten.each do |method|
25
+ cache_method(method)
26
+ end
27
+ end
28
+ end
29
+
30
+ module Internal
31
+ extend ActiveSupport::Concern
32
+
33
+ module ClassMethods
34
+ # cache_method :expensive_method
35
+ #
36
+ # currently don't support method with params, it's complex to serialize params as a key
37
+ # no param method covers most of our use cases
38
+ private
39
+ def cache_method(method)
40
+ raise "#{method} not defined in class #{self.to_s}" unless method_defined?(method)
41
+ raise "method with params is not supported by acts_as_method_cacheable yet!" unless self.new.method(method.to_sym).arity === 0
42
+
43
+ return if self.cached_methods.include?(method)
44
+
45
+ self.cached_methods.push(method)
46
+
47
+ define_method "#{method}_with_cacheable" do
48
+ unless cache_var_defined?(method)
49
+ cache_var_set(method, send("#{method}_without_cacheable".to_sym))
50
+ end
51
+ cache_var_get(method)
52
+ end
53
+ alias_method_chain method, :cacheable
54
+ end
55
+
56
+ end
57
+
58
+ def reset_cache(method)
59
+ remove_instance_variable(cache_var_name(method)) if cache_var_defined?(method)
60
+ end
61
+
62
+ # instance version cache_method
63
+ # cache_method(:expensive_method)
64
+ # cache_method([:expensive_method, :expensive_method2])
65
+ # cache_method([:expensive_method, :expensive_method2])
66
+ # cache_method([:expensive_method, :sub_associations => :expensive_method2])
67
+ def cache_method(args)
68
+ normalized_args = args.is_a?(Array) ? args : [args]
69
+
70
+ self_items = normalized_args.select{ |item| item.is_a?(Symbol) }
71
+ self_items.each { |self_item| _cache_method(self_item) }
72
+
73
+ children_items = normalized_args.select{ |item| item.is_a?(Hash) }
74
+ children_items.each do |child_item|
75
+ child, child_args = child_item.keys.first, child_item.values.first
76
+ child_instances = send(child)
77
+ child_instances = [child_instances] unless child_instances.respond_to?(:each)
78
+ child_instances.each do |instance|
79
+ instance.cache_method(child_args)
80
+ end
81
+ end
82
+ self
83
+ end
84
+
85
+ private
86
+
87
+ def cache_var_name(method)
88
+ "@cached_var_for_method_#{method}".to_sym
89
+ end
90
+
91
+ def cache_var_set(method, value)
92
+ instance_variable_set(cache_var_name(method), value)
93
+ end
94
+
95
+ def cache_var_get(method)
96
+ instance_variable_get(cache_var_name(method))
97
+ end
98
+
99
+ def cache_var_defined?(method)
100
+ instance_variable_defined?(cache_var_name(method))
101
+ end
102
+
103
+ # method which only accept a symbol as parameter
104
+ def _cache_method(method)
105
+ raise "#{method} not defined in class #{self.class.to_s}" unless self.class.method_defined?(method)
106
+ raise "method with params is not supported by acts_as_method_cacheable yet!" unless method(method.to_sym).arity === 0
107
+
108
+ return if cached_methods.include?(method)
109
+
110
+ self.instance_cache_methods ||= []
111
+
112
+ return if self.instance_cache_methods.include?(method)
113
+
114
+ self.instance_cache_methods.push(method)
115
+
116
+ self.instance_eval <<-CACHEEND, __FILE__, __LINE__ + 1
117
+ class << self
118
+ def #{method}
119
+ unless cache_var_defined?(:#{method})
120
+ cache_var_set(:#{method}, super)
121
+ end
122
+ cache_var_get(:#{method})
123
+ end
124
+ end
125
+ CACHEEND
126
+ end
127
+ end
128
+
129
+ end
130
+
131
+ ActiveRecord::Base.send(:include, ActsAsMethodCacheable)
@@ -0,0 +1,3 @@
1
+ module ActsAsMethodCacheable
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,216 @@
1
+ require 'spec_helper.rb'
2
+
3
+ class Schema < ActiveRecord::Migration
4
+ def change
5
+ create_table :posts do |t|
6
+ t.string :title
7
+ t.string :date
8
+ end
9
+
10
+ create_table :comments do |t|
11
+ t.string :content
12
+ t.string :author
13
+ t.string :date
14
+ t.references :post
15
+ end
16
+ end
17
+ end
18
+ schema = Schema.new
19
+ schema.down
20
+ schema.up
21
+
22
+ require 'acts_as_method_cacheable'
23
+
24
+ class Post < ActiveRecord::Base
25
+ has_many :comments
26
+
27
+ def comment_authors
28
+ comments.map(&:author).join(" ")
29
+ end
30
+
31
+ def comment_contents
32
+ comments.map(&:content).join(" ")
33
+ end
34
+
35
+ def comment_dates
36
+ comments.map(&:date).join(" ")
37
+ end
38
+
39
+ def comment_signatures
40
+ comments.map(&:signature).join(" ")
41
+ end
42
+
43
+ acts_as_method_cacheable :methods => [:comment_authors, :comment_contents]
44
+ end
45
+
46
+ class Comment < ActiveRecord::Base
47
+ belongs_to :post
48
+
49
+ def signature
50
+ sub_signature
51
+ end
52
+
53
+ def sub_signature
54
+ "cool!"
55
+ end
56
+
57
+ acts_as_method_cacheable
58
+ end
59
+
60
+ describe ActsAsMethodCacheable do
61
+
62
+ before(:each) do
63
+ @post = Post.create!(:title => 'test', :date => '2013-04-04')
64
+ @post.comments.create!(:content => 'ct1', :author => 'ben', :date => '2013-04-05')
65
+ @post.comments.create!(:content => 'ct2', :author => 'feng', :date => '2013-04-06')
66
+ @comment1, @comment2 = @post.comments.to_a
67
+ end
68
+
69
+ context "class" do
70
+ it "should return the same result as without cache" do
71
+ @post.comment_authors.should == @comment1.author + " " + @comment2.author
72
+ @post.comment_authors.should == @comment1.author + " " + @comment2.author
73
+ end
74
+
75
+ it "should return the correct result for multiple cache_method" do
76
+ @post.comment_authors.should == @comment1.author + " " + @comment2.author
77
+ @post.comment_authors.should == @comment1.author + " " + @comment2.author
78
+ @post.comment_contents.should == @comment1.content + " " + @comment2.content
79
+ @post.comment_contents.should == @comment1.content + " " + @comment2.content
80
+ end
81
+
82
+ it "should cache method for a class" do
83
+ @comment1.expects(:author).once
84
+ @post.comment_authors
85
+ @comment1.expects(:author).never
86
+ @post.comment_authors
87
+ end
88
+
89
+ it "should clear cache when reload" do
90
+ @post.comment_authors
91
+ @post.reload
92
+ @comment1 = @post.comments.to_a.first
93
+ @comment1.expects(:author).once
94
+ @post.comment_authors
95
+ end
96
+
97
+ it "should raise exception when trying to cache a non-existing method" do
98
+ expect {
99
+ Post.class_eval do
100
+ acts_as_method_cacheable :methods => [:not_exist_method]
101
+ end
102
+ }.to raise_error(Exception, "not_exist_method not defined in class Post")
103
+ end
104
+
105
+ it "should raise exception when trying to cache a method with params" do
106
+ expect {
107
+ Post.class_eval do
108
+ def method_with_params(a, b)
109
+ a + b
110
+ end
111
+ acts_as_method_cacheable :methods => :method_with_params
112
+ end
113
+ }.to raise_error(Exception, "method with params is not supported by acts_as_method_cacheable yet!")
114
+ end
115
+ end
116
+
117
+ context "instance" do
118
+ def assert_for_no_cache_case
119
+ post = Post.find(@post.id)
120
+ comment1 = post.comments.to_a.first
121
+
122
+ post.comment_dates
123
+ comment1.expects(:date).once
124
+ post.comment_dates
125
+
126
+ post.comment_signatures
127
+ comment1.expects(:sub_signature).once
128
+ post.comment_signatures
129
+ end
130
+
131
+ it "should return the same result as not cache" do
132
+ post1 = Post.find(@post.id)
133
+ post1.cache_method(:comment_dates)
134
+ post2 = Post.find(@post.id)
135
+ post1.comment_dates.should == post2.comment_dates
136
+
137
+ post1 = Post.find(@post.id)
138
+ post1.cache_method({:comments => :signature})
139
+ post2 = Post.find(@post.id)
140
+ post1.comment_signatures.should == post2.comment_signatures
141
+ end
142
+
143
+ it "should cache specific method for a instance" do
144
+ post = Post.find(@post.id)
145
+ post.cache_method(:comment_dates)
146
+
147
+ comment1, comment2 = post.comments.to_a
148
+ comment1.expects(:date).once
149
+ post.comment_dates
150
+ comment1.expects(:date).never
151
+ post.comment_dates
152
+
153
+ assert_for_no_cache_case
154
+ end
155
+
156
+ it "should cache methods for a instances and its children instances" do
157
+ post = Post.find(@post.id)
158
+ post.cache_method([:comment_dates, {:comments => :signature}])
159
+
160
+ comment1 = post.comments.to_a.first
161
+
162
+ comment1.expects(:date).once
163
+ post.comment_dates
164
+ comment1.expects(:date).never
165
+ post.comment_dates
166
+
167
+ comment1.expects(:sub_signature).once
168
+ post.comment_signatures
169
+ comment1.expects(:sub_signature).never
170
+ post.comment_signatures
171
+
172
+ assert_for_no_cache_case
173
+ end
174
+
175
+ it "should clear cached after reload" do
176
+ post = Post.find(@post.id)
177
+ post.cache_method([:comment_dates, {:comments => :signature}])
178
+
179
+ comment1, comment2 = post.comments.to_a
180
+
181
+ comment1.expects(:date).once
182
+ post.comment_dates
183
+
184
+ comment1.expects(:sub_signature).once
185
+ post.comment_signatures
186
+
187
+ post.reload
188
+ comment1, comment2 = post.comments.to_a
189
+
190
+ comment1.expects(:date).once
191
+ post.comment_dates
192
+
193
+ comment1.expects(:sub_signature).once
194
+ post.comment_signatures
195
+ end
196
+
197
+ it "should raise exception when trying to cache a non-existing method" do
198
+ expect {
199
+ post = Post.find(@post.id)
200
+ post.cache_method :not_exist_method
201
+ }.to raise_error(Exception, "not_exist_method not defined in class Post")
202
+ end
203
+
204
+ it "should raise exception when trying to cache a method with params" do
205
+ expect {
206
+ Post.class_eval do
207
+ def method_with_params(a, b)
208
+ a + b
209
+ end
210
+ end
211
+ post = Post.find(@post.id)
212
+ post.cache_method(:method_with_params)
213
+ }.to raise_error(Exception, "method with params is not supported by acts_as_method_cacheable yet!")
214
+ end
215
+ end
216
+ end
@@ -0,0 +1,13 @@
1
+ require 'active_support'
2
+ require 'active_record'
3
+ require 'sqlite3'
4
+ require 'pry'
5
+
6
+ ActiveRecord::Base.configurations = YAML::load(IO.read('db/database.yml'))
7
+ ActiveRecord::Base.establish_connection('development')
8
+
9
+ RSpec.configure do |config|
10
+ # == Mock Framework
11
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
12
+ config.mock_with :mocha
13
+ end
metadata ADDED
@@ -0,0 +1,199 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: acts_as_method_cacheable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ben Cao
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-04-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 10.0.4
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 10.0.4
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 2.13.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 2.13.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: mocha
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.13.3
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 0.13.3
69
+ - !ruby/object:Gem::Dependency
70
+ name: sqlite3
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: 1.3.7
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: 1.3.7
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry-theme
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: pry-nav
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: activesupport
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ~>
130
+ - !ruby/object:Gem::Version
131
+ version: 3.2.13
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ~>
137
+ - !ruby/object:Gem::Version
138
+ version: 3.2.13
139
+ - !ruby/object:Gem::Dependency
140
+ name: activerecord
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ~>
144
+ - !ruby/object:Gem::Version
145
+ version: 3.2.13
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ~>
151
+ - !ruby/object:Gem::Version
152
+ version: 3.2.13
153
+ description: Make cache methods on ActiveRecord easy!
154
+ email:
155
+ - benb88@gmail.com
156
+ executables: []
157
+ extensions: []
158
+ extra_rdoc_files: []
159
+ files:
160
+ - .gitignore
161
+ - Gemfile
162
+ - LICENSE.txt
163
+ - README.md
164
+ - Rakefile
165
+ - acts_as_method_cacheable.gemspec
166
+ - db/database.yml
167
+ - lib/acts_as_method_cacheable.rb
168
+ - lib/acts_as_method_cacheable/version.rb
169
+ - spec/acts_as_method_cacheable_spec.rb
170
+ - spec/spec_helper.rb
171
+ homepage: https://github.com/bencao/acts_as_method_cacheable
172
+ licenses:
173
+ - MIT
174
+ metadata: {}
175
+ post_install_message:
176
+ rdoc_options: []
177
+ require_paths:
178
+ - lib
179
+ required_ruby_version: !ruby/object:Gem::Requirement
180
+ requirements:
181
+ - - '>='
182
+ - !ruby/object:Gem::Version
183
+ version: '0'
184
+ required_rubygems_version: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - '>='
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
189
+ requirements: []
190
+ rubyforge_project:
191
+ rubygems_version: 2.0.0.rc.2
192
+ signing_key:
193
+ specification_version: 4
194
+ summary: Instead of writing def expensive { @cached_expensive ||= original_expensive
195
+ }, now you can write instance.cache_method(:expensive) instead. Also support nested
196
+ cache method for associations.
197
+ test_files:
198
+ - spec/acts_as_method_cacheable_spec.rb
199
+ - spec/spec_helper.rb