何気なく使っていたrenderとredirect_toだったので、それぞれの違いを整理してみたいと思います!
Contents
render
renderはActionView::Baseクラスのインスタンスに使用できるメソッドで、「レンダリング」という意味。ここでのレンダリングは、Webブラウザがサーバーからレスポンスで返ってきたHTMLファイルを解析して、画面に表示させることを意味する。
つまり、このrenderメソッドでは、Webブラウザが表示させるHTMLファイル(viewファイル)を引数として指定する必要がある。
色々なrenderの書き方
renderは色々な書き方があるので、それぞれの開発ルールに応じて書いた方が良いかもしれない。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
##tweets_controllerがあると仮定 render :edit render action: :edit render "edit" render "edit.html.erb" render action: "edit" render action: "edit.html.erb" render "tweets/edit" render "tweets/edit.html.erb" render template: "tweets/edit" render template: "tweets/edit.html.erb" render "/path/to/rails/app/views/tweets/edit" render "/path/to/rails/app/views/tweets/edit.html.erb" render file: "/path/to/rails/app/views/tweets/edit" render file: "/path/to/rails/app/views/tweets/edit.html.erb" |
その他オプションはRailsドキュメント参照
redirect_to
redirect_toはURL(HTTPリクエストメソッド)を指定することで、Webブラウザに新しい処理をリクエストを促すことである。なので、redirect_toにはURLを指定する必要がある。
色々なredirect_toの書き方
redirect_toは色々な書き方があるので、それぞれの開発ルールに応じて書いた方が良いかもしれない。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
##tweets_controllerがあると仮定 # URLへリダイレクト(アクションはconfig/routes.rbを参照) redirect_to URL # indexアクションへリダイレクト redirect_to action: 'index' # tweetsコントローラのindexアクションへリダイレクト redirect_to controller: 'tweets', action: 'index' # tweetsコントローラーのshowアクションのid=7へリダイレクト redirect_to controller: 'tweets', action: 'show', id: 7 # 前ページへリダイレクト redirect_to :back # indexアクションへstatusコード404でリダイレクト redirect_to action: 'index', status: 404 # indexアクションへstatusコード200でリダイレクト(シンボル使用) redirect_to action: 'index', status: :ok # indexアクションへオプション(エラーメッセージ)付きでリダイレクト redirect_to action: 'index', alert: 'ERROR!!' # indexアクションへオプション(通知用メッセージ)付きでリダイレクト redirect_to ({:action => 'index'}), :notice => 'message' # indexアクションへオプション(一時的なメッセージ)付きでリダイレクト redirect_to action: 'index', flash: {success: 'Yes!! Success'} |
URLを指定する必要があるのに、下記のような書き方があることに疑問を持ったがいるかもしれません。
1 |
redirect_to action: 'index' |
でも、この記述が本当に表している意味はこれです。
1 2 |
#Railsをlocalhost:3000で起動したと仮定 localhost:3000/tweets/index |
RailsはWebブラウザから受け取ったリクエストをroutes.rbで処理した上で、コントローラーに渡しており、それをコントローラーの◯◯アクションという言い方をしていますが、元をたどればURL(Webブラウザからのリクエスト)ということを思い出すと理解しやすいです。
renderとredirect_toの使い分け
では、この2つをどのように使い分けるのか?
ざっくり言うとこんな感じです。
■render ⇒ データの取得
■redirect_to ⇒ データの追加、更新、削除
renderとredirect_toの挙動の違い
■render:
controller⇒表示したいviewファイルを指定
⇒viewはcontrollerから指定されたファイルをレスポンスとしてクライアント(Webブラウザ)に返す。
※viewに表示されるインスタンス変数は、この時点でcontrollerから生成されたインスタンス変数。
■redirect_to:
controller⇒クライアント(Webブラウザ)にリダイレクト先のURLを渡す
⇒クライアント(Webブラウザ)は渡されたURLでサーバーにリクエストを送信⇒routes.rbでリクエストを処理し、controllerに渡す
⇒controllerで、新たに処理を始め、新しいインスタンス変数を生成し、viewに渡す⇒viewは、新しいインスタンス変数をもとにHTMLファイルを生成し、レスポンスとしてクライアント(Webブラウザ)に返す。
上記のような挙動の違いから、追加、更新、削除した最新のデータ(新しいインスタンス変数)をブラウザに表示させたいのであれば、redirect_toを使用し、そうでなければrenderを使うことになる。
以下、簡単な記述例です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#tweets_controllerがあると仮定 def index @tweets = Tweet.new end def create @tweet = Tweet.new(tweet_params) if @tweet.save redirect_to :index #このindexは新しいtweetが保存された最新のviewを表示させたい。 else flash[:alert] = "メッセージを入力してください。" render action: :index #このindexはシンプルにviewを表示させたい。 end end |
コードを書く際は、そのコードが何を意味・意図しているのかを理解しているのとそうでないのとでは、今後エンジニアとして雲泥の差が出てきそうなので、注意しようと思います!
参考記事
https://qiita.com/jumpyoshim/items/ed10721c26963abdf121
https://qiita.com/1ulce/items/282cccba1e44158489c8
https://qiita.com/morikuma709/items/e9146465df2d8a094d78
https://qiita.com/ko8@github/items/c0e7d2511b569e2d892e