Rails中redirect_to后sleep延迟及flash后置生效问题咨询
嘿,这个问题挺典型的,刚好能帮你理清Rails里redirect_to和flash的工作逻辑,咱们一步步拆解:
为什么redirect_to后加sleep会让网站卡顿10秒?
你得先明白Rails处理请求的核心流程:控制器action里的所有代码都会先执行完毕,Rails才会把最终的响应发送给浏览器。
redirect_to root_url这个方法并没有立刻给浏览器发重定向指令,它只是告诉Rails:「等下要给浏览器返回一个302重定向到首页的响应」。所以你在它后面加的sleep 10会被正常执行——整个create action会先停10秒,等sleep结束后,Rails才会把重定向响应发送给浏览器,这时候浏览器才会跳转到首页,所以你会感觉网站先卡顿10秒。
而render的情况看起来不一样,是因为render "new"是直接在当前请求里渲染登录页面的视图,同样要等action代码跑完才会把渲染好的页面发给浏览器,但你测试时可能没在render后加sleep;或者你误以为render会立刻输出内容,但本质上两者都是要等action执行完才会发送响应,只是render返回的是视图内容,redirect_to返回的是重定向指令而已。
为什么redirect_to后设置flash还能生效?
这也是因为Rails处理flash的时机:flash的内容是在整个action执行完毕后才被写入session的,而不是在调用redirect_to的瞬间。
你虽然把flash[:danger] = message写在了redirect_to后面,但这段代码还是会被执行,等action跑完后,Rails会把flash的内容存入session,然后发送重定向响应。当浏览器跳转到首页的新请求时,就能从session里读取到这个flash消息,所以它能正常显示。
不过这确实是不良实践!因为按照常规逻辑,我们会认为redirect_to之后的代码不会被执行(很多新手会误以为redirect_to会终止action),如果后面不小心加了其他逻辑,很容易出bug。正确的写法应该是先设置flash再调用redirect_to,或者在redirect_to后面加return来终止后续代码执行:
# 推荐写法1:先设置flash再重定向 message = "Account not activated. " message += "Check your email for the activation link." flash[:danger] = message redirect_to root_url # 推荐写法2:重定向后加return,避免后续代码执行 redirect_to root_url return message = "..." # 这段代码就不会被执行了
内容的提问来源于stack exchange,提问作者Lil E

