我正在使用gem Responders,但我无法使用erros.add(:base, 'Error message')
显示我在模型上创建的错误。
在我的控制器上,在respond_with @app
之前,我调试了@app
对象,有错误@app.errors.any?
返回true
在我看来,当我检查flash
和@app
个对象时,没有错误
App控制器
# app_controllers.rb
def destroy
@app = current_company.apps.find(params[:id])
@app.destroy
respond_with @app
end
App模型
# app.rb
before_destroy :destroy_on_riak
# ...
def destroy_on_riak
# SOME CODE HERE
rescue Exception => e
errors.add(:base, I18n.t("models.app.could_not_destroy", :message => e.message))
return false
end
应用视图
# apps.html.haml
-flash.each do |name, msg|
%div{:class => "flash #{name}"}
=content_tag :p, msg if msg.is_a?(String)
这是@app对象之前 @app.destroy
"#<ActiveModel::Errors:0x00000004fa0510 @base=#<App id: 34, ...>, @messages={}>"
这是 @app.destroy
"#<ActiveModel::Errors:0x00000004fa0510 @base=#<App id: 34, ...>, @messages={:base=>[\"Não foi possível excluir a aplicação: undefined method `get_or_new' for #<App:0x00000004f824c0>\"]}>"
为了简单起见,我删除了@base=
中的内容。
答案 0 :(得分:2)
jefflunt是正确的,当一个人调用#valid?
时,它会清除错误数组:请参阅https://github.com/rails/rails/blob/4a19b3dea650351aa20d0cad64bf2d5608023a33/activemodel/lib/active_model/validations.rb#L333
验证程序旨在 100%确定对象的有效性,而不是在您自己添加错误以供以后使用时。
虽然ActiveRecord会覆盖#valid?
,但它仍会调用super
:https://github.com/rails/rails/blob/4a19b3dea650351aa20d0cad64bf2d5608023a33/activerecord/lib/active_record/validations.rb#L58
如果你想添加错误并坚持下去,我建议这样:
def failures
@failures ||= []
end
validate :copy_failures_to_errors
def copy_failures_to_errors
@failures.each { |f| errors.add(*f) }
end
然后修改您的rescue
:
def destroy_on_riak
# SOME CODE HERE
rescue Exception => e
failures.push([:base, I18n.t("models.app.could_not_destroy", :message => e.message)])
return false
end
我知道这看起来很复杂,我知道网上甚至有人使用或推荐errors.add(:base, ...)
的例子,但这不是一种安全存储和检索错误的方法。
另外,只是一个推荐,但我建议你拯救StandardError
而不是Exception
,除非你绝对必须。内存不足错误和类似的内容是Exception
s,但是你想要解决的每个正常错误都应该从StandardError
继承。仅供参考。
答案 1 :(得分:1)
这个谜似乎是(a)你可能没有调用正确的方法,或者(b).errors
哈希不包含你认为它包含的内容。
在您的控制器中,您正在调用@app.destroy
,但添加错误的方法称为destroy_on_riak
你确定你不打算输入这个吗?
# app_controllers.rb
def destroy
@app = current_company.apps.find(params[:id])
@app.destroy_on_riak # <= The offending line?
respond_with @app
end
或者您的代码示例中是否缺少before_destroy
回调,而这些回调又会调用destroy_on_riak
?从包含的代码中我看不到destroy_on_riak
方法被调用的任何地方,所以这只是猜测。
.errors
hash的意外内容?如果这不是问题,那么当@app.errors.any?
返回true
时,代码中的那一点会将@app.errors
的内容打印到您的日志中,这样您就可以看到错误了。
答案 2 :(得分:1)
我会给你一些提示:
提示1
您的表单可能正在valid?
对象上调用@app
。 valid?
方法清除实例上的errors
数组。
在验证上下文之外使用errors
数组/构造是不正确的。但这是MHO。
提示2
根据Responders gem(我以前从未使用过),您的语言环境只需要具有正确的配置。例如:
flash:
actions:
create:
notice: "{resource_name} was successfully created"
update:
notice: "{resource_name} was successfully updated"
destroy:
notice: "{resource_name} was successfully destroyed"
alert: "{resource_name} could not be destroyed"
是吗?
答案 3 :(得分:0)
我必须同意@p.mastinopoulos。这应该通过内置验证来处理。听起来你需要建立一个自定义验证器。
http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validate
尝试将before_destroy
替换为validate
:
validate :destroy_on_riak, on: :destroy
没有尝试过,但如果它不起作用,您可能需要考虑创建文档中引用的自定义Validator。