render は Rails で HTTP レスポンスを作るための大事なメソッドです。
初心者の方は特に render メソッドをなんとなく使っていないでしょうか?
かくいう私も Rails 学びたてのころは既存のコードを参考に勘で使っていました。
勘でなんとかなるのは最初のうちだけで、すぐに限界が訪れます。
なにより、よく分からないメソッドを使うのは不安が残ります。
Rails のコードを自信を持って書けるようになったのは render メソッドの仕組みやルールをしっかりと把握してからでした。
本記事では render メソッドの基本から引数・オプションの仕組みについて徹底的に解説します。

render メソッドを理解できれば Rails 力がみるみる向上しますよ!
render メソッドとは

render メソッドは以下のいずれかを指定してHTTPレスポンスを作成します。
(上図ではビューテンプレートのファイルパスを渡してHTTPレスポンスを作成する様子を模式化しています)
render メソッドはコントローラとビューから呼び出せます。
コントローラから呼び出す render
まずコントローラから呼び出す render について解説します。
基本形は以下の通りです。
render 'ビューテンプレートのファイルパス'
ビューテンプレートのファイルパスを指定します。
ファイルパスには省略ルールがあります。
例えば以下のときは app/views/xxx/yyy.html.erb が利用されるビューテンプレートとなります。
render 'xxx/yyy'
ただし、さらに省略できるルールがあります。
詳しいルールについては以下の記事を参照してください。
>> 【Rails】render メソッドの引数のルールを徹底解説!!【初心者向け】
ビューから呼び出す render (部分テンプレート, パーシャルテンプレート)
ビューで使用する render は、ビューの中で部分テンプレートを差し込むためのメソッドです。
基本形は以下の通りです。
<%= render '部分テンプレートのファイルパス', 変数名: 値, ・・・ %>
ファイルパスのルールはコントローラのrenderと同じですが、ファイル名の先頭にアンダースコア(_)をつけるというルールが追加されます。
例えば以下であれば app/views/xxx/_yyy.html.erb となります。
<%= render 'xxx/yyy' %>
第2引数は部分テンプレートに渡す値を変数名をつけて指定します。
例えば
<%= render 'xxx/yyy', x: 1, y: 2 %>
とした場合、app/views/xxx/_yyy.html.erb 側に変数 x, y で値を受け渡し、
<p><%= x %></p>
<p><%= y %></p>
のようなコードを書いた場合、実行すると以下のように変換されます。
<p>1</p>
<p>2</p>
HTML以外の形式で返す(JSON, XML, Plain text)
render メソッドでは HTML 以外の形式でもレスポンスとして返せます。
代表的な形式として以下の形式を紹介します。
JSON
JSON形式で返すためには render メソッドの引数に json オプションを指定し、以下の形式で記述します。
render json: オブジェクト
オブジェクトには Hash やモデルのインスタンスなど様々な値を指定できます。
例えば以下は詳細ページを表示する変わりに1件のモデルのインスタンスを JSON 形式で返しています。
class PostsController < ApplicationController
def show
@post = Post.find(params[:id])
render json: @post # ← 取得したモデルのインスタンスを指定
end
end
ブラウザでアクセスすると JSON 形式のレスポンスを確認できます。

XML
XML 形式で返すには render メソッドの引数に xml オプションを指定し、以下の形式で記述します。
render xml: オブジェクト
特に Hash を渡せば対応した XML の形式に整形して返してくれます。
例えば以下のように取得したモデルのインスタンスを attributes メソッドでHash に変換して xml: オプションに渡すことができます。
class PostsController < ApplicationController
def show
@post = Post.find(params[:id])
render xml: @post.attributes # ← 取得したモデルのインスタンスを Hash に変換(attributes)して指定
end
end
ブラウザでアクセスすると XML 形式のレスポンスを確認できます。

プレーンテキスト
HTML や JSON など構造化されたテキストではなく、普通のテキスト(プレーンテキスト)として返すこともできます。
プレーンテキストで返す場合は以下の形式で記述します。
render plain: 文字列
例えば以下のようにフォーマットしたテキストを plain: オプションに渡すとプレーンテキストで返します。
class PostsController < ApplicationController
def show
@post = Post.find(params[:id])
render plain: "ID: #{@post.id}\nタイトル: #{@post.title}" # ← 文字列にフォーマットした
end
end
ブラウザでアクセスすると以下のように表示されます。

ステータスコードを指定する
renderで作成されるHTTPレスポンスのステータスコードはデフォルトでは 200 (ok) です。
「失敗」を表したい場合は別のステータスコードを設定したい場合があります。
render では status: オプションでステータスコードを指定できます。
render 'xxx/yyy', status: 番号もしくはシンボル
例えば 400 (Bad Request) を指定するには以下のように記述します。
class PostsController < ApplicationController
def show
@post = Post.find(params[:id])
render :show, status: 400
end
end
ステータスコードは Google Chrome であればデベロッパーツールのネットワークタブで確認できます。

ステータスコード毎にシンボルが用意されています。
400の場合は :bad_request となり、以下のように記述できます。
class PostsController < ApplicationController
def show
@post = Post.find(params[:id])
render :show, status: :bad_request
end
end
各ステータスコードに対するシンボルは以下の通りです。
ステータスコード | シンボル |
100 | :continue |
101 | :switching_protocols |
102 | :processing |
200 | :ok |
201 | :created |
202 | :accepted |
203 | :non_authoritative_information |
204 | :no_content |
205 | :reset_content |
206 | :partial_content |
207 | :multi_status |
208 | :already_reported |
226 | :im_used |
300 | :multiple_choices |
301 | :moved_permanently |
302 | :found |
303 | :see_other |
304 | :not_modified |
305 | :use_proxy |
306 | :reserved |
307 | :temporary_redirect |
308 | :permanent_redirect |
400 | :bad_request |
401 | :unauthorized |
402 | :payment_required |
403 | :forbidden |
404 | :not_found |
405 | :method_not_allowed |
406 | :not_acceptable |
407 | :proxy_authentication_required |
408 | :request_timeout |
409 | :conflict |
410 | :gone |
411 | :length_required |
412 | :precondition_failed |
413 | :request_entity_too_large |
414 | :request_uri_too_long |
415 | :unsupported_media_type |
416 | :requested_range_not_satisfiable |
417 | :expectation_failed |
422 | :unprocessable_entity |
423 | :locked |
424 | :failed_dependency |
426 | :upgrade_required |
428 | :precondition_required |
429 | :too_many_requests |
431 | :request_header_fields_too_large |
500 | :internal_server_error |
501 | :not_implemented |
502 | :bad_gateway |
503 | :service_unavailable |
504 | :gateway_timeout |
505 | :http_version_not_supported |
506 | :variant_also_negotiates |
507 | :insufficient_storage |
508 | :loop_detected |
510 | :not_extended |
511 | :network_authentication_required |
redirect_to との違い
render と同時に登場するのが redirect_to です。
redirect_to メソッドもHTTPレスポンスを作るためのメソッドです。
redirect_to メソッドは 300 番台のレスポンスを作成します。
以下のような形式で記述します。
redirect_to リダイレクト先のURL
たとえば、指定した ID のレコードが存在しない場合に、一覧画面にリダイレクトするには以下のように記述します。
class PostsController < ApplicationController
def index
@posts = Post.all
end
def show
@post = Post.find_by(id: params[:id])
unless @post # 指定した ID のレコードがない場合
redirect_to posts_url # 一覧画面にリダイレクト
end
end
end
デベロッパーツールでステータスコードを確認すると 302 でリダイレクトされているのが確認できます。

レスポンスヘッダの Location: でリダイレクト先のURLを確認できます。
リダイレクトの仕組みについては以下も参考にしてください。
≫ redirect_to によるリダイレクトの方法を徹底解説【Ruby on Rails】
よくあるエラー: AbstractController::DoubleRenderError
render メソッド関連でよく発生するエラーは AbstractController::DoubleRenderError です。
一回のリクエストに対して複数回 render メソッドや redirect_to メソッドが呼び出されると発生します。
例えばよくあるパターンとしては以下のように条件分岐で異常系で特別に用意した画面を表示したい場合です。
class PostsController < ApplicationController
def show
@post = Post.find_by(id: params[:id])
unless @post # 見つからなかった時は
render 'errors/not_found' # エラー画面を表示する
end
render @post
end
end
上記プログラムでは @post が nil のとき(= Post.find_by(id: params[:id]) で見つからなかったとき) に以下のようなエラーとなります。

@post が nil のとき、unless の中が実行対象となり、
render 'errors/not_found'
が呼ばれます。
そして、retern などをしていないのでそこでは終わらず、
render @post
も実行しています。
このため DoubleRenderError です。
これを避けるにはどのような場合でも呼び出される render メソッドは一回だけにする必用があります。
例えば以下の様に if-else でどちらかだけを実行するようにしたり・・・
class PostsController < ApplicationController
def show
@post = Post.find_by(id: params[:id])
if @post
render @post
else
render 'errors/not_found'
end
end
end
他にも、render の時点で return すれば片方だけが実行されます。
class PostsController < ApplicationController
def show
@post = Post.find_by(id: params[:id])
unless @post
return render 'errors/not_found' # render メソッドを呼びつつ return する
end
render @post
end
end
before_action でアクションを停止する
render の効果で見過ごされがちなのが before_action で実行すると後続の処理を止めるということです。
例えば以下のように before_action で「対象のデータが見つからないときにエラー画面を表示する」ということをやってみましょう。
class PostsController < ApplicationController
before_action :set_post
def show
render @post
end
private
def set_post
@post = Post.find_by(id: params[:id])
unless @post
render 'errors/not_found' # ここが実行されると render @post は実行されない
end
end
end
この場合は show メソッドが実行される前に set_post メソッドが実行されますが、@post が nil の場合、render ‘errors/not_found’ が実行されます。
render メソッドが before_action である set_post 内で実行された場合は show メソッド自体が実行されません。
このように、before_action 内で render メソッドを呼び出せば後続の処理を止められます。
before_action で render メソッドを呼び出して後続処理を止めるのは、show メソッド本体をシンプルにするためです。
before_action 側でエラー処理を実施することで、show メソッド本体から複雑な処理を省略できます。
まとめ
Rails の render メソッドについて解説しました。
render メソッドは HTTP レスポンスを作るための大切なメソッドですが初心者のうちはなんとなく使いがちです。
なんとなくで通用するのは最初のうちだけです。
この機会にしっかりと理解して Rails プログラムを自信をもって書けるようにしましょう!