2010-03-13 71 views
1

我該如何幹下面的代碼?我需要設置一系列的ELSE嗎?我通常會發現「如果遇到這種情況,停止」,「如果遇到這種情況,停止」,而不是一堆嵌套的ifs。Ruby操作:如何避免一堆退貨來暫停執行?

我發現redirect_to的和渲染不停止動作執行...

def payment_confirmed  
    confirm_payment do |confirmation|  
    @purchase = Purchase.find(confirmation.order_id) 
    unless @purchase.products_match_order_products?(confirmation.products) 
     # TODO notify the buyer of problems 
     return 
    end 

    if confirmation.status == :completed 
     @purchase.paid!      
     # TODO notify the user of completed purchase 
     redirect_to purchase_path(@purchase) 
    else  
     # TODO notify the user somehow that thigns are pending 
    end 

    return 
    end 

    unless session[:last_purchase_id] 
    flash[:notice] = 'Unable to identify purchase from session data.' 
    redirect_to user_path(current_user) 
    return 
    end 

    @purchase = Purchase.find(session[:last_purchase_id]) 

    if @purchase.paid? 
    redirect_to purchase_path(@purchase)  
    return 
    end 

    # going to show message about pending payment 
end 

回答

0

添加and return false到redirect_to的結束或呈現在該點停止執行。這應該有助於清理你的東西。

+0

返回false會導致Rails渲染nothign? – Alexandre 2010-03-13 23:05:52

3

您可以執行以下操作來減少代碼。

1)使用

return redirect_to(..) 

代替

redirect_to(..) 
return 

2)提取flashredirect_to代碼的常用方法。

def payment_confirmed  
    confirm_payment do |confirmation|  
    @purchase = Purchase.find(confirmation.order_id)   
    return redirect_with_flash(...) unless @purchase.products_match_..(..) 

    return redirect_with_flash(...) unless confirmation.status == :completed 

    @purchase.paid! 
    return redirect_to(...) 
    end 

    return redirect_with_flash(...) unless session[:last_purchase_id]  

    @purchase = Purchase.find(session[:last_purchase_id]) 
    return redirect_to(...) if @purchase.paid? 

    # going to show message about pending payment 
end 

創建一個新方法,在顯示一條Flash消息後重定向到給定的URL。

def redirect_with_flash url, message 
    flash[:notice] = message 
    redirect_to(url) 
end 

注意我在一些地方的可讀性截斷上面的代碼。

+0

嗨Kandada。認爲代碼可以重構以避免早日返回? – Alexandre 2010-03-15 02:24:01

+0

結合'return'和'redirect_to'已經減少了冗餘。你能否在你的問題中提供更多細節? – 2010-03-15 02:57:08

0

您也可以將步驟分解爲單獨的方法。所以結束代碼看起來是這樣的:

def payment_confirmed  
    confirm_payment do |cnf|  
    confirmation_is_sane?(cnf) && purchase_done?(cnf) 
    return 
    end 
    has_last_purchase? && last_purchase_paid? 
end 

對於保看起來像:

def confirmation_is_sane?(confirmation) 
    @purchase = Purchase.find(confirmation.order_id) 
    unless @purchase.products_match_order_products?(confirmation.products) 
    # TODO notify the buyer of problems and render 
     return false 
    end 
    true 
end 
def purchase_done?(confirmation) 
    if confirmation.status == :completed 
     @purchase.paid!      
     # TODO notify the user of completed purchase 
     redirect_to purchase_path(@purchase) 
     return false 
    else  
     # TODO notify the user somehow that thigns are pending and render 
     return true 
    end 
end 
def has_last_purchase? 
    unless session[:last_purchase_id] 
    flash[:notice] = 'Unable to identify purchase from session data.' 
    redirect_to user_path(current_user) 
    return false 
    end 

    @purchase = Purchase.find(session[:last_purchase_id]) 
    return true 
end 
def last_purchase_paid? 
    if @purchase.paid? 
    redirect_to purchase_path(@purchase)  
    return false 
    end 
    # going to show message about pending payment 
    return true 
end 

這基本上只是用真/與& &的falses做早期退出,而不是使用回報,但對我來說似乎更容易閱讀。在其他方法中,您仍然需要撥打render,但這不應該太大。

確認訂單和最後一次購買之間的區別似乎也很奇怪,但也許這是confirm_payment工作方式的一個神器。

相關問題