Как мне заблокировать записи в Rails 3 на определенное количество времени? - PullRequest
3 голосов
/ 13 октября 2011

То, что я хочу сделать, - это, по сути, сделать так, чтобы пользователь получил блокировку для записи и имел ее в течение определенного периода времени, чтобы он мог вносить в нее изменения, как в википедии. Допустим, статья в Википедии дает пользователю час на ее редактирование, прежде чем другие пользователи смогут его редактировать.

Как я могу добиться этого с Rails 3? Я прочитал и обнаружил, что пессимистическая блокировка - это то, что я должен использовать для блокировки. Учитывая это ... Какой механизм я бы использовал для снятия блокировки, скажем, через час?

Мой стек - Rails 3, Heroku, PostgreSQL.

Спасибо за любые ответы, и я люблю видеть код, если вы можете, это было бы так здорово!

Ответы [ 3 ]

0 голосов
/ 13 октября 2011

Добавьте поле с именем "editable_until": datetime и установите конкретную дату (Time.now + 30.min f.e.) при создании вашей записи. И просто запросите это поле, чтобы узнать, имеет ли пользователь право обновлять запись или нет.

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 голосов
/ 06 ноября 2018

Вы можете сделать это с acts_as_lockable_by gem.

Представьте, что у вас есть класс пациента (ActiveRecord), который может редактировать только один пользователь, и он должен быть заблокирован для этого пользователя, пока он не решит выпустить его:

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

Тогда вы можете сделать это в вашем контроллере:

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
0 голосов
/ 13 октября 2011

Вот пример, который создает блокировки, но не удаляет их.

Я оставляю это на ваше усмотрение.

Срок действия блокировок истекает через час в этом примере, но для завершения приложения их следует автоматически удалить при успешном обновлении сообщения.

рабочий пример

или прочитайте

соответствующий коммит

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...