2011-09-21 10 views
34

Dla kodu poniżej, co się stanie, jeśli zastąpienie przekierowania_do renderem lub wersetem wiersza?Czy polecenie redirect_to i render są wymienialne?

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 

Wygląda na to, że zastąpienie jednego z drugim w powyższym kodzie. Czy istnieje miejsce, w którym należy użyć tylko redirect_to lub render? Render nie robi nic poza renderowaniem widoku. Redirect_to wysyła 302 żądania do serwera, a bieżące parametry są tracone po przekierowaniu.

Dzięki.

Odpowiedz

98

Jeśli używasz render, gdy użytkownik odświeża stronę , ponownie prześle poprzednie żądanie POST. Może to spowodować niepożądane wyniki, takie jak zduplikowany zakup i inne.

enter image description here

Ale jeśli używasz redirect_to, gdy użytkownik odświeża stronę, to będzie po prostu zażądać ponownie tę samą stronę. Jest to również znane jako wzór Post/Redirect/Get (PRG).

enter image description here

więc miejsce, w którym powinien być stosowany redirect_to jest, gdy robisz żądania HTTP POST i nie chcesz, aby użytkownik ponownie złożyć wniosek, gdy to się robi (co może powodować duplikaty i inne problemy).

W Railsach, gdy nie można zapisać modelu, render służy do ponownego wyświetlenia formularza z tymi samymi wpisami, które zostały wcześniej wypełnione. Jest to prostsze, ponieważ jeśli używasz przekierowania, będziesz musiał przekazać dane formularza za pomocą parametrów lub sesji. Efektem ubocznym jest to, że jeśli odświeżysz przeglądarkę, spróbuje ponownie przesłać poprzednie wpisy formularza. Jest to dopuszczalne, ponieważ prawdopodobnie nie powiedzie się w ten sam sposób, lub jeśli odniosło sukces już teraz, to było to, czego użytkownik powinien się spodziewać w pierwszej kolejności.

Aby uzyskać więcej szczegółowych wyjaśnień na temat render i redirect, należy przeczytać to article.

+0

Dzięki. To jest dokładne wyjaśnienie. – user938363

+0

Nie sądzę, że widziałem bardziej doskonałe wyjaśnienie, szczególnie na zakończenie, DLACZEGO jest to ważne z praktycznymi różnicami w użyciu na końcu. – ahnbizcad

+2

Uwaga: odświeżanie to * nie * to samo, co naciśnięcie klawisza Enter w pasku adresu URL.Naciśnięcie klawisza Enter w pasku adresu URL powoduje wysłanie żądania GET do tego adresu URL. Odświeżanie powoduje ponowne przesłanie ostatniego żądania (które przeglądarka śledzi). –

9

Po przekierowaniu wygenerujesz nowe żądanie, które uderza w metodę kontrolera, a renderowanie powoduje renderowanie powiązanego widoku. Używasz renderowania w tworzeniu, ponieważ chcesz zachować stan obiektu modelu, jeśli zapis nie powiedzie się, aby można było renderować informacje o jego błędach. Jeśli próbował skierować na ścieżkę new_product chcesz utworzyć nowy obiekt modelu i stracić wszystkie dane formularza użytkownik wprowadził i żadnych błędów etc etc

edycji (z niektórymi więcej informacji):

przykładem sytuacja, w której MUSISZ użyć redirect_to, to jeśli twój szablon widoku wykorzystuje zmienne instancji, które nie zostały zainicjowane w metodzie kontrolera, z którego przekierowujesz. Więc chyba nie mógł zadzwonić render {:action => 'index'} w sposobie tworzenia, ponieważ indeks szablon prawdopodobnie używa zmiennej @products ale twoja jedyna zainicjowany @product więc spowodowałoby to wyjątek

+0

Wygląda na to, że renderowanie jest bezpieczne w wielu miejscach. Czy jest gdziekolwiek, gdzie należy użyć przekierowania? Dzięki. – user938363

+0

Zobacz edycję powyżej dla przykładu – Matthew

+0

Dzięki za odpowiedź. – user938363