2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

renderとredirect_toの違い、引数の必要性

Last updated at Posted at 2021-01-03

はじめに

現在、フリマサイトのwebアプリを、railsを用いて実装中です。
その中で、**「商品を保存できたら商品一覧画面へ遷移する」**という機能を実装する際に、redirect_toとrenderのURI(パス)に引数をつける必要性が分からなくなってしまった為、メンターさんに聞きました。
その回答内容を以下に整理します。

1.redirect_toとrenderの違い

redirect_toとrenderのそれぞれの意味を、実際の使用例を参考にまとめます。
下部の参考サイトでは図でまとめている為、より理解しやすいかと思います。

1-1. redirect_to : 「アクションの実行」

使用例は、商品を削除したら商品一覧画面へ遷移する(※今回root_pathは商品一覧画面)機能です。

items_controller.rb
def index
  @items = Item.all.order('created_at DESC')
end

def destroy
  item = Item.find(params[:id])
  item.destroy
  redirect_to root_path  #上記indexアクションを実行
end

redirect_toは指定したURIのアクションの実行である為、今回、
「root_pathを実行する」
=「routes.rbに指定したrootを実行する」
=「itemsコントローラーのindexアクションを実行する」

この場合、indexアクションを実行するため、indexアクション内の@itemsは再度生成されます。

もしここでrenderを用いてしまうと、@itemsは再度生成されません。削除することによって、@itemsに含まれるデータが変更されますが、変更前の@itemsを用いてviewへ遷移しているため、下の画像のようなNoMethodErrorが発生します。
renderを用いた場合のエラー画面

1-2. render : 「viewの呼び出し」

使用例は、商品を保存したらredirect_toで商品一覧画面へ遷移し、保存できなかったらrenderで新規投稿画面を表示する(= new.html.erb を呼び出す)機能です。

items_controller.rb
def new
  @item = Item.new
end

def create
  @item = Item.new(item_params)
  if @item.save
    redirect_to root_path
  else
    render :new
  end
end

renderは指定したviewの呼び出しである為、今回、
「new.html.erbを呼び出す」

この場合、createアクション内でnew.html.erbを呼び出しており、newアクションは実行されません。即ち、newアクション内の@itemは生成されません。renderを用いる理由は、データの保存に失敗した場合に、入力していたデータを残したまま入力画面を再度表示できることです。
ちなみに、「createアクション内でnew.html.erbを呼び出している」ことは、商品の保存をあえて失敗すると、ドメイン表示からnewが消えるため、確認できます。

もしここでredirect_toを用いると、@itemが再度生成されます。そのため、保存に失敗した場合、再度newアクションを実行するため、先ほど入力したデータが更新され、空になってしまいます。

2.URIに引数が必要な場合

2-1.redirect_toで引数が必要な場合

redirect_toを用いる際には、パスに引数を与える必要がある場合があります。
以下画像は、ターミナルでrais routesコマンドを実行した際の一例です。
この青部分の様に、URI Patternにidが含まれている場合、パスに引数を与える必要があります。

rails routes

その理由は、redirect先のパスが多数存在する場合は、引数によりアクションを実行する対象のパスを一つ指定しなければならないためです。
Ex) リダイレクト先がツイートのパスで、ツイートが100個ある場合、どのツイートかを引数により指定してあげる必要がある。

2-2.renderで引数が必要な場合

renderで引数が必要な場合は、基本的には必要ありません。
その理由は、renderはviewの使い回しであり、コントローラのアクションは同一であるため、すでに生成したインスタンスを、render先のviewでも用いることができるからです。

3.まとめ

  • redirect_toは再度アクションを実行する
  • renderはviewを切り出す
  • redirect_toを用いる際に、URIにidが含まれている場合は、引数を設定する必要がある
  • renderでは基本的に引数は必要ない

参考サイト

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?