mongoid_magic_counter_cache 0.0.1.beta

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## v0.0.1
2
+
3
+ * Initial Release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in mongoid_magic_counter_cache.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Justin Herrick
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,66 @@
1
+ Mongoid Magic Counter Cache
2
+ =======
3
+
4
+ ## DESCRIPTION
5
+
6
+ Mongoid Counter Cache is a simple mongoid extension to add basic counter cache functionality to Embedded and Referenced Mongoid Documents.
7
+
8
+
9
+ ## INSTALLATION
10
+
11
+ ### RubyGems
12
+
13
+ $ [sudo] gem install mongoid_magic_counter_cache
14
+
15
+ ### GemFile
16
+
17
+ gem 'mongoid_magic_counter_cache'
18
+
19
+ ## USAGE
20
+
21
+ First add a field to the document where you will be accessing the counter cache from.
22
+
23
+ class Library
24
+ include Mongoid::Document
25
+
26
+ field :name
27
+ field :city
28
+ field :book_count
29
+ has_many :books
30
+
31
+ end
32
+
33
+ Then in the referrenced/Embedded document. Include `Mongoid::MagicCounterCache`
34
+
35
+ class Book
36
+ include Mongoid::Document
37
+ include Mongoid::MagicCounterCache
38
+
39
+ field :first
40
+ field :last
41
+
42
+ belongs_to :library
43
+ magic_counter_cache :library
44
+ end
45
+
46
+
47
+ => @library.book_count
48
+ => 990
49
+
50
+ ### Alternative Syntax
51
+
52
+ If you do not wish to use the `model_count` naming convention, you can override the defaults by specifying the `:field` parameter.
53
+
54
+ magic_counter_cache :library, :field => "total_amount_of_books"
55
+
56
+ ## TODO
57
+
58
+ 1. Thoroughly Test embedded associations
59
+ 2. Add additional options parameters
60
+ 3. Simplify syntax (I.E. including MagicCounterCache will add counts for all `belongs_to` associations on a document
61
+
62
+
63
+
64
+ ## CONTRIBUTE
65
+
66
+ If you'd like to contribute, feel free to fork and merge until your heart is content
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
Binary file
@@ -0,0 +1,5 @@
1
+ module Mongoid
2
+ module MagicCounterCache
3
+ VERSION = "0.0.1.beta"
4
+ end
5
+ end
@@ -0,0 +1,84 @@
1
+ require 'mongoid'
2
+ require 'pry'
3
+ module Mongoid #:nodoc:
4
+
5
+ # The Counter Cache will yada yada
6
+ #
7
+ # class Person
8
+ # include Mongoid::Document
9
+ #
10
+ # field :name
11
+ # field :feeling_count
12
+ # has_many :feelings
13
+ # end
14
+ #
15
+ # class Feeling
16
+ # include Mongoid::Document
17
+ # include Mongoid::MagicCounterCache
18
+ #
19
+ # field :name
20
+ # belongs_to :person
21
+ # counter_cache :person
22
+ # end
23
+ #
24
+ # Alternative Syntax
25
+ #
26
+ # class Person
27
+ # include Mongoid::Document
28
+ #
29
+ # field :name
30
+ # field :all_my_feels
31
+ # has_many :feelings
32
+ # end
33
+ #
34
+ # class Feeling
35
+ # include Mongoid::Document
36
+ # include Mongoid::MagicCounterCache
37
+ #
38
+ # field :name
39
+ # belongs_to :person
40
+ # counter_cache :person, :field => "all_my_feels"
41
+ # end
42
+ module MagicCounterCache
43
+ extend ActiveSupport::Concern
44
+
45
+ module ClassMethods
46
+
47
+ def counter_cache(*args, &block)
48
+ options = args.extract_options!
49
+ name = options[:class] || args.first.to_s
50
+
51
+ if options[:field]
52
+ counter_name = "#{options[:field].to_s}"
53
+ else
54
+ counter_name = "#{model_name.downcase}_count"
55
+ end
56
+ after_create do |doc|
57
+ if doc.embedded?
58
+ parent = doc._parent
59
+ parent.inc(counter_name.to_sym, 1) if parent.respond_to? counter_name
60
+ else
61
+ relation = doc.send(name)
62
+ if relation && relation.class.fields.keys.include?(counter_name)
63
+ relation.inc(counter_name.to_sym, 1)
64
+ end
65
+ end
66
+ end
67
+
68
+ after_destroy do |doc|
69
+ if doc.embedded?
70
+ parent = doc._parent
71
+ parent.inc(counter_name.to_sym, -1) if parent.respond_to? counter_name
72
+ else
73
+ relation = doc.send(name)
74
+ if relation && relation.class.fields.keys.include?(counter_name)
75
+ relation.inc(counter_name.to_sym, -1)
76
+ end
77
+ end
78
+ end
79
+
80
+ end
81
+ end
82
+
83
+ end
84
+ end
@@ -0,0 +1 @@
1
+ require "mongoid/magic_counter_cache"
@@ -0,0 +1,3 @@
1
+ module MongoidMagicCounterCache
2
+ VERSION = "0.0.1.beta"
3
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "mongoid/magic-counter-cache/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "mongoid_magic_counter_cache"
7
+ s.version = Mongoid::MagicCounterCache::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Justin Herrick"]
10
+ s.email = ["justin@justinherrick.com"]
11
+ s.homepage = "https://github.com/jah2488/mongoid-magic-counter-cache"
12
+ s.summary = %q{Setup Counter Caches in Mongoid Documents}
13
+ s.description = %q{A quick and easy way to add counter cache functionality to model/document associations in Mongoid}
14
+
15
+ s.rubyforge_project = "mongoid_magic_counter_cache"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency("mongoid", "2.2.6")
23
+ s.add_dependency("rake")
24
+ s.add_dependency("bson_ext","~> 1.5")
25
+ s.add_development_dependency "rspec"
26
+ s.add_development_dependency "pry"
27
+ end
@@ -0,0 +1,10 @@
1
+ class Album
2
+ include Mongoid::Document
3
+
4
+ embeds_many :songs
5
+
6
+ field :title
7
+ field :genre
8
+ field :song_count, type: Integer, default: 0
9
+
10
+ end
@@ -0,0 +1,12 @@
1
+ class Book
2
+ include Mongoid::Document
3
+ include Mongoid::MagicCounterCache
4
+
5
+ belongs_to :library
6
+ embeds_many :pages
7
+
8
+ field :title
9
+ field :page_count, :type => Integer, :default => 0
10
+
11
+ counter_cache :library
12
+ end
@@ -0,0 +1,7 @@
1
+ class Feeling
2
+ include Mongoid::Document
3
+ include Mongoid::MagicCounterCache
4
+
5
+ belongs_to :person
6
+ counter_cache :person, :field => "all_my_feels"
7
+ end
@@ -0,0 +1,9 @@
1
+ class Library
2
+ include Mongoid::Document
3
+
4
+ field :title
5
+ field :book_count, :type => Integer, :default => 0
6
+
7
+ has_many :books
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ class Page
2
+ include Mongoid::Document
3
+ include Mongoid::MagicCounterCache
4
+
5
+ embedded_in :book
6
+ counter_cache :book, :type => Integer, :default => 0
7
+
8
+ field :title
9
+ end
@@ -0,0 +1,7 @@
1
+ class Person
2
+ include Mongoid::Document
3
+ has_many :feelings
4
+
5
+ field :name
6
+ field :all_my_feels
7
+ end
@@ -0,0 +1,8 @@
1
+ class Song
2
+ include Mongoid::Document
3
+ include Mongoid::MagicCounterCache
4
+ embedded_in :album
5
+ counter_cache :album
6
+ field :title
7
+ field :track_length
8
+ end
@@ -0,0 +1,202 @@
1
+ #encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ module Mongoid
5
+ describe MagicCounterCache do
6
+
7
+ describe ".counter_cache" do
8
+
9
+ context "when the document is associated" do
10
+
11
+ before do
12
+ Library.delete_all
13
+ end
14
+
15
+ let(:library) do
16
+ Library.new
17
+ end
18
+
19
+ let(:book) do
20
+ Book.new
21
+ end
22
+
23
+ before do
24
+ library.save
25
+ library.books.create(:title => "War and Peace")
26
+ end
27
+
28
+ it "sets the target of the relation" do
29
+ library.books.first.title.should == "War and Peace"
30
+ end
31
+
32
+ it "should have 1 book in books" do
33
+ library.books.size.should == 1
34
+ end
35
+
36
+ it "should have 1 song in counter" do
37
+ library.book_count.should == 1
38
+ end
39
+
40
+ it "should have book_count and relation count equal" do
41
+ library.book_count.should == library.books.size
42
+ end
43
+
44
+ it "sets the counter cache equal to the relation count on addition" do
45
+ 5.times do |n|
46
+ library.books << Book.new
47
+ library.book_count.should == library.books.size
48
+ end
49
+ end
50
+
51
+ it "should increase counter when new books are added" do
52
+ library.books.push( book )
53
+ library.books.size.should == 2
54
+ end
55
+
56
+ it "should increase counter when new books are added" do
57
+ library.books.push( book )
58
+ library.books.size.should == library.book_count
59
+ end
60
+
61
+ it "should increase counter when new books are added" do
62
+ library.books.push( book )
63
+ book.destroy
64
+ library.books.size.should == 1
65
+ end
66
+
67
+ it "should increase counter when new books are added" do
68
+ library.books.push( book )
69
+ book.destroy
70
+ library.books.size.should == library.book_count
71
+ end
72
+
73
+ it "decreases the counter cache when records are deleted" do
74
+ library.book_count.should == library.books.entries.size
75
+ end
76
+
77
+ context "when the referenced document has an embedded document" do
78
+
79
+ let(:page) do
80
+ Page.new
81
+ end
82
+
83
+ before do
84
+ book.pages.create(:title => "it was a long and stormy night")
85
+ library.books << book
86
+ end
87
+
88
+ it "should have 1 page in pages" do
89
+ book.pages.size.should == 1
90
+ end
91
+
92
+ it "should be accessible through parent" do
93
+ library.books.last.pages.size.should == 1
94
+ end
95
+
96
+ it "should have 1 page in counter" do
97
+ book.pages.length.should == book.page_count
98
+ end
99
+
100
+ it "should increase with additional pages" do
101
+ 20.times do |n|
102
+ book.pages.create()
103
+ book.pages.length.should == book.page_count
104
+ end
105
+ end
106
+
107
+ it "should decrease the counter when records are deleted" do
108
+ book.pages.all.destroy
109
+ book.pages.length.should == book.page_count
110
+ end
111
+ end
112
+
113
+ end
114
+ context "when the document is embedded" do
115
+
116
+ before do
117
+ Album.delete_all
118
+ end
119
+
120
+ let(:album) do
121
+ Album.new
122
+ end
123
+
124
+ let(:song) do
125
+ Song.new(:title => "love song")
126
+ end
127
+
128
+ before do
129
+ album.songs.create(:title => "create you a song")
130
+ end
131
+
132
+ it "should have 1 song in songs" do
133
+ album.songs.length.should == 1
134
+ end
135
+
136
+ it "should have correct title" do
137
+ album.songs.first.title.should == "create you a song"
138
+ end
139
+
140
+ it "should have 1 song in counter" do
141
+ album.song_count.should == 1
142
+ end
143
+
144
+ it "sets the counter cache equal to the relation count" do
145
+ album.songs.length.should == album.song_count
146
+ end
147
+
148
+ it "sets the counter cache equal to the relation count on addition" do
149
+ 5.times do |n|
150
+ album.songs << Song.new
151
+ album.songs.length.should == album.song_count
152
+ end
153
+ end
154
+ it "decreases the counter cache when records are deleted" do
155
+ album.songs.all.destroy
156
+ album.songs.length.should == album.song_count
157
+ end
158
+ end
159
+
160
+ context "when the field is specified directly in an associated context" do
161
+
162
+ before do
163
+ Person.delete_all
164
+ end
165
+
166
+ let(:person) do
167
+ Person.new
168
+ end
169
+
170
+ let(:feeling) do
171
+ Feeling.new
172
+ end
173
+
174
+ before do
175
+ person.save
176
+ person.feelings.create
177
+ end
178
+
179
+ it "should have 1 feeling in feelings" do
180
+ person.feelings.size.should == 1
181
+ end
182
+
183
+ it "should have 1 feeling in counter" do
184
+ person.all_my_feels.should == person.feelings.size
185
+ end
186
+
187
+ it "sets the counter cache equal to the relation count on addition" do
188
+ 5.times do |n|
189
+ person.feelings.create
190
+ person.feelings.size.should == person.all_my_feels
191
+ end
192
+ end
193
+ it "decreases the counter cache when records are deleted" do
194
+ person.feelings.push( feeling )
195
+ feeling.destroy
196
+ person.all_my_feels.should == person.feelings.size
197
+ end
198
+ end
199
+ end
200
+
201
+ end
202
+ end
@@ -0,0 +1,20 @@
1
+ require "rubygems"
2
+ require "mongoid"
3
+ require "bundler/setup"
4
+ require "rspec"
5
+ require "pry"
6
+ require File.expand_path("../../lib/mongoid_magic_counter_cache", __FILE__)
7
+
8
+ Mongoid.configure do |config|
9
+ name = "mongoid_magic_counter_cache_test"
10
+ config.master = Mongo::Connection.new.db(name)
11
+ end
12
+
13
+ Dir["#{File.dirname(__FILE__)}/models/*.rb"].each { |f| require f }
14
+
15
+ RSpec.configure do |c|
16
+ c.mock_with :rspec
17
+ c.before(:each) do
18
+ Mongoid.master.collections.select {|c| c.name !~ /system/ }.each(&:drop)
19
+ end
20
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongoid_magic_counter_cache
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.beta
5
+ prerelease: 6
6
+ platform: ruby
7
+ authors:
8
+ - Justin Herrick
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-26 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mongoid
16
+ requirement: &70241193037560 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - =
20
+ - !ruby/object:Gem::Version
21
+ version: 2.2.6
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70241193037560
25
+ - !ruby/object:Gem::Dependency
26
+ name: rake
27
+ requirement: &70241193035840 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70241193035840
36
+ - !ruby/object:Gem::Dependency
37
+ name: bson_ext
38
+ requirement: &70241193033260 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: '1.5'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70241193033260
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: &70241193031820 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70241193031820
58
+ - !ruby/object:Gem::Dependency
59
+ name: pry
60
+ requirement: &70241193029900 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70241193029900
69
+ description: A quick and easy way to add counter cache functionality to model/document
70
+ associations in Mongoid
71
+ email:
72
+ - justin@justinherrick.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - .rspec
79
+ - CHANGELOG.md
80
+ - Gemfile
81
+ - LICENSE
82
+ - README.md
83
+ - Rakefile
84
+ - lib/mongoid/.DS_Store
85
+ - lib/mongoid/magic-counter-cache/version.rb
86
+ - lib/mongoid/magic_counter_cache.rb
87
+ - lib/mongoid_magic_counter_cache.rb
88
+ - lib/mongoid_magic_counter_cache/version.rb
89
+ - mongoid_magic_counter_cache.gemspec
90
+ - spec/models/album.rb
91
+ - spec/models/book.rb
92
+ - spec/models/feeling.rb
93
+ - spec/models/library.rb
94
+ - spec/models/page.rb
95
+ - spec/models/person.rb
96
+ - spec/models/song.rb
97
+ - spec/mongoid/magic_counter_cache_spec.rb
98
+ - spec/spec_helper.rb
99
+ homepage: https://github.com/jah2488/mongoid-magic-counter-cache
100
+ licenses: []
101
+ post_install_message:
102
+ rdoc_options: []
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ segments:
112
+ - 0
113
+ hash: 3833120303120061916
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ! '>'
118
+ - !ruby/object:Gem::Version
119
+ version: 1.3.1
120
+ requirements: []
121
+ rubyforge_project: mongoid_magic_counter_cache
122
+ rubygems_version: 1.8.17
123
+ signing_key:
124
+ specification_version: 3
125
+ summary: Setup Counter Caches in Mongoid Documents
126
+ test_files:
127
+ - spec/models/album.rb
128
+ - spec/models/book.rb
129
+ - spec/models/feeling.rb
130
+ - spec/models/library.rb
131
+ - spec/models/page.rb
132
+ - spec/models/person.rb
133
+ - spec/models/song.rb
134
+ - spec/mongoid/magic_counter_cache_spec.rb
135
+ - spec/spec_helper.rb