Rails - 从模型中获取不是验证错误的错误消息

Posted

技术标签:

【中文标题】Rails - 从模型中获取不是验证错误的错误消息【英文标题】:Rails - Getting an error message from the model that is not a Validation error 【发布时间】:2010-12-14 07:02:37 【问题描述】:

所以我在预订模型中有一个名为 add_equip 的方法。此方法会进行一些检查以确保添加的设备有效(不与另一个预订冲突)。

检查有效。如果不应该添加一件额外的设备,它不是,如果它应该是。

问题是我不知道如何将消息发送回控制器以放入闪存消息中?我知道我一定在这里遗漏了一些东西,但是我已经用谷歌搜索了几个小时,并没有真正找到任何明确的解释如何将错误传递回控制器,除非它们是验证错误。

在 reservations_controller 中添加_equip

    def add_equip
    @reservation = Reservation.find(params[:id])
    @addedEquip = Equip.find(params[:equip_id])

    respond_to do |format|
     if @reservation.add_equip(@addedEquip)
        flash[:notice] = "Equipment was added"
        format.html  redirect_to(edit_reservation_path(@reservation)) 
     else
        flash[:notice] = @reservation.errors
        format.html  redirect_to(edit_reservation_path(@reservation)) 
     end
    end
  end

在预订模型中添加装备

def add_equip equip
   if self.reserved.find_by_equip_id(equip.id)
     self.errors.add_to_base("Equipment Already Added")
     return false
   elsif !equip.is_available?(self.start, self.end)
     self.errors.add_to_base("Equipment Already Reserved")
     return false
   else
     r = Reserved.new
     r.reservation = self
     r.equip = equip
     r.save
   end
  end

任何帮助将不胜感激。我知道我在这里缺少一些基本的东西。

【问题讨论】:

【参考方案1】:

使用add_to_base 存储错误消息对我来说似乎很好,您只需要弄清楚如何将其放入视图中。

怎么样:

flash[:notice] = @reservation.errors.full_messages.to_sentence

假设您要重新显示一个表单,您也可以使用:

<%= f.error_messages %>

或者可能:

<%= error_messages_for :reservation %>

另外,您可能想要使用 flash[:error],然后您可以在视图中使用 CSS 类对其进行不同的着色。

【讨论】:

感谢添加“.full_messages.to_sentance”。我知道我一定错过了一些愚蠢的事情。 在 Flash 消息中使用 model.errors.full_messages 恕我直言,这是解决此问题的一种糟糕方法。正如您所指出的,'error_messages_for :model' 是显示错误消息的传统方式。解决问题的正确方法是将错误放在equip_id 而不是base 上,然后只呈现编辑表单操作。无需重定向。 这点很好,重新渲染页面会更好。 谢谢!它也对我有用! 您是否必须先自己实现错误才能使其正常工作? api.rubyonrails.org/classes/ActiveModel/Errors.html【参考方案2】:

我想我可以理解为什么错误没有被传回给用户。

问题在于,当操作失败时,您正在向用户发送重定向,而不是仅仅进行渲染,这意味着您丢失了您设置为在请求中使用的所有变量。无需向 Flash 添加错误,只需渲染编辑页面并将 Flash 设置为正常消息,一切都应该没问题。

例如:

def add_equip
  @reservation = Reservation.find(params[:id])
  @addedEquip = Equip.find(params[:equip_id])

  respond_to do |format|
    if @reservation.add_equip(@addedEquip)
      flash[:notice] = "Equipment was added"
      format.html  redirect_to(edit_reservation_path(@reservation)) 
    else
      flash[:error] = 'Error adding equipment'
      format.html  render :action => :edit 
    end
  end
end

现在您可以继续使用普通表单助手来显示错误消息。

另外,只是对模型代码的一点建议,尽可能尝试使用 i18n(包括控制器中的闪存消息)。虽然这主要是个人喜好,但它为您的所有消息和特定文本提供了一个逻辑主页,并且 alos 允许您创建可以在一个地方更改的一般或默认消息,而不是在多个模型和控制器中复制更改。

例如。

def add_equip equip
  if self.reserved.find_by_equip_id(equip.id)
    self.errors.add_to_base(:already_added)
    return false
  elsif !equip.is_available?(self.start, self.end)
    self.errors.add_to_base(:already_reserved)
    return false
  else
    r = Reserved.new
    r.reservation = self
    r.equip = equip
    r.save
  end
end

【讨论】:

感谢您的回复。第一篇文章在不更改重定向代码的情况下解决了这个问题。不过,i18n 的建议是个好主意。谢谢。 我强烈建议您更改代码以遵循我的示例。第一个示例未遵循显示错误的标准约定,尽管这本身并不是一件坏事,但您的问题并不新鲜,并且已经建立了处理此工作流的标准方法。按照惯例,其他开发人员将能够更快地理解您的代码,而无需弄清楚自定义工作流程或如何显示错误消息。

以上是关于Rails - 从模型中获取不是验证错误的错误消息的主要内容,如果未能解决你的问题,请参考以下文章

如何在Rails 5中更改设计中的验证错误消息

从 JQuery 验证器获取验证消息

Rails 3 - 获取一个字段的完整错误消息

jquery验证插件不在rails中显示错误消息

如何让模型验证与 Rails 中的视图层对话以提供简单的功能?

rails 3 的验证自定义消息