2009-11-08 49 views
12

所以我在预留模型中有一个名为add_equip的方法。此方法会进行一些检查以确保添加的设备有效(与另一个预留不冲突)。Rails - 从非验证错误的模型中获取错误消息

检查工作。如果不应该添加一件设备,那么它不是,如果应该的话。

问题是我无法弄清楚如何将消息发送回控制器放在闪存消息中?我知道我必须在这里丢失一些东西,但我现在已经搜索了几个小时,并且无法真正找到任何明确的解释,说明如何将错误传递回控制器,除非它们是验证错误。

add_equip在reservations_controller

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 

add_equip在预订模式

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 

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

回答

21

使用add_to_base来存储错误信息对我来说似乎很好,你只需要弄清楚如何把它放到视图中。

如何:

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

假设你要重新显示形式,你也可能使用:

<%= f.error_messages %> 

或者可能:

<%= error_messages_for :reservation %> 

而且,你可能想使用flash [:error],那么你可以用你的视图中的CSS类以不同的颜色着色。

+0

感谢加入“.full_messages。to_sentance“做了诡计,我知道我必须错过一些愚蠢的东西 – raytiley 2009-11-08 15:30:58

+0

在flash中使用model.errors.full_messages是恕我直言,这是一种很好的解决方法。'error_messages_for:model'是显示错误消息的常规方法,如你指出的,解决这个问题的正确方法是把equip_id上的错误代替base,然后渲染编辑表单动作,不需要重定向 – 2009-11-08 16:42:03

+0

这是一个好处,重新渲染会更好 – 2009-11-08 18:42:49

1

我想我可以看到为什么错误不会传回给用户。

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

例如:

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 
+0

感谢您的回复。第一篇文章解决了这个问题,而不改变重定向代码。国际建议虽然是个好主意。谢谢。 – raytiley 2009-11-08 15:32:01

+0

我强烈建议您更改您的代码以遵循我的示例。第一个例子并不遵循显示错误的标准惯例,尽管这本身并不是一件坏事,但您的问题并不新鲜,处理此工作流程的标准方法已经建立。按照惯例,其他开发人员将能够更快地理解您的代码,而无需查明自定义工作流程或如何显示错误消息。 – 2009-11-08 16:34:09