Rails:如何防止删除记录?

Bob*_*gor 8 ruby-on-rails ruby-on-rails-4

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

办公室。我知道我可以利用面向对象的方法通过重写此方法来解决此问题(例如在调用时引发错误),但这假设我必须知道基类的所有继承方法。如果有人可以提供更优雅的解决方案,我会很高兴。

coo*_*sse 14

受到 Mark Swardstrom 回答的启发,我提出以下建议也适用于 Rails > 5.0:

在您的模型中:

before_destroy :stop_destroy

def stop_destroy
  errors.add(:base, :undestroyable)
  throw :abort
end
Run Code Online (Sandbox Code Playgroud)

以下将使所有调用model.destroy返回false并且您的模型不会被删除。

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

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

Rubocop会检查您对delete或delete_all的调用并发出警告,因此您可以100%确定您调用model.delete是因为您确实想要它。

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


Mar*_*rom 4

有一个 before_destroy 回调,也许你可以利用它。

before_destroy :stop_destroy

def stop_destroy
  self.errors[:base] << "Countries cannot be deleted"
  return false
end
Run Code Online (Sandbox Code Playgroud)

  • 使用“删除”时不会触发该操作。仅当破坏时。 (2认同)