2009-11-08 71 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