Skip to content
This repository

Ruby on Rails plugin that implements optimistic locking across HTTP requests. It provides simple methods for avoiding race conditions that could result in database inconsistencies.

branch: master

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 doc
Octocat-spinner-32 generators
Octocat-spinner-32 lib
Octocat-spinner-32 tasks
Octocat-spinner-32 test
Octocat-spinner-32 MIT-LICENSE
Octocat-spinner-32 README.rdoc
Octocat-spinner-32 Rakefile
Octocat-spinner-32 init.rb
Octocat-spinner-32 install.rb
Octocat-spinner-32 uninstall.rb
README.rdoc

Conflict_Warnings

conflict_warnings is an ActionController extension that provides methods of preventing data inconsistencies that could arise from multiple users interacting with the same resource at roughly the same time. Essentially providing Optimistic Locking persisting across requests. Named after the HTTP 409 Conflict status, conflict_warnings determines if a database conflict is likely and intercepts potentailly dangerous requests.

Installation

From the root of your rails project run the following command:

./script/plugin install git://github.com/EmFi/conflict_warnings.git

Usage

filters

Add either filter_conflicts, filter_stale_optimistic_locks or filter_resource_conflicts to your controllers as if they were a before filter.

class ExamplesController < ApplicationController
  filter_conflicts
end

or

class LockExampleController < ApplicationController
  filter_stale_optimistic_locks
end

class ExamplesController < ApplicationController
  filter_resources_conflicts :only => :update
end

Controller Instance Methods

The underlying methods are also provided for use in your own filters, as catch_conflict, catch_stale_optimistic_locks and catch_resource_conflict.

class LockingResourcesController < ApplicationController
  before_filter :login_required, :acquire_lock

  protected
  def acquire_lock
      catch_resources_unavailable current_user, :accessor => :acquire_lock_for_user
    end
  end
end

The ConflictWarnings methods will use the options supplied and the params to select a model in the database and apply an accessor to identify problem requests.

By default the model associated with the controller handling the request is used, will be used to find the instance with an id of params[:id].

filter_conflicts and catch_conflicts compare a timestamp passed in the link against the updated_at column of the instance. Helpers are provided for creating links with this timestamp. If the model was modified after the timestamp, the request interrupted.

filter_stale_optimistic_locks and catch_stale_optimistic_locks compare a lock version passed in the link against the lock_version fo the the selected instance.

filter_resources_unavialable and catch_conflicts will check for an instance method that ends with available. If this method returns 0 or a false value, the request is interrupted.

Without any options interrupted requests redirect to the referring request, essentially reloading the page and any changes.

Helpers

conflict_warnings provides view helpers that add parameters catch_conflicts require to links:

<%= link_to_remote_with_timestamp("Confirm", confirm_event_url(@event) %>

And forms:

<%= f.timestamp %>

or

<%= timestamp_tag %>

Javascript

conflict_warnings provides a javascript function for use in your RJS templates to update timestamps in regions of a page that are not updated as by an interrupted AJAX request.

page.call('replaceTimeStamps', params[:page_rendered_at], Time.now.to_i)

Documenation

This plugin comes with generated documentation for its provided methods and classes in the doc folder.

In depth documentation of filter_conflicts, filter_stale_optimistic_locks and filter_resources_unavailable can be found in ConflictWarnings::ActionController::ClassMethods#. While documentation of catch_conflicts, catch_stale_optimistic_locks and catch_resources_unavaialble can be found in ConflictWarnigns::ActionController::InstanceMethods#.

conflict_warnings provides view helpers that add parameters catch_conflicts require to links. They can be found in ConflictWarnings::ActionView::Helpers::UrlHelper, ConflictWarnings::ActionView::Helpers::PrototypeHelper, ConflictWarnings::ActionView::Helpers::FormHelper, and ConflictWarnings::ActionView::Helpers::FormTagHelper

Caveats

If catch_conflicts, catch_stale_optimistic_locks, catch_resource_conflict, filter_conflicts, filter_stale_optimistic_locks and filter_resource_conflicts, not receive enough information to reach a decision it will usually assumes the action is harmful. Records that produce a nil value for comparing a time or lock version against a counterpart value(provided in the paremters) will be allowed to complete successfully.

At present forms are not handled well. With the default options, a users' form will be overwritten by the changes to the record that occured between page load and submit. You will have to provide a template to caputre the form from the params hash and figure out a way to display the merged data.

Things To Do:

* Handle additional formats beyond html and js
* Write form builder to allow for automatic side by side comparison of conflicting form data.

Copyright © 2009 Emery Finkelstein, released under the MIT license

Something went wrong with that request. Please try again.