lib/voteable_mongoid/voteable/voting.rb in voteable_mongoid-0.7.1 vs lib/voteable_mongoid/voteable/voting.rb in voteable_mongoid-0.7.2
- old
+ new
@@ -12,32 +12,47 @@
# - :value: :up or :down
# - :revote: change from vote up to vote down
# - :unvote: unvote the vote value (:up or :down)
def vote(options)
options.symbolize_keys!
+ options[:votee_id] ||= options[:votee].id
options[:votee_id] = BSON::ObjectId(options[:votee_id]) if options[:votee_id].is_a?(String)
options[:voter_id] = BSON::ObjectId(options[:voter_id]) if options[:voter_id].is_a?(String)
options[:value] = options[:value].to_sym
options[:voteable] = VOTEABLE[name][name]
- update_parents = true
+ update_parents = options[:voteable][:update_parents]
if options[:voteable]
- update_result = if options[:revote]
+ query, update = if options[:revote]
revote(options)
elsif options[:unvote]
unvote(options)
else
new_vote(options)
end
- # Only update parent votes if votee is updated successfully
- update_parents = ( update_result['err'] == nil and
- update_result['updatedExisting'] == true and
- update_result['n'] == 1 )
- end
- update_parent_votes(options) if update_parents
+ if options[:votee] || update_parents
+ # If votee exits or need to update parent
+ # use Collection#find_and_modify to retrieve updated votes data and parent_ids
+ begin
+ doc = collection.master.collection.find_and_modify(
+ :query => query,
+ :update => update,
+ :new => true
+ )
+ # Update new votes data
+ options[:votee].write_attribute('votes', doc['votes']) if options[:votee]
+ update_parent_votes(doc, options) if update_parents
+ rescue
+ # Don't update parents if operation fail or no matching object found
+ end
+ else
+ # Just update and don't care the result
+ collection.update(query, update)
+ end
+ end
end
private
def new_vote(options)
@@ -47,11 +62,11 @@
else
positive_voter_ids = 'votes.down'
positive_votes_count = 'votes.down_count'
end
- collection.update({
+ return {
# Validate voter_id did not vote for votee_id yet
:_id => options[:votee_id],
'votes.up' => { '$ne' => options[:voter_id] },
'votes.down' => { '$ne' => options[:voter_id] }
}, {
@@ -59,13 +74,11 @@
'$push' => { positive_voter_ids => options[:voter_id] },
'$inc' => {
'votes.count' => +1,
positive_votes_count => +1,
'votes.point' => options[:voteable][options[:value]] }
- }, {
- :safe => true
- })
+ }
end
def revote(options)
if options[:value] == :up
@@ -80,11 +93,11 @@
positive_votes_count = 'votes.down_count'
negative_votes_count = 'votes.up_count'
point_delta = -options[:voteable][:up] + options[:voteable][:down]
end
- collection.update({
+ return {
# Validate voter_id did a vote with value for votee_id
:_id => options[:votee_id],
positive_voter_ids => { '$ne' => options[:voter_id] },
negative_voter_ids => options[:voter_id]
}, {
@@ -94,13 +107,11 @@
'$inc' => {
positive_votes_count => +1,
negative_votes_count => -1,
'votes.point' => point_delta
}
- }, {
- :safe => true
- })
+ }
end
def unvote(options)
if options[:value] == :up
@@ -111,39 +122,35 @@
positive_voter_ids = 'votes.down'
negative_voter_ids = 'votes.up'
positive_votes_count = 'votes.down_count'
end
- # Check if voter_id did a vote with value for votee_id
- update_result = collection.update({
- # Validate voter_id did a vote with value for votee_id
+ return {
:_id => options[:votee_id],
+ # Validate if voter_id did a vote with value for votee_id
negative_voter_ids => { '$ne' => options[:voter_id] },
positive_voter_ids => options[:voter_id]
}, {
# then update
'$pull' => { positive_voter_ids => options[:voter_id] },
'$inc' => {
positive_votes_count => -1,
'votes.count' => -1,
'votes.point' => -options[:voteable][options[:value]]
}
- }, {
- :safe => true
- })
+ }
end
- def update_parent_votes(options)
+ def update_parent_votes(doc, options)
value = options[:value]
votee ||= options[:votee]
VOTEABLE[name].each do |class_name, voteable|
# For other class in VOTEABLE options, if is parent of current class
next unless relation_metadata = relations[class_name.underscore]
- votee ||= find(options[:votee_id])
# If can find current votee foreign_key value for that class
- next unless foreign_key_value = votee.read_attribute(relation_metadata.foreign_key)
+ next unless foreign_key_value = doc[relation_metadata.foreign_key.to_s]
class_name.constantize.collection.update(
{ '_id' => foreign_key_value },
{ '$inc' => parent_inc_options(value, voteable, options) }
)