A lesson about the redirect_to and return keywords while working in a Rails controller

Jason Gong
3 min readNov 1, 2021

So I have written a bit about the return keyword before here and this feels like a nice continuation of that article. I was doing some work inside a Rails controller recently and ran into more more issues with assumptions with returning and how redirect_to works. There was some great learnings here especially with how these worked in different contexts. Let me show you. Here we go!

So heres a little context of the work I was doing. I was in bug fix mode in a food ordering app. An error would occur because a user would remove all items from their cart while on the update item page, press the back button going back to the update page and then clicking refresh. The refreshed update page would error because that page expects, on load, that there be a cart item present. The fix was basically to check if any cart items are present when loading the update page. If not, redirect back to the add items page. Simple.

Now the meat and potatoes of the story…

First, I created this private method to check if there is a cart item. If not, we redirect

Then I call that method in the update action as a guard clause against not having a cart item. Very nice article below on how a guard clause should be used below.

To my surprise, my guard clause did not work in this case.

Even if the condition in ensure_cart_item_exists is met and its redirect is executed, the code execution of the rest of the update action will continue.

Ok. redirect_to does not return automatically?

Hmm... Let us investigate!

Returning explicitly worked! Let’s continue digging into the issue and see what else we may learn and find. Maybe if I extract it from the private method and call the conditional right in the controller action?

Nope, pulling the method straight into the update method did not work. It is definitely a return issue.

After more research, redirect_to only sets the instruction of the response, body, and location. It does nothing else. The code execution will continue normally. And if those instructions are overridden further along the code execution, your intended redirect_to will not execute.

Another option. Use a before_action ! I have not seen the code base for it, but there seems to be an additional return if it sees a redirect_to .

There is a case to use either a before_action or returning explicitly in this case. Using a before_action removes the option of inheriting from this controller in the future. Explicitly returning requires duplicating code. Both options work just as well, minus its tradeoffs.

So this a nice bit of learning gained through this bug fix. I made an assumption here that turned out to cause me a bit of pain. But I learned a bunch in the process. There are so many abstractions that Rails has given us. It is nice to dig into them and see how they work. When running into bugs, test all your assumptions and investigate!

That is all I have today. I hope to share more interesting learnings with everyone in the near future. Thanks for reading and Happy Coding!

--

--