This gem helps to abstract the "Update if Current" method which may be used as a replacement for transactions in Mongo.
The gem is an addon over Mongoid ODM and is based on ActiveRecord's Optimistic Locking.
Works with Mongoid 3.
For Mongoid 2 use version 0.0.2
Add the gem to your Gemfile
:
gem 'mongoid_optimistic_locking'
To use it, all you have to do is add include Mongoid::OptimisticLocking
:
class Post
include Mongoid::Document
include Mongoid::OptimisticLocking
field :text
end
This will add a _lock_version
field in the document which will be incremented every time a save is called.
Be sure to rescue Mongoid::Errors::StaleDocument
to handle applicative logic in case the object was changed.
For example:
class PostController < ApplicationController
## Adds an "UPDATE: ...some text..." to an existing document
def add_update
begin
post = Post.find(params[:id])
post.text += "---UPDATE--- " + params[:more_text]
post.save
rescue Mongoid::Errors::StaleDocument
retry
end
end
end
That's it!
While Mongoid::OptimisticLocking
can be used to some degree within embedded documents, there are certain limitations due to Mongoid's document embedding callback structure. Consider the following example:
class Post
include Mongoid::Document
field :text
embeds_many :comments
end
class Comment
include Mongoid::Document
include Mongoid::OptimisticLocking
embedded_in :post
field :text
end
post = Post.new
comment = post.comments.build(:text => 'hello')
comment.save # will use optimistic locking checks
post.save # will not use optimistic locking checks
Mongo Developer FAQ - How do I do transactions/locking?
Mongo Atomic Operations - "Update if Current"
Presentation from "Startup Day" on Mongoid Optimistic Locking