renderとredirect_toの違い

こんにちは!kossyです!





本日の気になるニュースはこちら
tech-camp.in

気になるニュースというか、
「IT界隈の情報が週単位でまとまって集められるサイト見つけたのでシェアします!」
といった感じですね笑

この中で気になったニュースを挙げると、


「副業サービス カオスマップ」の2018年版が公開
というニュースですね。

個人型の確定拠出年金ideco」や、政府が副業解禁を後押しするような流れもあり、
「老後の面倒は自分でみてくださいね」といった流れになるのは明白で、
自分の身を守れるのは自分だけ、という時代になりつつあると思っています。

その中で、高度とされているスキルを身につけ、副業として本業以外でも収入を得ることは
マストになっていくのではないでしょうか。










さて、今回はrailsでよく使われるrenderとredirect_toの違いを
ブログに残してみたいと思います。

環境
Rails 5.1.6
Ruby 2.5.1





renderとredirect_toの違い

各メソッドの仕様を書くと、
render: コントローラーのアクション内で、呼び出すViewを指定するメソッド。

redirect_to: 引数に指定したURLへリダイレクトするメソッド

というようになります。

また、フラッシュメッセージの実装の仕方も若干異なります。
その点については後述します。





renderメソッドの使い方

def update
    if current_user.update(user_params)
      redirect_to root_path, notice: 'successed to update'
    else
      flash.now[:alert] = "failed to update"
      render :edit
    end
end

  private

  def user_params
    params.require(:user).permit(:name, :email)
  end

redirect_toも使ってしまっていますが、
基本的には、renderのユースケースは、
「データを取得して表示する場合」になります。

上記のコードは、ユーザ情報の更新に成功した場合は、
ルートパスへリダイレクトし、フラッシュメッセージを表示させ、
失敗した場合はrenderでeditアクションを呼び出し、
フラッシュメッセージを伴って、
再度編集画面が表示されるように実装しています。

フラッシュメッセージですが、
renderメソッドで表示したビュー内に出したい場合は、

flash.now[:alert] = "フラッシュメッセージ"

と記述する必要があります。
なぜそうする必要があるのかは下の項で説明します。





redirect_toの使い方

before_action :set_review, only: [:show, :destroy]

def destroy
  @review.destroy
  redirect_to root_path, notice: '投稿の削除に成功しました'
end

  private

  def set_review
    @review = Review.find(params[:id])
  end

redirect_toのユースケースは、
「データの追加・更新・削除をする場合」になります。

上記のコードでは、取得したインスタンスをdestroyメソッドで削除し、
redirect_toでルートパスへリダイレクトし、フラッシュメッセージを表示しています。

redirect_toでフラッシュメッセージを出したい場合、

flash[:notice] = "メッセージ"

でもいいですし、

notice: "メッセージ"

でもOKです。





なぜrenderとredirect_toでフラッシュの記述が違うのか

なぜ記述が異なるかというと、
flashメッセージの表示期間に関わっています。flashを使った場合のメッセージの表示期間は次のリクエストまでです。
現在のリクエストとリダイレクトのリクエスト分がメッセージの表示期間と合致するため、リダイレクト先でflashメッセージが表示されます。

対して、flash.nowの表示期間は現在のリクエストまでです。
リダイレクトを伴わない場合(上記のコードで言うと、render :newを使っているところ)、
flash[:notice]としてしまうと、メッセージは表示されるのですが、メッセージの表示期間は次のリクエストまでなので、
必要以上にメッセージが表示されてしまいます。
なので、redirect_toとrenderでフラッシュの記法が異なります。





参考にさせていただいた記事
railsのrenderとredirect_toの違い - Qiita
render - リファレンス - - Railsドキュメント
redirect_to - リファレンス - - Railsドキュメント