我如何"验证"铁轨上的销毁

时间:2020-03-06 14:37:12  来源:igfitidea点击:

关于销毁宁静的资源,我想保证一些事情之后我才能继续销毁操作?基本上,我希望能够停止销毁操作,如果我注意到这样做会导致数据库处于无效状态?销毁操作上没有验证回调,那么如何"验证"是否应接受销毁操作?

解决方案

我们可以引发一个异常,然后捕获该异常。 Rails将删除操作包装在事务中,这很重要。

例如:

class Booking < ActiveRecord::Base
  has_many   :booking_payments
  ....
  def destroy
    raise "Cannot delete booking with payments" unless booking_payments.count == 0
    # ... ok, go ahead and destroy
    super
  end
end

另外,我们可以使用before_destroy回调。此回调通常用于销毁相关记录,但是我们可以引发异常或者添加错误。

def before_destroy
  return true if booking_payments.count == 0
  errors.add :base, "Cannot delete booking with payments"
  # or errors.add_to_base in Rails 2
  false
  # Rails 5
  throw(:abort)
end

现在," myBooking.destroy"将返回false,并且将在返回时填充" myBooking.errors"。

我们还可以使用before_destroy回调引发异常。

ActiveRecord关联has_many和has_one允许使用一个相关选项,以确保在删除时删除相关的表行,但这通常是为了保持数据库干净而不是防止其无效。

我们可以将destroy操作包装在控制器的" if"语句中:

def destroy # in controller context
  if (model.valid_destroy?)
    model.destroy # if in model context, use `super`
  end
end

哪里有效?是模型类上的方法,如果满足销毁记录的条件,则该方法返回true。

拥有这样的方法还可以防止向用户显示删除选项,这将改善用户体验,因为用户将无法执行非法操作。