2011-02-16 26 views
1

只是想知道處理以下問題的最佳方法,因爲在互聯網上似乎存在衝突的信息。我的代碼開始生活這樣的..如何處理這個問題 - NoMethodError vs NoRecordFound

@merchant = Merchant.find_by_name(params[:merchant]) 
@products = @merchant.products.all.paginate(:page => params[:page]) 

現在的偉大工程,直到你打一個網址,商家會不會存在即/merchants/thisonedontexist/在這一點,我得到以下錯誤:

`undefined method `products' for nil:NilClass` 

我明白爲什麼我得到這個錯誤。

因此,經過一番研究之後,我決定將我的代碼更改爲以下代碼,並帶有BANG(!),這會引發NoRecordFound錯誤,因此它從不碰到下一行,麻煩是,我現在得到一個醜陋的錯誤:

@merchant = Merchant.find_by_name!(params[:merchant]) 
@products = @merchant.products.all.paginate(:page => params[:page]) 

錯誤是:ActiveRecord::RecordNotFound

所以更多的研究後,我做了以下內容,重定向這些請求到404 ...

def show 
    @merchant = Merchant.find_by_name(params[:merchant]) 
    if [email protected]? 
     @products = @merchant.products.all.paginate(:page => params[:page]) 
    else 
     redirect_to :status => 404 
    end 
    end 

這似乎工作,但似乎很笨重......這裏最好的做法是什麼?

我想爲它顯示一個像"Sorry no category exists"一樣的頁面。

p.s.我是Rails的新手,或許對這個問題有一個非常明顯的答案

回答

2

使用bang版本是最好的方法。 NoMethodError讓我覺得你沒有正確處理應用程序工作流程。

此外,使用爆炸版本可以簡化您的代碼。 在生產中,ActiveRecord::RecordNotFound被解救爲404.這意味着,當錯誤發生時,默認情況下,Rails將解救錯誤並顯示帶有404狀態碼的404錯誤頁面。

查看source code

您可以在您的視圖簡化代碼

def show 
    @merchant = Merchant.find_by_name!(params[:merchant]) 
    @products = @merchant.products.all.paginate(:page => params[:page]) 
end 
+0

感謝您的答案,但我確實需要「.all」,否則我得到以下錯誤:未初始化的常量ActiveRecord :: Calculations :: CALCULATIONS_OPTIONS – Zinc 2011-02-16 12:22:30

+0

恢復#all。 – 2011-02-16 12:23:29

-1

控制器

def show 
    @merchant = Merchant.find_by_name(params[:merchant]) 
    @products = @merchant.products.all.paginate(:page => params[:page]) if @merchant 
    end 

/show.html.erb

if @merchant 
    ... 
    ...your code here 
else 
    <div>No such merchant</div> 
end 
0

由於@simone說,你可以簡化代碼到

def show 
    @merchant = Merchant.find_by_name!(params[:merchant]) 
    @products = @merchant.products.all.paginate(:page => params[:page]) 
end 

現在,當找不到@merchant時,會引發異常。幸運的是,rails提供了一個很好的解決方案來很好地處理異常。

內部控制器(或者,如果你想使你的通用ApplicationController)你寫

rescue_from ActiveRecord::RecordNotFound, :with => :handle_not_found 

def handle_not_found 
    # either 
    flash[:error] = ... some appropriate error message ... 
    redirect_to :root # or some relevant path 
end 

,這樣方法,你可以做任何你想做,你想處理的異常中。

相關問題