mongoid_magic_counter_cache 1.1.0 → 1.1.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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/CHANGELOG.md +4 -0
- data/README.md +55 -4
- data/lib/mongoid/magic-counter-cache/version.rb +1 -1
- data/lib/mongoid/magic_counter_cache.rb +16 -3
- data/lib/mongoid_magic_counter_cache/version.rb +1 -1
- data/spec/models/article.rb +2 -0
- data/spec/models/post.rb +2 -0
- data/spec/models/update_comment.rb +11 -0
- data/spec/models/update_review.rb +10 -0
- data/spec/mongoid/magic_counter_cache_spec.rb +297 -1
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 25296ae82c14af47df70fe8096ad2244fa467048
|
4
|
+
data.tar.gz: 78bd144a9aa04db9793d77c00dca4d921278d7f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 08eb70d110aee1c08194d6edeab68721b313c2589213bce32b1cf6c2cdbb2832a1ceafa1a9b95d36647e737130cc5ffde187569ef04cb063c4f5cc6ff123be34
|
7
|
+
data.tar.gz: 527f217433cc05a4e1a6bfe1797c02f06336526613243f98f9dd90db47fe7f194bf9265cc52b8d4735451853ea8ed9311a33b7ec308090a057a7c1d49cb29369
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
## v1.1.1
|
2
|
+
|
3
|
+
* Add :if_update option in order to allow counter to be conditionally increment/decrement counter when an update is made to a referenced/embedded object.
|
4
|
+
|
1
5
|
## v1.0.0
|
2
6
|
|
3
7
|
* Remove version dependency to work with rails 4. Breaks compatibility with ruby 1.9.2 and older
|
data/README.md
CHANGED
@@ -61,13 +61,64 @@ If you do not wish to use the `model_count` naming convention, you can override
|
|
61
61
|
counter_cache :library, :field => "total_amount_of_books"
|
62
62
|
````
|
63
63
|
|
64
|
-
## TODO
|
65
64
|
|
66
|
-
|
67
|
-
|
65
|
+
### Conditional Counter
|
66
|
+
|
67
|
+
If you want to maintain counter based on certain condition, then you can specify it using `:if`
|
68
|
+
|
69
|
+
````rb
|
70
|
+
class Post
|
71
|
+
include Mongoid::Document
|
72
|
+
|
73
|
+
field :article
|
74
|
+
field :comment_count
|
75
|
+
|
76
|
+
has_many :comments
|
77
|
+
|
78
|
+
end
|
79
|
+
````
|
80
|
+
Then in the referrenced/Embedded document, add condition for counter using `:if`
|
81
|
+
|
82
|
+
````rb
|
83
|
+
class Comment
|
84
|
+
include Mongoid::Document
|
85
|
+
include Mongoid::MagicCounterCache
|
86
|
+
|
87
|
+
belongs_to :post
|
88
|
+
|
89
|
+
field :remark
|
90
|
+
field :is_published, type: Boolean, default: false
|
91
|
+
|
92
|
+
counter_cache :post, :if => Proc.new { |act| (act.is_published) }
|
93
|
+
end
|
94
|
+
````
|
95
|
+
|
96
|
+
comment_count will get incremented / decremented only when `:if` condition returns `true`
|
97
|
+
|
98
|
+
### Conditional Counter After Update
|
99
|
+
|
100
|
+
In conjunction with the conditional counter, if you want to maintain counter after an update to an object, then you can specify it using `:if_update`
|
101
|
+
|
102
|
+
Using same example as above, in the referrenced/Embedded document, add an additional condition for counter using `:if_update`
|
103
|
+
|
104
|
+
````rb
|
105
|
+
class Comment
|
106
|
+
include Mongoid::Document
|
107
|
+
include Mongoid::MagicCounterCache
|
108
|
+
|
109
|
+
belongs_to :post
|
110
|
+
|
111
|
+
field :remark
|
112
|
+
field :is_published, type: Boolean, default: false
|
113
|
+
|
114
|
+
counter_cache :post, :if => Proc.new { |act| (act.is_published) }, :if_update => Proc.new { |act| act.changes['is_published'] }
|
115
|
+
end
|
116
|
+
````
|
117
|
+
|
118
|
+
When a comment is saved, comment_count will get incremented / decremented if the is_published field is dirty.
|
68
119
|
|
69
120
|
|
70
121
|
|
71
122
|
## CONTRIBUTE
|
72
123
|
|
73
|
-
If you'd like to contribute, feel free to fork and merge until your heart is content
|
124
|
+
If you'd like to contribute, feel free to fork and merge until your heart is content
|
@@ -69,10 +69,9 @@ module Mongoid #:nodoc:
|
|
69
69
|
name = options[:class] || args.first.to_s
|
70
70
|
counter_name = get_counter_name(options)
|
71
71
|
condition = options[:if]
|
72
|
+
update_condition = options[:if_update]
|
72
73
|
|
73
|
-
|
74
|
-
result = condition_result(condition, doc)
|
75
|
-
return unless result
|
74
|
+
increment_proc = ->(doc, inc) do
|
76
75
|
if doc.embedded?
|
77
76
|
parent = doc._parent
|
78
77
|
if parent.respond_to?(counter_name)
|
@@ -86,8 +85,22 @@ module Mongoid #:nodoc:
|
|
86
85
|
end
|
87
86
|
end
|
88
87
|
|
88
|
+
callback_proc = ->(doc, inc) do
|
89
|
+
result = condition_result(condition, doc)
|
90
|
+
return unless result
|
91
|
+
increment_proc.call(doc, inc)
|
92
|
+
end
|
93
|
+
|
94
|
+
update_callback_proc = ->(doc) do
|
95
|
+
return if condition.nil? || update_condition.nil? # Don't execute if there is no update condition.
|
96
|
+
return unless update_condition.call(doc) # Determine whether to execute update increment/decrements.
|
97
|
+
inc = condition.call(doc) ? 1 : -1
|
98
|
+
increment_proc.call(doc, inc)
|
99
|
+
end
|
100
|
+
|
89
101
|
after_create( ->(doc) { callback_proc.call(doc, 1) })
|
90
102
|
after_destroy(->(doc) { callback_proc.call(doc, -1) })
|
103
|
+
after_update( ->(doc) { update_callback_proc.call(doc) })
|
91
104
|
|
92
105
|
end
|
93
106
|
|
data/spec/models/article.rb
CHANGED
data/spec/models/post.rb
CHANGED
@@ -0,0 +1,11 @@
|
|
1
|
+
class UpdateComment
|
2
|
+
include Mongoid::Document
|
3
|
+
include Mongoid::MagicCounterCache
|
4
|
+
|
5
|
+
belongs_to :post
|
6
|
+
|
7
|
+
field :remark
|
8
|
+
field :is_published, type: Boolean, default: false
|
9
|
+
|
10
|
+
counter_cache :post, :if => Proc.new { |act| (act.is_published) }, :if_update => Proc.new { |act| act.changes['is_published'] }
|
11
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class UpdateReview
|
2
|
+
include Mongoid::Document
|
3
|
+
include Mongoid::MagicCounterCache
|
4
|
+
|
5
|
+
embedded_in :article
|
6
|
+
counter_cache :article, :if => Proc.new { |act| (act.is_published) }, :if_update => Proc.new { |act| act.changes['is_published'] }
|
7
|
+
|
8
|
+
field :comment
|
9
|
+
field :is_published, type: Boolean, default: false
|
10
|
+
end
|
@@ -6,7 +6,7 @@ module Mongoid
|
|
6
6
|
|
7
7
|
describe ".counter_cache" do
|
8
8
|
|
9
|
-
context "when the document is
|
9
|
+
context "when the document is associated without condition" do
|
10
10
|
|
11
11
|
before do
|
12
12
|
Library.delete_all
|
@@ -279,6 +279,44 @@ module Mongoid
|
|
279
279
|
Comment.where(:remark == "2nd comment").first.destroy
|
280
280
|
post.comment_count.should == 2
|
281
281
|
end
|
282
|
+
|
283
|
+
context "if update condition" do
|
284
|
+
it "should not increase counter when old unpublished comment is published" do
|
285
|
+
new_comment = Comment.new
|
286
|
+
post.comments << new_comment
|
287
|
+
post.comments.size.should == post.comment_count + 1
|
288
|
+
|
289
|
+
new_comment.is_published.should == false
|
290
|
+
new_comment.is_published = true
|
291
|
+
new_comment.save!
|
292
|
+
|
293
|
+
post.comments.size.should == post.comment_count + 1
|
294
|
+
end
|
295
|
+
|
296
|
+
it "should not decrease counter when old published comment is unpublished" do
|
297
|
+
new_comment = Comment.new(:is_published => true)
|
298
|
+
post.comments << new_comment
|
299
|
+
post.comments.size.should == post.comment_count
|
300
|
+
|
301
|
+
new_comment.is_published.should == true
|
302
|
+
new_comment.is_published = false
|
303
|
+
new_comment.save!
|
304
|
+
|
305
|
+
post.comments.size.should == post.comment_count
|
306
|
+
end
|
307
|
+
|
308
|
+
it "should not modify counter when publish field is not dirty" do
|
309
|
+
new_comment = Comment.new
|
310
|
+
post.comments << new_comment
|
311
|
+
post.comments.size.should == post.comment_count + 1
|
312
|
+
|
313
|
+
new_comment.is_published.should == false
|
314
|
+
new_comment.remark = 'New Remark'
|
315
|
+
new_comment.save!
|
316
|
+
|
317
|
+
post.comments.size.should == post.comment_count + 1
|
318
|
+
end
|
319
|
+
end
|
282
320
|
end
|
283
321
|
|
284
322
|
context "when the document is embedded and has condition for counter" do
|
@@ -335,6 +373,264 @@ module Mongoid
|
|
335
373
|
article.reviews.length.should == 6
|
336
374
|
article.review_count.should == 1
|
337
375
|
end
|
376
|
+
|
377
|
+
context "if update condition" do
|
378
|
+
it "should not increase counter when old unpublished review is published" do
|
379
|
+
new_review = Review.new
|
380
|
+
article.reviews << new_review
|
381
|
+
article.reviews.size.should == article.review_count + 1
|
382
|
+
|
383
|
+
new_review.is_published.should == false
|
384
|
+
new_review.is_published = true
|
385
|
+
new_review.save!
|
386
|
+
|
387
|
+
article.reviews.size.should == article.review_count + 1
|
388
|
+
end
|
389
|
+
|
390
|
+
it "should not decrease counter when old published review is unpublished" do
|
391
|
+
new_review = Review.new(:is_published => true)
|
392
|
+
article.reviews << new_review
|
393
|
+
article.reviews.size.should == article.review_count
|
394
|
+
|
395
|
+
new_review.is_published.should == true
|
396
|
+
new_review.is_published = false
|
397
|
+
new_review.save!
|
398
|
+
|
399
|
+
article.reviews.size.should == article.review_count
|
400
|
+
end
|
401
|
+
|
402
|
+
it "should not modify counter when published field is not dirty" do
|
403
|
+
new_review = Review.new
|
404
|
+
article.reviews << new_review
|
405
|
+
article.reviews.size.should == article.review_count + 1
|
406
|
+
|
407
|
+
new_review.is_published.should == false
|
408
|
+
new_review.comment = 'New Comment'
|
409
|
+
new_review.save!
|
410
|
+
|
411
|
+
article.reviews.size.should == article.review_count + 1
|
412
|
+
end
|
413
|
+
end
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
describe ".counter_cache with if_update" do
|
418
|
+
|
419
|
+
context "when the document is associated with condition" do
|
420
|
+
|
421
|
+
before do
|
422
|
+
Post.delete_all
|
423
|
+
end
|
424
|
+
|
425
|
+
let(:post) do
|
426
|
+
Post.new
|
427
|
+
end
|
428
|
+
|
429
|
+
let(:comment) do
|
430
|
+
UpdateComment.new(:is_published => true)
|
431
|
+
end
|
432
|
+
|
433
|
+
before do
|
434
|
+
post.save
|
435
|
+
post.update_comments.create(:remark => "I agree with you", :is_published => true)
|
436
|
+
end
|
437
|
+
|
438
|
+
it "sets the target of the relation" do
|
439
|
+
post.update_comments.first.remark.should == "I agree with you"
|
440
|
+
end
|
441
|
+
|
442
|
+
it "should have 1 comment for post" do
|
443
|
+
post.update_comments.size.should == 1
|
444
|
+
end
|
445
|
+
|
446
|
+
it "should have 1 in comment counter" do
|
447
|
+
post.update_comment_count.should == 1
|
448
|
+
end
|
449
|
+
|
450
|
+
it "sets the counter cache equal to the relation count on addition" do
|
451
|
+
5.times do |n|
|
452
|
+
post.update_comments << UpdateComment.new(:is_published => true)
|
453
|
+
post.update_comment_count.should == post.update_comments.size
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
it "should increase counter when new books are added" do
|
458
|
+
post.update_comments.push( comment )
|
459
|
+
post.update_comments.size.should == 2
|
460
|
+
end
|
461
|
+
|
462
|
+
it "should increase counter when new books are added" do
|
463
|
+
post.update_comments.push( comment )
|
464
|
+
post.update_comments.size.should == post.update_comment_count
|
465
|
+
end
|
466
|
+
|
467
|
+
it "should decrease counter when published comment is deleted" do
|
468
|
+
post.update_comments.push( comment )
|
469
|
+
comment.destroy
|
470
|
+
post.update_comments.size.should == 1
|
471
|
+
end
|
472
|
+
|
473
|
+
it "should increase counter when new books are added" do
|
474
|
+
post.update_comments.push( comment )
|
475
|
+
comment.destroy
|
476
|
+
post.update_comments.size.should == post.update_comment_count
|
477
|
+
end
|
478
|
+
|
479
|
+
it "shouldnot increase counter when unpublished comment is added" do
|
480
|
+
post.update_comments << UpdateComment.new
|
481
|
+
post.update_comments.size.should == post.update_comment_count + 1
|
482
|
+
end
|
483
|
+
|
484
|
+
it "shouldnot decrease counter when unpublished comment is deleted" do
|
485
|
+
post.update_comments << UpdateComment.new(:remark => "2nd comment")
|
486
|
+
post.update_comments << UpdateComment.new(:remark => "3rd comment", :is_published => true)
|
487
|
+
UpdateComment.where(:remark == "2nd comment").first.destroy
|
488
|
+
post.update_comment_count.should == 2
|
489
|
+
end
|
490
|
+
|
491
|
+
context "if update condition" do
|
492
|
+
it "should increase counter when old unpublished comment is published" do
|
493
|
+
new_comment = UpdateComment.new
|
494
|
+
post.update_comments << new_comment
|
495
|
+
post.update_comments.size.should == post.update_comment_count + 1
|
496
|
+
|
497
|
+
new_comment.is_published.should == false
|
498
|
+
new_comment.is_published = true
|
499
|
+
new_comment.save!
|
500
|
+
|
501
|
+
post.update_comments.size.should == post.update_comment_count
|
502
|
+
|
503
|
+
new_comment.save! # Should not increment since is_published is not dirty.
|
504
|
+
post.update_comments.size.should == post.update_comment_count
|
505
|
+
end
|
506
|
+
|
507
|
+
it "should decrease counter when old published comment is unpublished" do
|
508
|
+
new_comment = UpdateComment.new(:is_published => true)
|
509
|
+
post.update_comments << new_comment
|
510
|
+
post.update_comments.size.should == post.update_comment_count
|
511
|
+
|
512
|
+
new_comment.is_published.should == true
|
513
|
+
new_comment.is_published = false
|
514
|
+
new_comment.save!
|
515
|
+
|
516
|
+
post.update_comments.size.should == post.update_comment_count + 1
|
517
|
+
|
518
|
+
new_comment.save! # Should not increment since is_published is not dirty.
|
519
|
+
post.update_comments.size.should == post.update_comment_count + 1
|
520
|
+
end
|
521
|
+
|
522
|
+
it "should not modify counter when publish field is not dirty" do
|
523
|
+
new_comment = UpdateComment.new
|
524
|
+
post.update_comments << new_comment
|
525
|
+
post.update_comments.size.should == post.update_comment_count + 1
|
526
|
+
|
527
|
+
new_comment.is_published.should == false
|
528
|
+
new_comment.remark = 'New Remark'
|
529
|
+
new_comment.save!
|
530
|
+
|
531
|
+
post.update_comments.size.should == post.update_comment_count + 1
|
532
|
+
end
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
536
|
+
context "when the document is embedded and has condition for counter" do
|
537
|
+
|
538
|
+
before do
|
539
|
+
Article.delete_all
|
540
|
+
end
|
541
|
+
|
542
|
+
let(:article) do
|
543
|
+
Article.new
|
544
|
+
end
|
545
|
+
|
546
|
+
let(:review) do
|
547
|
+
UpdateReview.new(:comment => "This is nice article")
|
548
|
+
end
|
549
|
+
|
550
|
+
before do
|
551
|
+
article.save
|
552
|
+
article.update_reviews.create(:comment => "This is very good article", :is_published => true)
|
553
|
+
end
|
554
|
+
|
555
|
+
it "should have 1 review in reviews" do
|
556
|
+
article.update_reviews.length.should == 1
|
557
|
+
end
|
558
|
+
|
559
|
+
it "should have correct comment" do
|
560
|
+
article.update_reviews.first.comment.should == "This is very good article"
|
561
|
+
end
|
562
|
+
|
563
|
+
it "should have 1 review in counter" do
|
564
|
+
article.update_review_count.should == 1
|
565
|
+
end
|
566
|
+
|
567
|
+
it "sets the counter cache equal to the relation count" do
|
568
|
+
article.update_reviews.length.should == article.update_review_count
|
569
|
+
end
|
570
|
+
|
571
|
+
it "sets the counter cache equal to the relation count on addition" do
|
572
|
+
5.times do |n|
|
573
|
+
article.update_reviews << UpdateReview.new(:is_published => true)
|
574
|
+
article.update_reviews.length.should == article.update_review_count
|
575
|
+
end
|
576
|
+
end
|
577
|
+
|
578
|
+
it "decreases the counter cache when records are deleted" do
|
579
|
+
article.update_reviews.all.destroy
|
580
|
+
article.update_reviews.length.should == article.update_review_count
|
581
|
+
end
|
582
|
+
|
583
|
+
it "counter should not get incremented if condition is not meet" do
|
584
|
+
5.times do |n|
|
585
|
+
article.update_reviews << UpdateReview.new
|
586
|
+
end
|
587
|
+
article.update_reviews.length.should == 6
|
588
|
+
article.update_review_count.should == 1
|
589
|
+
end
|
590
|
+
|
591
|
+
context "if update condition" do
|
592
|
+
it "should increase counter when old unpublished review is published" do
|
593
|
+
new_review = UpdateReview.new
|
594
|
+
article.update_reviews << new_review
|
595
|
+
article.update_reviews.size.should == article.update_review_count + 1
|
596
|
+
|
597
|
+
new_review.is_published.should == false
|
598
|
+
new_review.is_published = true
|
599
|
+
new_review.save!
|
600
|
+
|
601
|
+
article.update_reviews.size.should == article.update_review_count
|
602
|
+
|
603
|
+
new_review.save! # Should not increment since is_published is not dirty.
|
604
|
+
article.update_reviews.size.should == article.update_review_count
|
605
|
+
end
|
606
|
+
|
607
|
+
it "should decrease counter when old published review is unpublished" do
|
608
|
+
new_review = UpdateReview.new(:is_published => true)
|
609
|
+
article.update_reviews << new_review
|
610
|
+
article.update_reviews.size.should == article.update_review_count
|
611
|
+
|
612
|
+
new_review.is_published.should == true
|
613
|
+
new_review.is_published = false
|
614
|
+
new_review.save!
|
615
|
+
|
616
|
+
article.update_reviews.size.should == article.update_review_count + 1
|
617
|
+
|
618
|
+
new_review.save! # Should not decrement since is_published is not dirty.
|
619
|
+
article.update_reviews.size.should == article.update_review_count + 1
|
620
|
+
end
|
621
|
+
|
622
|
+
it "should not modify counter when published field is not dirty" do
|
623
|
+
new_review = UpdateReview.new
|
624
|
+
article.update_reviews << new_review
|
625
|
+
article.update_reviews.size.should == article.update_review_count + 1
|
626
|
+
|
627
|
+
new_review.is_published.should == false
|
628
|
+
new_review.comment = 'New Comment'
|
629
|
+
new_review.save!
|
630
|
+
|
631
|
+
article.update_reviews.size.should == article.update_review_count + 1
|
632
|
+
end
|
633
|
+
end
|
338
634
|
end
|
339
635
|
end
|
340
636
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid_magic_counter_cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Herrick
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-03-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mongoid
|
@@ -85,6 +85,8 @@ files:
|
|
85
85
|
- spec/models/post.rb
|
86
86
|
- spec/models/review.rb
|
87
87
|
- spec/models/song.rb
|
88
|
+
- spec/models/update_comment.rb
|
89
|
+
- spec/models/update_review.rb
|
88
90
|
- spec/mongoid/magic_counter_cache_spec.rb
|
89
91
|
- spec/spec_helper.rb
|
90
92
|
homepage: https://github.com/jah2488/mongoid-magic-counter-cache
|
@@ -107,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
107
109
|
version: '0'
|
108
110
|
requirements: []
|
109
111
|
rubyforge_project: mongoid_magic_counter_cache
|
110
|
-
rubygems_version: 2.
|
112
|
+
rubygems_version: 2.4.5
|
111
113
|
signing_key:
|
112
114
|
specification_version: 4
|
113
115
|
summary: Setup Counter Caches in Mongoid Documents
|
@@ -124,5 +126,7 @@ test_files:
|
|
124
126
|
- spec/models/post.rb
|
125
127
|
- spec/models/review.rb
|
126
128
|
- spec/models/song.rb
|
129
|
+
- spec/models/update_comment.rb
|
130
|
+
- spec/models/update_review.rb
|
127
131
|
- spec/mongoid/magic_counter_cache_spec.rb
|
128
132
|
- spec/spec_helper.rb
|