よく分かってない人を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も指定しない場合
よくありますよね。
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つ連続して書けません。(よく見るエラーですよね)
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"
が省略された形とみなされますので、同じくエラーになります。
class △△Controller < ApplicationController
def show
~~
if ~~
~~
render "index"
end
end
end
これの対策には、色々ありますが、ある条件下でindex.htmlを表示させたいならば、render "index"
の後にreturnを入れるのが良いでしょう。
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"
とかですかね。これを使うときは設計が悪い可能性がありますが。。。