开发者

How do I lock records in Rails 3 for a specific amount of time?

开发者 https://www.devze.com 2023-04-13 04:00 出处:网络
What I want to do is basically have a user obtain the lock on a record and have it for a specific amount of time so they can make changes to it, like wikipedia. So lets say a wikipedia article gives t

What I want to do is basically have a user obtain the lock on a record and have it for a specific amount of time so they can make changes to it, like wikipedia. So lets say a wikipedia article gives the user an hour to edit it before other users may edit it.

How coul开发者_JS百科d I achieve that with Rails 3? I have read up and found that pessimistic locking is what I should use for the lock. Given that... What kind of mechanism would I use for releasing the lock say after an hour?

My stack is Rails 3, Heroku, PostgreSQL.

Thanks for any answers and I love to see code if you can that would be so awesome!


Here's an example that creates locks, but doesn't delete them.

I leave that up to you.

The locks do expire after an hour in this example, but to complete the app they should automatically be deleted on a successful update of a post.

working example

or read the

relevant commit


You can do this with acts_as_lockable_by gem.

Imagine you have a patient (ActiveRecord) class that can only be edited by one user and it should be locked to this user till he decides to release it:

class Patient < ApplicationRecord
  acts_as_lockable_by :id, ttl: 30.seconds
end

Then you can do this in your controller:

class PatientsController < ApplicationController
  def edit
    if patient.lock(current_user.id) 
      # It will be locked for 30 seconds for the current user
      # You will need to renew the lock by calling /patients/:id/renew_lock
    else
      # Could not lock the patient record which means it is already locked by another user
    end
  end

  def renew_lock
    if patient.renew_lock(current_user.id)
      # lock renewed return 200
    else
      # could not renew the lock, it might be already released
    end
  end

  private

  def patient
    @patient ||= Patient.find(params[:id])
  end
end


Add a field called "editable_until":datetime and set a specific date (Time.now + 30.min f.e.) when creating your record. And simply query this field to find out if the user has the right to update the record or not.

class Post << AR
  before_validation :set_editable_time

  validate :is_editable

  def editable?
    self.editable_until.nil? || self.editable_until >= Time.now
  end

protected
  def is_editable
    self.errors[:editable_until] << "cannot be edited anymore" unless editable?
  end

  def set_editable_time
    self.editable_until ||= Time.now + 30.min
  end
end

Post.create(:params....)
=> <Post, ID:1, :editable_until => "2011-10-13 15:00:00">

Post.first.editable?
=> true

sleep 1.hour

Post.first.editable?
=> false
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号