Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

redirect_to does not work as expected on if statement

Trying to figure out why my nil check fails when calling a method with no param, or a param id which yields no records.

@game = Game.where(:id => params[:id]).first

if @game.nil?
  redirect_to root_path
end

In console this works fine.

>> pp @game.nil?
=> true

In application this fails (it never redirects!), why?

EDIT 1:

In console ( with param id nil or non existent record value): This works:

unless Game.exists?(params[:id])
  raise('ok')
end

But not in the real life application :( I tried almost every way to check the record to be existent or valid, the code just runs past this check and continues as is

EDIT 2:

Looking at some other code I noticed I used a return statement IT seems to solve it with that so..

Works:

unless Game.exists?(params[:id])
  redirect_to root_path
  return
end

Fails:

unless Game.exists?(params[:id])
  redirect_to root_path
end

Not quite sure why it needs an return after the redirect_to explicit

like image 951
Rubytastic Avatar asked Dec 09 '22 12:12

Rubytastic


1 Answers

If the redirect_to instruction is not the last instruction in your controller, the redirect will never happen.

if @game.nil?
  redirect_to root_path
  return
end

render @game

Without the return, the redirect_to will be overridden by a render. You have to see it like this: Rails will not immediately redirect upon a redirect_to instruction. It will set the instruction somewhere and once your Controller returns, it will retrieve if there is a set action to do, if not, it will jump to the default action ("render action view")

Possibly would be nice if there was a warning that you overwrite your action if you have multiple redirects/renders, but other than that, this is totally fine behaviour.

Regards.

EDIT

On a side note, if you're using Rails 4, use Game.find_by(id: params[:id]) instead of Game.where(id: params[:id]).first.
If you simply want to check existance, Game.exists?(params[:id]) is a nice way, as others have mentioned. Game.find(params[:id]) will throw an error if id can't be found. A good hint would be to work with slugs as people might guess your games' IDs which is basically a security vulnerability.

like image 80
Danyel Avatar answered Dec 11 '22 09:12

Danyel