Skip to content

Commit

Permalink
Merge pull request jah2488#15 from joe1chen/add_if_update_option
Browse files Browse the repository at this point in the history
Add if_update option for conditionally updating counter in after_update hook.
  • Loading branch information
jah2488 committed Mar 16, 2014
2 parents d3ca1df + 16d0953 commit b93b7d7
Show file tree
Hide file tree
Showing 10 changed files with 372 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## v1.1.1

* 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.

## v1.0.0

* Remove version dependency to work with rails 4. Breaks compatibility with ruby 1.9.2 and older
Expand Down
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,28 @@ end

comment_count will get incremented / decremented only when `:if` condition returns `true`

### Conditional Counter After Update

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`

Using same example as above, in the referrenced/Embedded document, add an additional condition for counter using `:if_update`

````rb
class Comment
include Mongoid::Document
include Mongoid::MagicCounterCache

belongs_to :post

field :remark
field :is_published, type: Boolean, default: false

counter_cache :post, :if => Proc.new { |act| (act.is_published) }, :if_update => Proc.new { |act| act.changes['is_published'] }
end
````

When a comment is saved, comment_count will get incremented / decremented if the is_published field is dirty.

## TODO

1. Add additional options parameters
Expand Down
2 changes: 1 addition & 1 deletion lib/mongoid/magic-counter-cache/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Mongoid
module MagicCounterCache
VERSION = "1.1.0"
VERSION = "1.1.1"
end
end
22 changes: 22 additions & 0 deletions lib/mongoid/magic_counter_cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ def counter_cache(*args, &block)
name = options[:class] || args.first.to_s
counter_name = get_counter_name(options)
condition = options[:if]
update_condition = options[:if_update]

callback_proc = ->(doc, inc) do
result = condition_result(condition, doc)
Expand All @@ -86,8 +87,29 @@ def counter_cache(*args, &block)
end
end

update_callback_proc = ->(doc) do
return if condition.nil?
return if update_condition.nil? # Don't execute if there is no update condition.
return unless update_condition.call(doc) # Determine whether to execute update increment/decrements.

inc = condition.call(doc) ? 1 : -1

if doc.embedded?
parent = doc._parent
if parent.respond_to?(counter_name)
increment_association(parent, counter_name.to_sym, inc)
end
else
relation = doc.send(name)
if relation && relation.class.fields.keys.include?(counter_name)
increment_association(relation, counter_name.to_sym, inc)
end
end
end

after_create( ->(doc) { callback_proc.call(doc, 1) })
after_destroy(->(doc) { callback_proc.call(doc, -1) })
after_update( ->(doc) { update_callback_proc.call(doc) })

end

Expand Down
2 changes: 1 addition & 1 deletion lib/mongoid_magic_counter_cache/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module MongoidMagicCounterCache
VERSION = "1.1.0"
VERSION = "1.1.1"
end
2 changes: 2 additions & 0 deletions spec/models/article.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ class Article
include Mongoid::Document

embeds_many :reviews
embeds_many :update_reviews

field :title
field :review_count, type: Integer, default: 0
field :update_review_count, type: Integer, default: 0

end
2 changes: 2 additions & 0 deletions spec/models/post.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ class Post

has_many :comments

field :update_comment_count, :type => Integer, :default => 0
has_many :update_comments
end
11 changes: 11 additions & 0 deletions spec/models/update_comment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class UpdateComment
include Mongoid::Document
include Mongoid::MagicCounterCache

belongs_to :post

field :remark
field :is_published, type: Boolean, default: false

counter_cache :post, :if => Proc.new { |act| (act.is_published) }, :if_update => Proc.new { |act| act.changes['is_published'] }
end
10 changes: 10 additions & 0 deletions spec/models/update_review.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class UpdateReview
include Mongoid::Document
include Mongoid::MagicCounterCache

embedded_in :article
counter_cache :article, :if => Proc.new { |act| (act.is_published) }, :if_update => Proc.new { |act| act.changes['is_published'] }

field :comment
field :is_published, type: Boolean, default: false
end
Loading

0 comments on commit b93b7d7

Please sign in to comment.