2011-09-21 9 views
34

Para el siguiente código, ¿qué ocurre si reemplazamos redirect_to con render o viceversa?¿Son redirect_to y render intercambiables?

def create 
    @product = Product.new(params[:product]) 

    respond_to do |format| 
    if @product.save 
     format.html { redirect_to(@product, :notice => 'Product was successfully created.') } 

    else 
     format.html { render :action => "new" } 
    end 
    end 
end 

Parece correcto reemplazar uno con el otro en el código anterior. ¿Hay un lugar donde solo se debe usar redirect_to o render? Render no hace más que renderizar una vista. Redirect_to envía 302 solicitud al servidor y los parámetros actuales se pierden después de redirigir.

Gracias.

Respuesta

98

Si está utilizando render, cuando el usuario actualiza la página , enviará la solicitud POST anterior nuevamente. Esto puede causar resultados no deseados como la compra duplicada y otros.

enter image description here

Pero si usted está utilizando redirect_to, cuando el usuario actualiza la página, se acaba de solicitar esa misma página de nuevo. Esto también se conoce como el patrón Post/Redirect/Get (PRG).

enter image description here

Así que el lugar donde se debe utilizar redirect_to es cuando estás haciendo una petición HTTP POST y no desea que el usuario vuelva a presentar la solicitud cuando esté hecho (que pueden causar los elementos duplicados y otros problemas).

En Rails, cuando un modelo no se guarda, render se usa para volver a mostrar el formulario con las mismas entradas que se rellenaron previamente. Esto es más simple porque si usa el redireccionamiento, tendrá que pasar las entradas del formulario usando parámetros o sesión. El efecto secundario es que si actualiza el navegador, intentará volver a enviar las entradas del formulario anterior. Esto es aceptable porque probablemente fracasará de la misma manera, o si es exitoso ahora, fue lo que el usuario debería esperar en primer lugar. Para obtener más información detallada sobre render y redirect, lea article.

+0

Gracias. Esta es una explicación completa. – user938363

+0

No creo haber visto una explicación más perfecta, especialmente terminando con POR QUÉ es importante con las diferencias prácticas de casos de uso al final. – ahnbizcad

+2

Nota: actualizar * no * es lo mismo que presionar Enter en la barra de URL.Al presionar Enter en la barra de URL solo se envía una solicitud GET a esa URL. Refreshing vuelve a enviar la última solicitud (que el navegador realiza un seguimiento). –

9

Al redirigir que va a generar una nueva solicitud que realiza un método de controlador, genera sólo hace que la vista asociada. Utiliza renderizar en la creación porque desea mantener el estado del objeto modelo si la operación de guardado falla para que pueda mostrar información sobre sus errores. Si se trató de redirigir a la ruta new_product debe crear un nuevo objeto de modelo y de todos los datos de forma suelta el usuario introducido y los errores, etc, etc

EDITAR (con algo más de información):

Un ejemplo de una La situación donde DEBE usar redirect_to es si su plantilla de vista usa variables de instancia que no se inicializan en el método del controlador del que está redireccionando. Así que probablemente no podría llamar render {:action => 'index'} en su método de crear porque la plantilla índice probablemente hace uso de una variable @products pero su única inicializado @product lo que causaría una excepción

+0

Parece que hacen es seguro de usar en más lugares. ¿Hay algún lugar donde se deba usar redirect_to? Gracias. – user938363

+0

Ver la edición de arriba para un ejemplo – Matthew

+0

Gracias por la respuesta. – user938363

Cuestiones relacionadas