【问题标题】:Rails - Getting an error message from the model that is not a Validation errorRails - 从模型中获取不是验证错误的错误消息
【发布时间】: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

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

【问题讨论】:

    标签: ruby-on-rails error-handling


    【解决方案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 的建议是个好主意。谢谢。
    • 我强烈建议您更改代码以遵循我的示例。第一个示例未遵循显示错误的标准约定,尽管这本身并不是一件坏事,但您的问题并不新鲜,并且已经建立了处理此工作流的标准方法。按照惯例,其他开发人员将能够更快地理解您的代码,而无需弄清楚自定义工作流程或如何显示错误消息。
    猜你喜欢
    • 2016-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-07
    • 2015-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多