LoginSignup
349

More than 5 years have passed since last update.

railsのrenderとredirect_toの違い

Last updated at Posted at 2016-12-02

よく分かってない人を3人程見かけたため、改めて初心者向けにrailsのrenderとredirect_toの違いをまとめてみます。

そもそもMVCのどの部分?

Controller(の特定のAction)が特定のViewを呼びだす部分です。
(部分テンプレートを使用したい場合、View内でrenderを使用することもありますが、今回は割愛します。)

renderとは

Action内で、呼び出すViewを指定するメソッド。そのAction内で@〜〜(インスタンス変数)として格納されたものは、Viewからrubyの構文で呼び出せます。
呼び出すViewの形式は、RHTML形式です。(RHTML形式は、普通のfoo.htmlや、hogehoge.html.erb等のruby構文が実行できる形式のHTMLのこと)

redirect_toとは

HTTPリクエストをサーバーに送り、ユーザーはそこから返ってくるHTMLが表示される。

HTTPリクエストとは

  • URL(http://〜〜)
  • HTTPメソッド(GETとかPOSTとか)
  • その他クッキーとか、ユーザーが送りたいデータとか

を含みますが、
railsのredirect_toでは、HTTPメソッドはGETに固定されています。
また、自サーバーにredirect_toした場合は、routeを通り、routeに指定されたアクションを実行します。
ので、redirect_toが記載されているActionのインスタンス変数はView側から使えません。

renderもredirect_toも指定しない場合

よくありますよね。

controllers/△△.rb
class △△Controller < ApplicationController
  def index
  end
end

とかの、何もAction内に記載しない場合。
これは
render 'index(アクション名)'
を省略しているのと同じ効果を持ちます。
よって、indexアクションから、views/△△/index.html.erb
が呼ばれます。(もちろん、存在しなければmissing templete errorが返ります)

気をつけなければならないこと

  • 1つのActionからは1つのViewしか返せない。

→ そのため、renderやredirect_toを2つ連続して書けません。(よく見るエラーですよね)

controllers/△△.rb
class △△Controller < ApplicationController
  def show
    ~~
    if ~~
      ~~
      render "index"
    end
    render "show"
  end
end

これはエラーになります。if文の評価式がtrueの場合、render "index"を通り、そのままrender "show"も通ってしまいますね。double render error(でしたっけ?)のエラーが返ってきます。

先ほど書いた通り、render "show"を記載しない場合でも、render "show"が省略された形とみなされますので、同じくエラーになります。

controllers/△△.rb
class △△Controller < ApplicationController
  def show
    ~~
    if ~~
      ~~
      render "index"
    end
  end
end

これの対策には、色々ありますが、ある条件下でindex.htmlを表示させたいならば、render "index"の後にreturnを入れるのが良いでしょう。

controllers/△△.rb
class △△Controller < ApplicationController
  def show
    ~~
    if ~~
      ~~
      render "index"
      return
    end
    render "show"
  end
end

renderの色々な書き方

ajaxを使おうとすると、良くrenderにはお世話になりますよね。RailsGuideで色々な書き方がありましたので、ご紹介します。

実のところ、たとえばBooksControllerクラスのupdateアクション内で、本の更新に失敗したらeditテンプレートを出力したいとすると、以下のどのレンダリング呼び出しを行っても最終的には必ずviews/booksディレクトリのedit.html.erbを使用して出力が行われます。

render :edit
render action: :edit
render "edit"
render "edit.html.erb"
render action: "edit"
render action: "edit.html.erb"
render "books/edit"
render "books/edit.html.erb"
render template: "books/edit"
render template: "books/edit.html.erb"
render "/path/to/rails/app/views/books/edit"
render "/path/to/rails/app/views/books/edit.html.erb"
render file: "/path/to/rails/app/views/books/edit"
render file: "/path/to/rails/app/views/books/edit.html.erb"

たまに使うのは、render "/path/to/rails/app/views/books/edit.html.erb"とかですかね。これを使うときは設計が悪い可能性がありますが。。。

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
349