2010-03-30 41 views
0

我知道,如果我會寫「redirect_to」而不是「render:action」,我會失去我的@對象的錯誤。對象的錯誤和重定向

我的代碼:

def play 
    @room = params[:id][0,1] 
    @current_players = CurrentPlayer.all(:conditions => {:room => @room}) 
    end 

    def join 
    @new_player = CurrentPlayer.new(:user_id => current_user.id, :team_id => nil, :room => params[:room], :mode => params[:mode], :ip => request.remote_ip) 
    if @new_player.save 
     @game = create_game(params[:room], params[:mode]) 
     if @game 
     flash[:notice] = 'Game created' 
     return (redirect_to :action => "game_details", :recent => true) 
     else 
     flash[:error] = 'Game not created' 
     end 
    else 
    return render(:action => 'play') 
    end 
    redirect_to_back 
    end 

如果用戶點擊「加入」在play.html.erb鏈接,Rails會發送請求「加入」行動,那麼,如果有錯誤,我需要向用戶展示他們。

但我不能寫只是redirect_to時,我的代碼現在:

def join 
    @new_player = CurrentPlayer.new(:user_id => current_user.id, :team_id => nil, :room => params[:room], :mode => params[:mode], :ip => request.remote_ip) 
    if @new_player.save 
     @game = create_game(params[:room], params[:mode]) 
     if @game 
     flash[:notice] = 'Game created' 
     return (redirect_to :action => "game_details", :recent => true) 
     else 
     flash[:error] = 'Game not created' 
     end 
    else 
    # == Very ugly and not DRY (just copypaste from 'play' action) == 
    @room = params[:id][0,1] 
    @current_players = CurrentPlayer.all(:conditions => {:room => @room}) 
    # === 
    return render(:action => 'play') 
    end 
    redirect_to_back 
    end 

我怎樣才能避免這種情況的代碼?

+0

這個問題與'error_messages_for'有什麼關係? – 2012-01-02 22:00:24

回答

1

只要重用您的播放動作,因爲參數是相同的。此外,我建議避免如此多的嵌套if語句

def play 
    @room = params[:id][0,1] 
    @current_players = CurrentPlayer.all(:conditions => {:room => @room}) 
end 

def join 
    @new_player = CurrentPlayer.new(:user_id => current_user.id, :team_id => nil, :room => params[:room], :mode => params[:mode], :ip => request.remote_ip) 
    if ! @new_player.save 
    play 
    return render(:action => 'play') 
    end 

    @game = create_game(params[:room], params[:mode]) 
    if ! @game 
    flash[:error] = 'Game not created' 
    return(redirect_to_back) 
    end 

    flash[:notice] = 'Game created' 
    return redirect_to(:action => "game_details", :recent => true) 
end 
+0

吉米的建議提取設置邏輯是好的。 – 2010-03-30 19:56:27

+0

謝謝,我剛剛添加'玩',它現在=)。只有一個通知 - 我寧願使用「除非」而不是「如果!」 – FancyDancy 2010-03-30 20:17:59

1

只是將通用代碼重構爲私有方法。我在這裏手動調用新方法,但您也可以通過before_filter爲這兩個操作調用它。

def play 
    setup_play 
end 

def join 
    @new_player = CurrentPlayer.new(:user_id => current_user.id, :team_id => nil, :room => params[:room], :mode => params[:mode], :ip => request.remote_ip) 
    if @new_player.save 
    @game = create_game(params[:room], params[:mode]) 
    if @game 
     flash[:notice] = 'Game created' 
     return (redirect_to :action => "game_details", :recent => true) 
    else 
     flash[:error] = 'Game not created' 
    end 
    else 
    setup_play 
    return render(:action => 'play') 
    end 
    redirect_to_back 
end 

private 

def setup_play 
    @room = params[:id][0,1] 
    @current_players = CurrentPlayer.all(:conditions => {:room => @room}) 
end