Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby on Rails - Difference between redirect_to 'index' and redirect_to objects_path & redirect_to action: 'index'

I have a simple model and controller. Let's use Kiwis as an example:

def index
    @kiwis = Kiwi.all
end

def destroy
    kiwi = Kiwi.find(params[:id])
    kiwi.destroy
    redirect_to 'index'
end

I use a delete link on the index page. When I use redirect_to 'index' the page does not refresh the model. I have to do a hard refresh on the page in order for the Kiwi to get removed. However, if I use either redirect_to action: 'index' or redirect_to kiwis_path the page will update after the destroy action. I can't seem to find an explanation on this. Can anyone shed some light on the issue.

like image 800
CareBearKate Avatar asked Oct 12 '16 14:10

CareBearKate


1 Answers

Short answer

It is recommend in most cases to use the named route helpers. In your case, the correct thing to do is redirect_to kiwis_path.

Long answer

When you call redirect_to Rails will respond to the current request with a 302 (Redirect) status and the client (i.e. your browser) will then make another request to the specified location. The location for the redirect is determined by the arguments you pass to redirect_to.

When you pass a String to redirect_to it must be a URL (with the protocol and host, e.g. "http://localhost:3000/kiwis" or without, e.g. "/kiwis")

In your case redirect_to kiwis_path is correct. It is equivalent to redirect_to '/kiwis'

When you pass a hash argument action: 'index' the url_for methods is used to generate the URL.

redirect_to action: 'index' is the same as redirect_to url_for(action: 'index'). url_for(action: 'index') will match your route for the path /kiwis.

Therefore redirect_to action: 'index' is equivalent to both redirect_to '/kiwis' and redirect_to kiwis_path

Here you can read about the different arguments which redirect_to accepts and how they are handled.

What happens with redirect_to 'index'?

I've set up a test controller/action to redirect with redirect_to 'index'. Let's see what happens when making a request to it using curl.

~/projects/gitlab $ curl -v -H "Accept: text/html" http://localhost:3000/redirect_test

I've omitted some irrelevant parts of the output:

> GET /select_options HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.43.0
> Accept: text/html
>
< HTTP/1.1 302 Moved Temporarily
< X-Frame-Options: ALLOWALL
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< Location: http://localhost:3000index      <----- That is not what we want!

You can see on the last line shown that the value for the Location header is not the desired URL. When I tested in Chrome the request was cancelled when it encountered this bad redirect. Thus the browser stayed on the same page and did not navigate away. This would explain why you had to do a "hard refresh" to see changes on your page.

like image 181
Wizard of Ogz Avatar answered Oct 13 '22 01:10

Wizard of Ogz