LoginSignup
0
0

More than 3 years have passed since last update.

[Rails]redirect_toとrenderの違いについて[初心者]

Last updated at Posted at 2020-11-16

はじめに

いきなりですが、redirect_torenderって、初めて見たときは、両者の違いがよく分からなかったですよね。
深掘りして、一緒に学んでいきましょう!

redirect_toとrenderの違い

redirect_to: HTTPリクエストをサーバーに送り、ユーザーはそこから返ってくるHTMLが表示される。
render: アクションの中で、呼び出すViewファイルを指定するメソッド。

言葉だけだと、分かりづらい部分があると思うので、それぞれの処理の流れについて解説します。

それぞれの処理の流れについて

redirect_toの処理の流れ
controllerの処理でredirect_toを実行
redirect_toの引数で指定したURLHTTPリクエスト(GET!!)を実行
HTTPリクエスト(GET!!)されたURLに対応するルーティング処理を実行
④ルーティング処理に対応したcontroller、アクションが呼び出され処理を実行
⑤処理に応じたviewのレンダリングを実行

①controller(redirect_to) → ②HTTPリクエスト(GET!!) → ③ルーティング → ④controller → ⑤view

renderの処理の流れ
controllerの処理でrenderを実行
renderのオプションで指定したviewファイルを表示する

①controller(render) → ②view

ここで注意が必要なのは、redirect_toの指定先は、必ずGETメソッドのルーティングになるということです。

redirect_toやrenderの指定がない場合

たまに見かけますよね。
下の状態のようなコントローラーを。

controllers/books.rb
class BooksController < ApplicationController
  def index
  end
end

アクション内に、何も記載がない場合は、自動的にrenderが実行されます!!
つまり、上の場合だと、render 'index'が省略されているものと考えられ、このアクションからviews/books/index.html.erbが呼び出されます。

よく見る記載方法

それではここで、よく使われているredirect_toとrenderの記述例について見てみましょう!

controllers/books.rb
class BooksController < ApplicationController
  def create
    @book = Book.new(book_params)
    @book.user_id = current_user.id
    if @book.save
      redirect_to books_path, flash[:notice] = "投稿成功!!"
    else
      flash.now[:alert] = "投稿失敗!!"
      render 'new'
    end
  end
end

投稿を行う際に、saveメソッドの結果がtrueならば投稿一覧ページにリダイレクトし、falseなら新規投稿用のページを再表示するように設定しています。
render 'アクション名'で同じコントローラの別アクションのViewを表示できます。
 コントローラ名を指定することで、他のコントローラのViewも表示できます。

なぜfalseの場合はrenderを使用するのか

renderを利用して、viewファイルを表示する際に、アクションを呼び出していないことにお気づきでしょうか。
↑のrender 'new'は、books/new.html.erbを表示させているだけであり、newアクションを経由しているわけではないのです。

今回のパターンだと、投稿に失敗しているからnewページを表示させたいのですが、redirect_toを使用してしまうと、newアクションを呼び込み、インスタンス変数に空のメソッドを渡してしまうことで、newアクションがリセットされた状態になるので、ユーザーが打ち込んだデータが消えます。
よって、エラーメッセージを打ち出す為の情報も消えてしまう為、ユーザーは「なぜ投稿できなかったのか」を窺い知ることができなくなります。

ややこしいですが、大事な分岐点を決めるものなので、腹落ちするまで向き合ってもらえればと思います。

(補足)render時のフラッシュメッセージについて

本筋とは離れてしまうので、詳細は述べませんが、表示したビュー内にメッセージを出したい場合、以下のように記述します。

redirect_toの場合
flash[:notice] = "メッセージ"
 または
notice: "メッセージ"
renderの場合
flash.now[:alert] = "メッセージ"  #nowがついている!!!!

おわりに

初心者の方が間違いやすいredirect_toとrenderの違いについて説明しました!!
解説している中で、自分自身勉強になることが多く、アウトプットの重要性を痛感しています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0