2011-04-21 22 views
57

Solo quiero dar una confirmación sobre el comportamiento de redirect_to.redirect_to! = Return

que tienen código que se parece a:

if some_condition 
    redirect_to(path_one) 
end 

redirect_to(path_two) 

Si el some_condition = true me sale error:

Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action.

Parece que el método sigue ejecutando después de la llamada redirect_to. ¿Necesito crear un código como este:

if some_condition 
    redirect_to(path_one) 
    return 
end 

redirect_to(path_two) 

?

Respuesta

88

Sí, tiene que volver de método cuando se hace redirigir. En realidad, solo agrega encabezados apropiados para el objeto de respuesta.

Puede escribir más forma rubyish:

if some_condition 
    return redirect_to(path_one) 
end 

redirect_to(path_two) 

u otra manera:

return redirect_to(some_condition ? path_one : path_two) 

o de otra manera:

redirect_path = path_one 

if some_condition 
    redirect_path = path_two 
end 

redirect_to redirect_path 
29

De http://api.rubyonrails.org/classes/ActionController/Base.html:

If you need to redirect on the condition of something, then be sure to add “and return” to halt execution.

def do_something 
    redirect_to(:action => "elsewhere") and return if monkeys.nil? 
    render :action => "overthere" # won't be called if monkeys is nil 
end 
+1

+1 para RTFM ;-) – spume

+2

¿Qué pasa si, para estructurar su código más agradable, se pone la redirección en un método privado 'ayudante' en el controlador. Supongo que el formulario de devolución dentro de ese método privado no hará el trabajo, ¿correcto? ¿Cuál es la forma idiomática de manejar eso? ¿O tiene que poner todos los redireccionamientos en el nivel superior de la acción del controlador? – pitosalas

+3

@pitosalas Consulte http://guides.rubyonrails.org/action_controller_overview.html#filters. Dice 'Si un filtro" anterior "representa o redirige, la acción no se ejecutará. –

23

También se puede hacer

redirect_to path_one and return 

que se lee bien.

+0

¿Qué sucede aquí si redirect_to alguna vez devuelve falso o nulo? ¿Eso no significa que la declaración de devolución no se ejecutará? ¿O es esa la intención? El redirect_to docs no especifica cuál es su valor de retorno. – dbeachy1

1

Vale la pena señalar que hay es sin necesidad de return a menos que tenga cualquier código después de redirect_to, como en este ejemplo:

def show 
    if can?(:show, :poll) 
    redirect_to registrar_poll_url and return 
    elsif can?(:show, Invoice) 
    redirect_to registrar_invoices_url and return 
    end 
end 
1

para consolidar el "camino rubyish" ejemplo en Eimantas' answer a dos líneas de código :

return redirect_to(path_one) if some_condition 

redirect_to(path_two)