我知道,如果我写“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 :(得分: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
答案 1 :(得分: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