当前位置: 首页 > 知识库问答 >
问题:

Rails:如何防止删除记录?

宋博易
2023-03-14

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

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

共有3个答案

凌清夷
2023-03-14

在Rails 6中,这就是我如何防止记录被删除。引发的异常将回滚ActiveRecords正在使用的事务,从而防止记录被删除

    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

因此,ensure_home_page_remains方法会引发一个MenItem::Error,导致事务回滚,您可以在控制器中捕获该事务,并采取您认为必要的任何适当操作,通常只是在之后向用户显示错误消息重定向到某处。

      # DELETE /menu_items/1
      # DELETE /menu_items/1.json
      def destroy
        @menu_item.destroy
        respond_to do |format|
          format.html { redirect_to admin_menu_items_url, notice: 'Menu item was successfully destroyed.' }
          format.json { head :no_content }
        end
      end

      #Note, the rescue block is outside the destroy method
      rescue_from 'MenuItem::Error' do |exception|
        redirect_to menu_items_url, notice: exception.message
      end
private
#etc...
潘高岑
2023-03-14

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

before_destroy :stop_destroy

def stop_destroy
  self.errors[:base] << "Countries cannot be deleted"
  return false
end
甄坚白
2023-03-14

从Mark Swardstrom的回答中获得灵感,我提出了以下也适用于Rails的建议

在您的模型中:

before_destroy :stop_destroy

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

下面将对模型进行所有调用。销毁returnfalse,您的模型将不会被删除。

您可以争辩说,仍然需要调用模型。删除会起作用,并删除您的记录,但由于这些是较低级别的调用,因此这对我来说非常有意义。

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

Rubocop检查您的呼叫以删除或delete_all并提出警告,所以您可以100%确定如果您调用model.delete是因为您真的想要它。

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

 类似资料:
  • 我正在构建一个基于railsguide的rails应用程序 它在erb中调用的语法是... 控制器定义 与在application.html.erb中使用“application”相关联的错误

  • 我有一个用于用户配置文件图像的模型,当我删除具有默认图像的用户时,默认图像也会被删除。我相信这是必须的,因为我设置了on_delete=models.CASCADE。 我尝试在ImageField中启用_delete=PROTECT,但它无法识别该属性。

  • 问题内容: 如果你这样做 然后,当您看着时,您就会得到。(很公平。) 如果这样做,您会得到。 基本上,我正在寻找一种将其转换为string的方法。 显然,在现实生活中,我无法控制JSON输入,而是从Web服务获取JSON …我想使用浏览器的JSON解析器解析JSON,并能够识别数字值和。 除了手动读取JSON字符串外,还有什么方法可以做到这一点?在这种情况下,这实际上是不可能的,为了提高速度,我需

  • 问题内容: 是否可以防止删除PostgreSQL端表中的第一行? 我有一个类别表,我想防止删除默认类别,因为它可能会破坏应用程序。当然,我可以轻松地在应用程序代码中执行此操作,但是在数据库中执行此操作会更好。 我认为这与delete语句的规则有关,但是我找不到文档中与我的问题遥遥相望的任何东西。 问题答案: 我看到的最好的方法是在此表上创建一个删除触发器。基本上,您必须编写一个存储过程来确保该“默

  • 我想要一个数组列表,并限制元素删除。我该怎么做?

  • 问题内容: 当JDBC River进行轮询时,内务处理将删除记录块。 有人知道解决方案。我想停止删除记录。 有关更多参考: -https //github.com/jprante/elasticsearch-river- jdbc/issues/61 问题答案: 看家的工作是停止,如果版本被禁止在JDBC河参数,这是默认的。 是否在Elasticsearch索引文档中使用版本控制 通过引用:-ht