読者です 読者をやめる 読者になる 読者になる

Rails Webook

自社のECを開発している会社で働いています。Rails情報やサービスを成長させる方法を書いていきます

よく忘れるRailsのコントローラーでのrenderメソッドのレシピ集

Rails初級 Rails Controller

Railsのコントローラーでのrenderメソッドの使い方について説明します。
renderメソッドは、「コントローラー(Controller)」と「ビュー(View)」のそれぞれにあります。
ここではコントローラーのrenderメソッドの使い方を示します。
ビューでのrenderメソッドの使い方は こちらを参照してください。

動作確認

目次


1. ビューを表示する

1.1. 暗黙的なビューの表示する

Railsはコントローラ名とメソッド名からrenderメソッドを記載しなくても自動的にレンダリングするビューを特定します。
ルールは「app/views/コントローラ名/メソッド名.html.erb」を呼び出します。

# app/controllers/products_controller.rb

# GET /products
# 暗黙的に「app/views/products/index.html.erb」を呼び出す
def index  # indexはアクション名
  @products = Product.all
end


1.2. 他のアクションのビューを表示する(actionオプション)

actionオプションを指定することにより、 同じコントローラー内のビューファイルを明示的に指定することができます。

# app/controllers/products_controller.rb

# GET /products
# renderメソッドは、「app/views/products/new.html.erb」を呼び出す
def index
  @products = Product.all
  render action: :new  # 引数は :new のようなシンボルでも、'new' のような文字列でも良い
end

layoutオプションを指定することで、レイアウトファイルを指定することができます。

# special_layoutというレイアウトを使用して、new.html.erbテンプレートを表示する
render action: :new, layout: :special_layout

# レイアウトを表示しないで、new.html.erbテンプレートのみを表示する
render action: :new, layout: false

# レイアウトを指定しない場合は、コントローラーのデフォルトのレイアウトが使われて、
# new.html.erbテンプレートを表示する
render action: :new


1.3. 他のコントローラーのビューを表示する(templateオプション)

他のコントローラーのビューファイルを呼び出すためには、templateオプションを利用します。

# app/views/welcome/index.html.erb を表示する
render template: "welcome/index"

2. JSONを返す

2.1. renderメソッド

renderメソッドjsonオプションを追加するとJSONとしてレスポンスを返します。
指定したオブジェクトにto_jsonメソッドがあれば、自動的にJSON形式に変換して返します。

def index
  @products = Product.all
  render json: @products
end

JSON形式として次のように返されます。

[
  {"id":1,"name":"ジュース","description":"おいしいジュース","price":100,"created_at":"2014-11-23T07:12:19.942Z","updated_at":"2014-11-23T07:12:19.942Z"},
  {"id":2,"name":"ハンバーガー","description":"普通のハンバーガー","price":120,"created_at":"2014-11-23T07:12:31.892Z","updated_at":"2014-11-23T07:12:31.892Z"}
]


2.2. jbuilder

また、Rails4.1にはjbuilderというgemがデフォルトで入っており、テンプレートファイルでJSONを生成することができます。

# app/views/products/index.json.jbuilder

json.array!(@products) do |product|
  json.extract! product, :id, :name, :description, :price
  json.url product_url(product, format: :json)
end

localhost:3000/products.jsonにアクセすると次のように結果が表示されます。

[
  {"id":1,"name":"ジュース","description":"おいしいジュース","price":100,"url":"http://localhost:3000/products/1.json"},
  {"id":2,"name":"ハンバーガー","description":"普通のハンバーガー","price":120,"url":"http://localhost:3000/products/2.json"}
]

2.3. ActiveModelSerializer

active_model_serializerというgemによりモデルのように定義することでJSONを返すこともできます。



3. ビュー以外を表示する

3.1. 文字列を表示する(textオプション)

renderメソッドtextオプションを指定することで、テンプレートではなく、文字列を直接表示することが可能です。

render text: "Hello, world!"

f:id:nipe880324:20141123165933p:plain:w240


デフォルトではレイアウトは適用されていません。レイアウトを適用するには、layout: trueを指定します。

render text: "Hello, world!", layout: true


3.2. XMLを返す(xmlオプション)

renderメソッドxmlオプションを指定することで、テンプレートではなく、XMLを返すことが可能です。
XMLの表示には、to_xmlメソッドが用いられます。また、Content-Typeはapplication/xml; charset=utf-8です。

def index
  @products = Product.all
  render xml: @products  # @products.to_xml の結果が返される
end

次にようにXMLが返されます。
f:id:nipe880324:20141123165935p:plain:w480




4. ステータスコードのみを返す

APIとして動作するアクションなどでは、レスポンスの本文は省略し、ステータスコードのみで成功/失敗を伝えれば良い時があります。
そういう場合は、headメソッドを使います。

head 200   # 200を返す
head :ok   # 200を返す

第2引数にパラメーターを指定すると、HTTPヘッダの内容を指定できます。

# createdは201コード。locationヘッダも指定しリソースが作られたことを伝えるために使われる
head :created, location: product_path(@person)

例外を除去するために、次のようにすることも可能です。

return head(:method_not_allowed) unless request.post?
return head(:bad_request) unless valid_request?
render

ステータスコードについては、「良く使うステータスコード一覧」を参照してください。




5. リクエストの種類に応じて、レスポンスのフォーマットを変更する

resopnd_toを使うことで、JSON形式やXMLなどの形式でデータを返すことができます。

# app/controllers/products_controller.rb

# 下記のリクエストに応じて、それぞれの形式でレスポンスを返す
# GET /products/1
# GET /products/1.json
# GET /products/1.xml
# GET /products/1.yaml
def show
  @product = Product.find(params[:id)

  respond_to do |format|
    format.html # show.html.erb
    format.json { render json: @product } # JSON形式
    format.xml  { render xml:  @product } # XML形式
    format.yaml { render text: @product.to_yaml } # YAML形式
  end
end


6. テンプレートを文字列として取得する(デバッグなどで使える)

テンプレートの処理結果を画面に表示せず、文字列として取得したい場合は、render_to_stringメソッドを使います。

# index.html
html_str = render_to_string action: :index
p html_str
# => "<!DOCTYPE html>\n<html>\n<head>\n  ...


7. よく使うステータスコード

Codeシンボル説明
200:okレスポンスが正常に終了した
201:createdcreateなどのアクションの結果などでリソースが正常に作成された。作成されたリソースに対するlocationヘッダも指定する
302:found他のURLへのリダイレクトを示す。redirect_toメソッドが内部的に使っていて明示的に使うことは少ない
400:bad_requestリクエストチェックをした結果、不正だった
401:unauthorized認証に失敗した
403:forbiddenアクセスが禁止されている
404:not_found対象のURLやリソースが存在しない
406:not_acceptable指定されたフォーマットでレスポンスを返せない。respond_toの指定ミスなどで起こる
422:unprocessable_entityバリデーションエラーなど
500:internal_server_errorサーバー側が現認のシステムエラーが発生した
503:service_unavailableメンテナンスや高負荷など


以上です。
なにかありましたら、コメントいただけると嬉しいです。

参考文献

  • Rails3 レシピブック 190の技