0

我正在使用 gem Responders,但我无法显示我使用erros.add(:base, 'Error message').

在我的控制器上,在 之前respond_with @app,我调试了@app对象并且它错误@app.errors.any?返回true

在我看来,当我检查flashand@app对象时,没有一个错误

应用控制器

# app_controllers.rb
def destroy
  @app = current_company.apps.find(params[:id])
  @app.destroy
  respond_with @app
end

应用模型

# 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之后的对象@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=

4

4 回答 4

2

jefflunt 是正确的,当有人调用#valid?它时,它会清除错误数组:请参阅https://github.com/rails/rails/blob/4a19b3dea650351aa20d0cad64bf2d5608023a33/activemodel/lib/active_model/validations.rb#L333

验证器旨在100% 确定对象的有效性,而不是在您自己添加错误以供以后使用时。

虽然 ActiveRecord 确实覆盖#valid?,但它仍然调用superhttps ://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, ...),但这不是一种安全的方式来存储和检索错误以备后用。


此外,这只是一个建议,但我建议您进行救援StandardErrorException除非您绝对必须这样做。内存不足错误和类似的东西是Exceptions,但是你想要拯救的每个正常错误都应该继承自StandardError. 仅供参考。

于 2015-01-03T21:52:18.803 回答
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哈希的意外内容?

如果这不是问题,那么何时@app.errors.any?返回true,然后在代码中将内容打印@app.errors到您的日志中,以便您查看问题所在。

于 2013-10-28T19:02:34.287 回答
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"

可以?

于 2013-10-28T19:27:19.053 回答
0

我必须同意@p.mastinopoulos 对此的看法。这应该通过内置验证来处理。听起来您需要构建自定义验证器。

http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validate

尝试将您的替换before_destroyvalidate

validate :destroy_on_riak, on: :destroy

没有尝试过,但如果它不起作用,您可能需要考虑创建文档中引用的自定义验证器。

于 2013-10-31T19:21:26.493 回答