1

当无法销毁特定​​模型时,我要做的是返回错误而不是异常。目前,它会引发ActiveRecord::DeleteRestrictionError,但不会返回到 flash 消息,也不会添加到模型的错误集合中。

我所做的是在我足智多谋的控制器中进行设置:

  def destroy
    begin
      resource.destroy
    rescue ActiveRecord::DeleteRestrictionError => e
      resource.errors.add(:base, e)
    end
  end

我宁愿不在每个需要这种特殊行为的控制器中管理它。我该如何抽象它?我看不出覆盖 destroy 方法是个好主意ActiveRecord::Base,但也许不会有任何陷阱?

我正在使用inherited_resources gem,所以也许有办法通过扩展来回答这个问题?

我的另一个想法是扩展ActiveRecord::Base使用ActiveSupport::Concern(从这里:Rails 扩展 ActiveRecord::Base),然后在模型到模型的基础上将销毁方法委托给自定义销毁。想法?

4

2 回答 2

2

首先我要说我同意不覆盖 ActiveRecord::Base 方法如销毁的态度。为了干燥这种行为,你有几个选择,我将列出其中两个:

第一个 - 而不是在特定控制器中编写救援子句,您可以将其嵌入到您的 ApplicationController 中,这样行为将是应用程序范围的:

# ApplicationController.rb

rescue_from ActiveRecord::DeleteRestrictionError do |exception|
  resource.errors.add(:base, exception) if resource
end

另一种选择是制作一个模块并将其包含在您希望具有此行为的不同控制器中:

module SafeDestroyer
  def safe_destroy(resource)
   begin
      resource.destroy
    rescue ActiveRecord::DeleteRestrictionError => e
      resource.errors.add(:base, e)
    end
  end
end

class MyController < ApplicationController
  include SafeDestroyer

  def destroy
    safe_destroy(resource)
  end

end
于 2012-11-04T12:38:54.457 回答
0

我最终做的是从主资源控制器继承我的控制器,我发现它比讨论的其他选项更清洁和强大(在这里找到:http ://roberto.peakhut.com/2010/09/27 /admin-controllers-with-inherited-resources/)。

// controllers/resources_controller.rb
class ResourcesController < ApplicationController
  load_and_authorize_resource
  inherit_resources

  def destroy
    begin
      resource.destroy
    rescue ActiveRecord::DeleteRestrictionError => e
      resource.errors.add(:base, e)
    end
  end
end

然后,只需从该控制器而不是 ApplicationController 继承您的资源丰富的控制器:

// controllers/models_controller.rb
class ModelsController < ResourcesController

end

希望对处于类似情况的人有所帮助。

于 2012-11-04T13:09:11.347 回答