我想要做的是在无法销毁特定模型时返回错误,而不是异常。目前,它会引发ActiveRecord::DeleteRestrictionError
,但不会返回到Flash消息,也不会添加到模型的errors集合中。
我所做的就是在我的资源丰富的控制器中设置它:
def destroy
begin
resource.destroy
rescue ActiveRecord::DeleteRestrictionError => e
resource.errors.add(:base, e)
end
end
我宁愿不在每个需要这种特殊行为的控制器中管理它。我怎么抽象呢?我认为覆盖ActiveRecord::Base
的destroy方法不是一个好主意,但也许不会有任何陷阱?
我正在使用inherited_resources gem,所以也许有办法通过扩展它来回答这个问题?
我的另一个想法是使用ActiveRecord::Base
(从这里:Rails extending ActiveRecord::Base)扩展ActiveSupport::Concern
,然后在模型到模型的基础上将destroy方法委托给自定义销毁。想法?
答案 0 :(得分:2)
首先我会说我同意不重写ActiveRecord :: Base方法的态度,比如destroy。为了干这种行为你有几个选择,我将列出其中两个:
第一个 - 不是在特定控制器中编写rescue子句,而是可以将它嵌入到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
答案 1 :(得分: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
希望能帮助处于类似情况的人。