rails-实现一个简单的锁,以防止用户同时编辑相同的数据 [英] rails - implementing a simple lock to prevent user's from editing the same data concurrently

查看:104
本文介绍了rails-实现一个简单的锁,以防止用户同时编辑相同的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,在该应用程序中,我需要防止用户在其他用户正在编辑数据时对其进行编辑.我正在尝试最好的方法,并希望提出想法.到目前为止,我已经创建了一个设置模型,该模型以键/值对的形式在db上存储应用程序范围的配置.因此,对于锁,我有一个名为LOCKED_TABLE_UID的设置实例,它存储了编辑表的用户的user_id;如果表是空闲的,则存储为null(零).

I have an app where I need to prevent users from editing data while it is being edited by a different user. I'm trying to think of the best way to do it and wanted to ask for ideas. So far, I've created a settings model that stores application wide configuration on the db in key/value pairs. So, for the lock, I have a settings instance that's called LOCKED_TABLE_UID, and it stored the user_id of the user editing the table or null (nil) if the table is free.

>> lock = Setting.find_by_key('LOCKED_TABLE_UID')

然后,我在应用程序控制器中实现了两种方法来获取和释放锁:

Then, I implemented 2 methods in my application controller to acquire and release the lock:

# current_user returns the user currently logged in
def acquire_lock
  lock = Setting.find_by_key("LOCKED_TABLE_UID")
  if lock.value
    # if lock taken, see if it's the current_user or someone else
    if lock.value.to_i == current_user.id.to_i
      return true
    else
      return false
    end
  else
    # lock is free, assign it to this user
    lock.value = current_user.id
    return true if lock.save
  end
end

def release_lock
  lock = Setting.find_by_key("LOCKED_TABLE_UID")
  if lock.value
    # the lock belongs to current_user, so he can release it
    if lock.value.to_i == current_user.id.to_i
      lock.value = nil
      return true if lock.save
    else
      # not your lock, go away
      return false
    end
  else
    # lock is free, quit bugging
    return true
  end
end

我想要的是创建一种包含锁定机制的块代码,如下所示:

What I want is to create some kind of block code that contains the locking mechanism, something like this:

def some_crud_action
  requires_locking do |lock|
    if lock
      # do some CRUD stuff here
    else
      # decline CRUD and give some error
    end
  end
end

我很乐意为此提供帮助-但我也乐于接受其他建议,以了解如何完成所有这些工作或某些我可能忽略的事情.这个锁不必一定是原子的,而是相当基本的,也是最重要的-它起作用了:) 谢谢.

I'd appreciate help on this - but I'm also open to other suggestions on how to accomplish all that, or some things I may have overlooked. This lock doesn't have to be atomic, but fairly basic and most important - that it works :) thanks.

推荐答案

您快到了.创建您的require_locking?您认为合适的动作.然后使用before_filter处理它.

You're almost there. Create your require_locking? action as you see fit. Then process it with a before_filter.

 before_filter :requires_locking?, :only => [:update, :destroy]
 after_filter :release_lock, :only => [:update, :destroy]

 def requires_locking do |lock|
   unless acquire_lock
      lock = Setting.find_by_key("LOCKED_TABLE_UID")
      user_with_lock = User.find(lock.value)
      flash[:message] = "Action denied: Table locked by: #{user_with_lock.name}"
      redirect_to :back
   end
 end

这篇关于rails-实现一个简单的锁,以防止用户同时编辑相同的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆