Why won't ternary operator work with redirect

2020-04-19 09:12发布

问题:

I love the ternary operator. It really cleans up the code look, but I have a case where it won't behave correctly in a Rails controller.

I get a syntax error: unexpected tSYMBEG, expecting keyword_do or '{' or '('

I consistently get this issue, it light switches on changing the statement below to a ternary operator. It always happens when I'm trying to use it in conjunction with a redirect statement.

Am I unaware of a rule about this?

if nexti==0 then
  redirect_to :back
else
  redirect_to edit_playt_path(id: actform['playt_id'], i: nexti)
end

nexti==0 ? redirect_to :back : redirect_to edit_playt_path(id: actform['playt_id'], i: nexti)

回答1:

Because of the implied nature of the hash

Ruby / Rails will imply your argument to redirect is a hash which has some awkward implications in your example

When ruby implies the arguments to redirect it sees it as a hash in the following scenario it is parsing it as

nexti==0 ? redirect_to({:back, : redirect_to edit_playt_path(id: actform['playt_id'], i: nexti})

which is invalid, it should work if you explicitly define your hash / argument

nexti==0 ? redirect_to(:back) : redirect_to(edit_playt_path({id: actform['playt_id'], i: nexti}))

most ruby / rails devs will tell you to avoid ternaries for reasons like this, and also general human comprehension of what is going on. Ruby was ment to be an expressive language, so embrace it.

return redirect_to(:back) if nexti==0
redirect_to(edit_playt_path({id: actform['playt_id'], i: nexti}))


回答2:

You need to use parentheses in your call to redirect_to so the parser can correctly understand what’s going on:

nexti==0 ? redirect_to(:back) : redirect_to(edit_playt_path(id: actform['playt_id'], i: nexti))