def show
@user = User.find(params[:id])
redirect_to root_url and return unless @user.activated?
end
上記のコードが行なっていることはなんとくわかるのですがand returnが何をしているのか詳しく理解できたいなかったので調べてみることにしました。
まずはand returnから調べていきます。
参考資料:2.2.14 二重レンダリングエラー
"Can only render or redirect once per action"
例
def show
@book = Book.find(params[:id])
if @book.special?
render action: "special_show"
end
render action: "regular_show"
end
上記の例では"Can only render or redirect once per action" エラーになってしまいます。理由として
例えば@book.special?がtrueの場合、レンダリングを開始し、@book変数をspecial_showビューに転送します。
しかし、showアクションのコードはそこでは止まりません。showアクションのコードは最終行まで実行され
regular_showビューのレンダリングを行おうとします。ここでエラーが出力されます。1つのコード実行パス内では、renderメソッドやredirectメソッドの実行は1度だけにしなければなりません。ですので明示的にreturnが必要にな
ります。修正したコードを以下に示します。
def show
@book = Book.find(params[:id])
if @book.special?
render action: "special_show"
return
end
render action: "regular_show"
end
ここでrender action: "special_show"とreturnを一行にして可読性をあげるためにand を使います。
修正したコードを以下に示します。
def show
@book = Book.find(params[:id])
if @book.special?
render action: "special_show" and return
end
render action: "regular_show"
end
&&を使用すると評価の優先順位が高くてうまく機能しないため注意です。(優先順位参考資料)
またrender の戻り値がtureの以外の場合はreturnは実行されないのも注意です。
ここまでrenderの話でしたがredirect_toでも同じようにredirect_toを行なっても即時にメソッドが中断され
ることはないので上記のようにand returnを使用します。