Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails:如何防止删除记录?_Ruby On Rails_Ruby On Rails 4 - Fatal编程技术网

Ruby on rails Rails:如何防止删除记录?

Ruby on rails Rails:如何防止删除记录?,ruby-on-rails,ruby-on-rails-4,Ruby On Rails,Ruby On Rails 4,我有一个模范国家,因此有一个表国家。countries表作为iso国家和货币代码的集合,不应该减少这些内容(在我用种子数据填充之后)。因为Country是ActiveRecord::Base的一个子类,所以它继承了诸如destroy、delete_all等类方法来删除记录。我正在寻找一种解决方案,以防止在模型级别删除记录 Ofc。我知道我可以使用面向对象的方法来解决这个问题,方法是重写这些方法(例如,当它们调用时会引发错误),但这假设我必须知道基类的所有继承方法。如果有人能提供一个更优雅的解决方

我有一个模范国家,因此有一个表国家。countries表作为iso国家和货币代码的集合,不应该减少这些内容(在我用种子数据填充之后)。因为Country是ActiveRecord::Base的一个子类,所以它继承了诸如destroy、delete_all等类方法来删除记录。我正在寻找一种解决方案,以防止在模型级别删除记录


Ofc。我知道我可以使用面向对象的方法来解决这个问题,方法是重写这些方法(例如,当它们调用时会引发错误),但这假设我必须知道基类的所有继承方法。如果有人能提供一个更优雅的解决方案,我会很高兴

有一个销毁前回调,也许你可以利用它

before_destroy :stop_destroy

def stop_destroy
  self.errors[:base] << "Countries cannot be deleted"
  return false
end
销毁前:停止销毁
def stop_销毁

self.errors[:base]在Rails 6中,这就是防止记录被删除的方法。 引发的异常将回滚ActiveRecord正在使用的事务,从而防止删除该记录

    class MenuItem < ApplicationRecord

      after_destroy :ensure_home_page_remains

      class Error < StandardError
      end


      protected #or private whatever you need

      #Raise an error that you trap in your controller to prevent your record being deleted.
        def ensure_home_page_remains
          if menu_text == "Home"
          raise Error.new "Can't delete home page"
        end
    end

从Mark Swardstrom answer中汲取灵感,我提出了以下在Rails>5.0上也适用的建议:

在您的模型中:

before_destroy :stop_destroy

def stop_destroy
  errors.add(:base, :undestroyable)
  throw :abort
end
以下操作将对
model.destroy
return
false
进行所有调用,您的模型将不会被删除

您可以争辩说,调用
model.delete
会起作用,并删除您的记录,但由于这些都是较低级别的调用,这对我来说非常有意义

如果需要,您也可以直接从数据库中删除记录,但是上面的解决方案阻止从应用程序级别删除记录,而应用程序级别正是检查这一点的正确位置

Rubocop检查您的删除或全部删除调用并发出警告,因此您可以100%确定,如果您调用
model.delete
是因为您确实需要它


我的解决方案适用于最新的Rails版本,您需要抛出:abort,而不是返回false。

使用“delete”时不会触发该选项。只有在销毁时。同意这根本不是一个完整的答案。在销毁之前尝试:停止销毁,准备:真的这确实是一个很好的答案。我将给出一个新的、更新的答案,并提供更多细节。这篇文章讨论了如何做到这一点:你正在使用哪个数据库?也许你应该在数据库上解决这个问题:
before_destroy :stop_destroy

def stop_destroy
  errors.add(:base, :undestroyable)
  throw :abort
end