是否要破坏`before_validation`回调错误代码中的持久记录?

问题描述 投票:1回答:1

我想防止报告distributed && checked均为零||的报告创建后为零。

我还希望用户能够通过以下方式删除现有报告:将表单中的这些值设置为nil或零(创建报告并进行批量编辑,UX倾向于将值设置为0或从表单中删除值而不是“删除”按钮)。

作为一个业余爱好者,这有点不好意思:

class Report < ApplicationRecord
  ...
  before_validation :prevent_meaningless_reports, if: (distributed.nil? || distributed.zero?) && (checked.nil? || checked.zero?)
  ...

  ...

  private

  def prevent_meaningless_reports
    if new_record?
      throw :abort
    else #persisted?
      self.destroy
    end
  end
end

before_*回调期间销毁一条记录感到很遗憾。

我冒着问一个潜在的基于意见的问题的风险,因为似乎我可能违反了一些告诉我为什么这是个坏主意的软件原理。

如果这是可以接受的行为,那么最好分两个块来执行,一个用于before_create(对于新记录),另一个用于before_update(对于持久记录)?

ruby-on-rails callback
1个回答
1
投票

您将要遇到的问题是,当您尝试更新一个已经不存在的有意义的报告以对其执行进一步的操作时。

例如:


meaningless_report.update(attribute: some_value)

meaningless_report.some_other_value #meaningless_report is already removed from the db and frozen

如果再次尝试更新Meaningless_report对象,则会遇到RuntimeError。因此,这绝对不是一个好主意

一个更好的选择是使用ActiveRecord验证,这样即使在创建报告之前,我们也对它们进行验证以确保它们没有意义,并确保记录在更新期间不会变得毫无意义。>>

例如:

class Report < ApplicationRecord

  validate :validate_meaningful_reports

  def not_meaningful_report?
    (distributed.nil? || distributed.zero?) && (checked.nil? || checked.zero?)
  end

  private

  def validate_meaningful_reports
   if not_meaningful_report?
     errors.add(:base, "Report violates validations")
   end
  end


end

因此,我们确保不会创建无意义的报告。为了处理无意义的旧报告,我们可以为此使用脚本或rake任务。脚本/任务如下所示:

 meaningless_reports = Report.unscoped.find_each { |r| r.destroy if r.not_meaningful_report?}

这要安全得多

© www.soinside.com 2019 - 2024. All rights reserved.