database_cached_attribute 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: e3ef5688041c2ebdebee855e718969bc6cd71689
4
+ data.tar.gz: 9d6ddf4d939944de4cd165123d61d3a9c8cd0e15
5
+ SHA512:
6
+ metadata.gz: dabf006f76c29f149f7a0cf8663d5f18753270c129e075ed2ca440de752f40a10c6b3a907d4c88a6ea74879638094551b7b668e5c8bd54c3e5c7e7270ec9f1a1
7
+ data.tar.gz: 523acfca93ff269e49dc7631c89a2f480647de6ad29e4734f7dbb934a67bc31b85c70680acfee13e825e89b529d3d69391b2b81c829b364aac2803257066c0da
data/.travis.yml ADDED
@@ -0,0 +1 @@
1
+ language: ruby
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Declare your gem's dependencies in database_cached_attribute.gemspec.
4
+ # Bundler will treat runtime dependencies like base dependencies, and
5
+ # development dependencies will be added by default to the :development group.
6
+ gemspec
7
+
8
+ # Declare any dependencies that are still in development here instead of in
9
+ # your gemspec. These might include edge Rails or gems from your path or
10
+ # Git. Remember to move these dependencies to your gemspec before releasing
11
+ # your gem to rubygems.org.
12
+
13
+ # To use debugger
14
+ # gem 'debugger'
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Charles Smith (github.com/twohlix/)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,6 @@
1
+ database_cached_attribute
2
+ =========================
3
+ [![Code Climate](https://codeclimate.com/github/twohlix/database_cached_attribute.png)](https://codeclimate.com/github/twohlix/database_cached_attribute)
4
+ [![Build Status](https://travis-ci.org/twohlix/database_cached_attribute.png?branch=master)](https://travis-ci.org/twohlix/database_cached_attribute)
5
+
6
+ Ruby gem that adds simple functions to invalidate single columns as a cache on an ActiveRecord models.
data/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'DatabaseCachedAttribute'
12
+ rdoc.options << '--line-numbers'
13
+ #rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ Bundler::GemHelper.install_tasks
18
+
19
+ require 'rspec/core/rake_task'
20
+
21
+ RSpec::Core::RakeTask.new(:spec) do |spec|
22
+ spec.rspec_opts = '--colour'
23
+ end
24
+
25
+ task default: :spec
@@ -0,0 +1,81 @@
1
+ require 'active_support/concern'
2
+
3
+ # DatabaseCachedAttribute adds a method to add a set of easy to use cache invalidation
4
+ # methods/callbacks for specified attributes
5
+ #
6
+ # On the model where you possibly may want to cache things from this model that may
7
+ # be heavy to create:
8
+ # include DatabaseCachedAttribute
9
+ # database_cached_attribute :attribute_name, :another_attribute_name
10
+ # This will create the methods
11
+ # invalidate_attribute_name(optional_object)
12
+ # invalidate_another_attribute_name(optional_object)
13
+ # cache_attribute_name(optional_object)
14
+ # cache_another_attribute_name(optional_object)
15
+ # Which means invalidating that attribute is easy, say when you add an associated object
16
+ # has_many :things, before_add: :invalidate_attribute, before_remove: :invalidate_other_attribute
17
+ #
18
+ module DatabaseCachedAttribute
19
+ extend ActiveSupport::Concern
20
+
21
+ included do
22
+ # Cache invalidation by column
23
+ def invalidate_cache (column_name)
24
+ self[column_name.to_sym] = nil
25
+ update_cache column_name.to_sym
26
+ end
27
+
28
+ # Update cache by column
29
+ def update_cache (column_name)
30
+ save if only_change?(column_name) && persisted?
31
+ end
32
+
33
+ # Determines if the provided column name is the only change
34
+ def only_change? (column_name)
35
+ changes.length == 1 && changes.has_key?(column_name)
36
+ end
37
+
38
+ # Determines if the provided column names are the only changes
39
+ def only_changes? (*column_names)
40
+ return false if changes.length != column_names.length
41
+
42
+ column_names.each do |column_name|
43
+ return false if !changes.has_key?(column_name)
44
+ end
45
+
46
+ true
47
+ end
48
+
49
+ # Determines if the changes, if any, are only in the list of column names provided
50
+ def only_changes_in? (*column_names)
51
+ return false if changes.length > column_names.length
52
+
53
+ our_changes = changes.slice column_names
54
+ return false if our_changes.length < changes.length
55
+
56
+ true
57
+ end
58
+ end
59
+
60
+ module ClassMethods
61
+ # Sets up cache invalidation callbacks for the provided attributes
62
+ def database_cached_attribute(*attrs)
63
+ attrs.each do |attr|
64
+ define_method("invalidate_#{attr}") do |arg=nil| # default arg to allow before_blah callbacks
65
+ invalidate_cache attr.to_sym
66
+ end
67
+
68
+ define_method("only_#{attr}_changed?") do
69
+ only_change? attr.to_sym
70
+ end
71
+
72
+ define_method("cache_#{attr}") do
73
+ update_cache attr.to_sym
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+
80
+
81
+ end
@@ -0,0 +1,7 @@
1
+ module DatabaseCachedAttribute
2
+ VERSION = "0.1.0"
3
+ VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
4
+ VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
5
+ VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
6
+ VERSION_BUILD = VERSION_ARRAY[2] # :nodoc:
7
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :database_cached_attribute do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,144 @@
1
+ require 'temping'
2
+ require 'database_cached_attribute'
3
+
4
+ ActiveRecord::Base.establish_connection("sqlite3:///:memory:")
5
+
6
+ Temping.create :no_include_class do
7
+ with_columns do |t|
8
+ t.string :string_attribute
9
+ t.integer :integer_attribute
10
+ end
11
+ end
12
+ Temping.create :include_class do
13
+ include DatabaseCachedAttribute
14
+ database_cached_attribute :string_attribute
15
+ database_cached_attribute :integer_attribute
16
+
17
+ with_columns do |t|
18
+ t.string :string_attribute
19
+ t.integer :integer_attribute
20
+ end
21
+ end
22
+
23
+ describe DatabaseCachedAttribute do
24
+ # JUST INCLUDED TESTS
25
+ context "included" do
26
+ before do
27
+ @test_obj = IncludeClass.new
28
+ end
29
+
30
+ it "creates functions for invalidating cache" do
31
+ expect(@test_obj.respond_to? :invalidate_cache).to eq(true)
32
+ end
33
+
34
+ it "creates functions for saving cache" do
35
+ expect(@test_obj.respond_to? :update_cache)
36
+ end
37
+
38
+ it "using database_cached_attribute in the model adds nice functions to invalidate cache" do
39
+ expect(@test_obj.respond_to? :invalidate_string_attribute).to eq(true)
40
+ expect(@test_obj.respond_to? :invalidate_integer_attribute).to eq(true)
41
+ expect(@test_obj.respond_to? :invalidate_non_attribute).to eq(false)
42
+ end
43
+
44
+ it "using database_cached_attribute in the model adds nice functions to save caches" do
45
+ expect(@test_obj.respond_to? :cache_string_attribute).to eq(true)
46
+ expect(@test_obj.respond_to? :cache_integer_attribute).to eq(true)
47
+ expect(@test_obj.respond_to? :cache_non_attribute).to eq(false)
48
+ end
49
+ end
50
+
51
+ # NEW OBJECT TESTS
52
+ context "new objects not yet saved" do
53
+ before(:each) do
54
+ @test_obj = IncludeClass.new
55
+ @test_obj.string_attribute = "original string"
56
+ expect(@test_obj.new_record?).to eq(true)
57
+ expect(@test_obj.persisted?).to eq(false)
58
+ end
59
+
60
+ it "does not persist cache updates" do
61
+ @test_obj.cache_string_attribute
62
+ @test_obj.string_attribute = "new string"
63
+ @test_obj.cache_string_attribute
64
+ expect(@test_obj.new_record?).to eq(true)
65
+ expect(@test_obj.persisted?).to eq(false)
66
+ end
67
+
68
+ it "does not persist cache invalidations" do
69
+ @test_obj.invalidate_string_attribute
70
+ @test_obj.string_attribute = "new string"
71
+ @test_obj.invalidate_string_attribute
72
+ expect(@test_obj.new_record?).to eq(true)
73
+ expect(@test_obj.persisted?).to eq(false)
74
+ end
75
+
76
+ it "using .invalidate_attribute_name does change the data" do
77
+ expect(@test_obj.string_attribute).to eq("original string")
78
+ @test_obj.invalidate_string_attribute
79
+ expect(@test_obj.string_attribute).to eq(nil)
80
+ end
81
+
82
+ it "using .cache_attribute_name does not change the data" do
83
+ expect(@test_obj.string_attribute).to eq("original string")
84
+ @test_obj.cache_string_attribute
85
+ expect(@test_obj.string_attribute).to eq("original string")
86
+ end
87
+ end
88
+
89
+ # SAVED OBJECT TESTS
90
+ context "objects persisted in the database" do
91
+ before(:each) do
92
+ @test_obj = IncludeClass.new
93
+ @test_obj.string_attribute = "original string"
94
+ @test_obj.save
95
+ expect(@test_obj.new_record?).to eq(false)
96
+ expect(@test_obj.persisted?).to eq(true)
97
+ end
98
+
99
+ it "persists a cache invalidation" do
100
+ expect(@test_obj.string_attribute).to eq("original string")
101
+ @test_obj.invalidate_string_attribute
102
+ expect(@test_obj.string_attribute).to eq(nil)
103
+ @compare_obj = IncludeClass.last
104
+ expect(@compare_obj.id).to eq(@test_obj.id)
105
+ expect(@compare_obj.string_attribute).to eq(nil)
106
+ end
107
+
108
+ it "persists a cache update" do
109
+ expect(@test_obj.string_attribute).to eq("original string")
110
+ @test_obj.string_attribute = "new string"
111
+ @test_obj.cache_string_attribute
112
+ expect(@test_obj.string_attribute).to eq("new string")
113
+
114
+ @compare_obj = IncludeClass.last
115
+ expect(@compare_obj.id).to eq(@test_obj.id)
116
+ expect(@compare_obj.string_attribute).to eq("new string")
117
+ end
118
+
119
+ it "does not persist cache invalidation with other changes" do
120
+ expect(@test_obj.string_attribute).to eq("original string")
121
+ @test_obj.integer_attribute = 1337
122
+ @test_obj.invalidate_string_attribute
123
+ expect(@test_obj.string_attribute).to eq(nil)
124
+ @compare_obj = IncludeClass.last
125
+ expect(@compare_obj.id).to eq(@test_obj.id)
126
+ expect(@compare_obj.string_attribute).to eq("original string")
127
+ expect(@compare_obj.integer_attribute).to eq(nil)
128
+ end
129
+
130
+ it "does not persist cache updates with other changes" do
131
+ expect(@test_obj.string_attribute).to eq("original string")
132
+ @test_obj.string_attribute = "new string"
133
+ @test_obj.integer_attribute = 1337
134
+ @test_obj.cache_string_attribute
135
+ expect(@test_obj.string_attribute).to eq("new string")
136
+
137
+ @compare_obj = IncludeClass.last
138
+ expect(@compare_obj.id).to eq(@test_obj.id)
139
+ expect(@compare_obj.string_attribute).to eq("original string")
140
+ expect(@compare_obj.integer_attribute).to eq(nil)
141
+ end
142
+ end
143
+
144
+ end
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: database_cached_attribute
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Charles Smith
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 4.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 4.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: activerecord
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '3.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '3.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '3.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '3.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: sqlite3
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
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: temping
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
+ description: Provides simple methods on an ActiveRecord model using an ActiveRecord
112
+ concern to invalidate/save single_column caches.
113
+ email:
114
+ - twohlix@gmail.com
115
+ executables: []
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - lib/database_cached_attribute.rb
120
+ - lib/tasks/database_cached_attribute_tasks.rake
121
+ - lib/database_cached_attribute/version.rb
122
+ - LICENSE
123
+ - Rakefile
124
+ - README.md
125
+ - Gemfile
126
+ - spec/database_cached_attribute_spec.rb
127
+ - .travis.yml
128
+ homepage: http://github.com/twohlix/database_cached_attribute/
129
+ licenses:
130
+ - MIT
131
+ metadata: {}
132
+ post_install_message:
133
+ rdoc_options: []
134
+ require_paths:
135
+ - lib
136
+ required_ruby_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - '>='
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ requirements: []
147
+ rubyforge_project:
148
+ rubygems_version: 2.0.3
149
+ signing_key:
150
+ specification_version: 4
151
+ summary: ActiveRecord Concern to make db caching on ActiveRecord Models simpler
152
+ test_files:
153
+ - spec/database_cached_attribute_spec.rb
154
+ - .travis.yml