railsのrenderとredirect_toの違い

  • 16
    いいね
  • 0
    コメント

よく分かってない人を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"とかですかね。これを使うときは設計が悪い可能性がありますが。。。