method

render

Importance_5
v2.3.8 - Show latest stable - 16 notes - Class: ActionController::Base
render(options = nil, extra_options = {}, &block) protected

Renders the content that will be returned to the browser as the response body.

Rendering an action

Action rendering is the most common form and the type used automatically by Action Controller when nothing else is specified. By default, actions are rendered within the current layout (if one exists).

 # Renders the template for the action "goal" within the current controller render :action => "goal" # Renders the template for the action "short_goal" within the current controller, # but without the current active layout render :action => "short_goal", :layout => false # Renders the template for the action "long_goal" within the current controller, # but with a custom layout render :action => "long_goal", :layout => "spectacular" 

Rendering partials

Partial rendering in a controller is most commonly used together with Ajax calls that only update one or a few elements on a page without reloading. Rendering of partials from the controller makes it possible to use the same partial template in both the full-page rendering (by calling it from within the template) and when sub-page updates happen (from the controller action responding to Ajax calls). By default, the current layout is not used.

 # Renders the same partial with a local variable. render :partial => "person", :locals => { :name => "david" } # Renders the partial, making @new_person available through # the local variable 'person' render :partial => "person", :object => @new_person # Renders a collection of the same partial by making each element # of @winners available through the local variable "person" as it # builds the complete response. render :partial => "person", :collection => @winners # Renders a collection of partials but with a custom local variable name render :partial => "admin_person", :collection => @winners, :as => :person # Renders the same collection of partials, but also renders the # person_divider partial between each person partial. render :partial => "person", :collection => @winners, :spacer_template => "person_divider" # Renders a collection of partials located in a view subfolder # outside of our current controller. In this example we will be # rendering app/views/shared/_note.r(html|xml) Inside the partial # each element of @new_notes is available as the local var "note". render :partial => "shared/note", :collection => @new_notes # Renders the partial with a status code of 500 (internal error). render :partial => "broken", :status => 500 

Note that the partial filename must also be a valid Ruby variable name, so e.g. 2005 and register-user are invalid.

Automatic etagging

Rendering will automatically insert the etag header on 200 OK responses. The etag is calculated using MD5 of the response body. If a request comes in that has a matching etag, the response will be changed to a 304 Not Modified and the response body will be set to an empty string. No etag header will be inserted if it’s already set.

Rendering a template

Template rendering works just like action rendering except that it takes a path relative to the template root. The current layout is automatically applied.

 # Renders the template located in [TEMPLATE_ROOT]/weblog/show.r(html|xml) (in Rails, app/views/weblog/show.erb) render :template => "weblog/show" # Renders the template with a local variable render :template => "weblog/show", :locals => {:customer => Customer.new} 

Rendering a file

File rendering works just like action rendering except that it takes a filesystem path. By default, the path is assumed to be absolute, and the current layout is not applied.

 # Renders the template located at the absolute filesystem path render :file => "/path/to/some/template.erb" render :file => "c:/path/to/some/template.erb" # Renders a template within the current layout, and with a 404 status code render :file => "/path/to/some/template.erb", :layout => true, :status => 404 render :file => "c:/path/to/some/template.erb", :layout => true, :status => 404 

Rendering text

Rendering of text is usually used for tests or for rendering prepared content, such as a cache. By default, text rendering is not done within the active layout.

 # Renders the clear text "hello world" with status code 200 render :text => "hello world!" # Renders the clear text "Explosion!" with status code 500 render :text => "Explosion!", :status => 500 # Renders the clear text "Hi there!" within the current active layout (if one exists) render :text => "Hi there!", :layout => true # Renders the clear text "Hi there!" within the layout # placed in "app/views/layouts/special.r(html|xml)" render :text => "Hi there!", :layout => "special" 

Streaming data and/or controlling the page generation

The :text option can also accept a Proc object, which can be used to:

  1. stream on-the-fly generated data to the browser. Note that you should use the methods provided by ActionController::Steaming instead if you want to stream a buffer or a file.
  2. manually control the page generation. This should generally be avoided, as it violates the separation between code and content, and because almost everything that can be done with this method can also be done more cleanly using one of the other rendering methods, most notably templates.

Two arguments are passed to the proc, a response object and an output object. The response object is equivalent to the return value of the ActionController::Base#response method, and can be used to control various things in the HTTP response, such as setting the Content-Type header. The output object is an writable IO-like object, so one can call write and flush on it.

The following example demonstrates how one can stream a large amount of on-the-fly generated data to the browser:

 # Streams about 180 MB of generated data to the browser. render :text => proc { |response, output| 10_000_000.times do |i| output.write("This is line #{i}\n") end } 

Another example:

 # Renders "Hello from code!" render :text => proc { |response, output| output.write("Hello from code!") } 

Rendering XML

Rendering XML sets the content type to application/xml.

 # Renders '<name>David</name>' render :xml => {:name => "David"}.to_xml 

It’s not necessary to call to_xml on the object you want to render, since render will automatically do that for you:

 # Also renders '<name>David</name>' render :xml => {:name => "David"} 

Rendering JSON

Rendering JSON sets the content type to application/json and optionally wraps the JSON in a callback. It is expected that the response will be parsed (or eval’d) for use as a data structure.

 # Renders '{"name": "David"}' render :json => {:name => "David"}.to_json 

It’s not necessary to call to_json on the object you want to render, since render will automatically do that for you:

 # Also renders '{"name": "David"}' render :json => {:name => "David"} 

Sometimes the result isn’t handled directly by a script (such as when the request comes from a SCRIPT tag), so the :callback option is provided for these cases.

 # Renders 'show({"name": "David"})' render :json => {:name => "David"}.to_json, :callback => 'show' 

Rendering an inline template

Rendering of an inline template works as a cross between text and action rendering where the source for the template is supplied inline, like text, but its interpreted with ERb or Builder, like action. By default, ERb is used for rendering and the current layout is not used.

 # Renders "hello, hello, hello, again" render :inline => "<%= 'hello, ' * 3 + 'again' %>" # Renders "<p>Good seeing you!</p>" using Builder render :inline => "xml.p { 'Good seeing you!' }", :type => :builder # Renders "hello david" render :inline => "<%= 'hello ' + name %>", :locals => { :name => "david" } 

Rendering inline JavaScriptGenerator page updates

In addition to rendering JavaScriptGenerator page updates with Ajax in RJS templates (see ActionView::Base for details), you can also pass the :update parameter to render, along with a block, to render page updates inline.

 render :update do |page| page.replace_html 'user_list', :partial => 'user', :collection => @users page.visual_effect :highlight, 'user_list' end 

Rendering vanilla JavaScript

In addition to using RJS with render :update, you can also just render vanilla JavaScript with :js.

 # Renders "alert('hello')" and sets the mime type to text/javascript render :js => "alert('hello')" 

Rendering with status and location headers

All renders take the :status and :location options and turn them into headers. They can even be used together:

 render :xml => post.to_xml, :status => :created, :location => post_url(post) 
Show source
Register or log in to add new notes.
October 15, 2008
29 thanks

List of status codes and their symbols

Note that the :status option accepts not only an HTTP status code (such as 500), but also a symbol representing that code (such as :created), if that makes more sense to you. Here’s a list of which symbols map to which numbers (derived from ActionController::StatusCodes::SYMBOL_TO_STATUS_CODE):

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 226 = :im_used 300 = :multiple_choices 301 = :moved_permanently 302 = :found 303 = :see_other 304 = :not_modified 305 = :use_proxy 307 = :temporary_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 500 = :internal_server_error 501 = :not_implemented 502 = :bad_gateway 503 = :service_unavailable 504 = :gateway_timeout 505 = :http_version_not_supported 507 = :insufficient_storage 510 = :not_extended
July 5, 2008
23 thanks

Using counters with collections

When you’re rendering a collection partial, the partial_name_counter variable contains the position of the current element in the collection. For example:

<%= render(:partial => 'example', :collection => %w(rails-doc is cool)) %> 

Now in _example.html.erb:

<p>Element: <%= example %> (index: <%= example_counter %>)</p> 

It would produce:

<p>Element: rails-doc (index: 1)</p> <p>Element: is (index: 2)</p> <p>Element: cool (index: 3)</p> 

As you can see, indexing starts from 1.

October 9, 2008 - (<= v2.1.0)
12 thanks

Rendering nothing

If your controller action does not explicitly call render, Rails will, by default, attempt to locate and render the template corresponding to the action. It’s not uncommon, for example with Ajax calls, to want to render nothing. This will circumvent the default rendering and prevent errors on missing templates. To render nothing simply do the following:

render :nothing => true

Its important to note that this isn’t the same as returning no HTTP response. In fact, this results in an HTTP response with a status code of 200 OK being sent back with a blank content body. Why does it matter? Well, you can still test your controller by asserting that a :success response was returned.

September 5, 2008
6 thanks

Custom collection local variable name

Regarding the previous note from hoodow about using :variable_name to create a custom local variable name when rendering a collection with a partial, the argument should be :as instead of :variable_name, so:

render :partial => “video_listing”, :collection => @recommendations, :as => :video

October 7, 2009
3 thanks

Streaming XML with Builder

To generate larger XMLs, it’s a good idea to a) stream the XML and b) use Active Record batch finders.

Here’s one way of doing it:

def my_action @items = Enumerable::Enumerator.new( Item.some_named_scope, :find_each, :batch_size => 500) respond_to do |format| format.xml do render :text => lambda { |response, output| extend ApplicationHelper xml = Builder::XmlMarkup.new( :target => StreamingOutputWrapper.new(output), :indent => 2) eval(default_template.source, binding, default_template.path) } end end end 

The Builder template does not need to be modified.

July 24, 2008
3 thanks

render_collection

You can wrap render in helpers. For example, render_collection. In app/helpers/application.rb:

module ApplicationHelper def render_collection(name, collection) render :partial => "shared/#{name}", :collection => collection end end 

In views:

<h2>Comments</h2> <%= render_collection :comments, @photo.comments %> 
June 22, 2009
3 thanks

Optional local assigns

When you have a partial with optional local assigns, for instance:

<%= render :partial => 'articles/preview' %> <%= render :partial => 'articles/preview', :locals => { :show_call_out => true } %> 

And you don’t want the partial to break when the local isn’t assigned, you can reference it through the local_assigns local variable instead of through the template binding:

<% if local_assigns[:show_call_out] %> <em><%= format @article.call_out %></em> <% end %>
August 27, 2008
2 thanks

:variable_name

In Edge Rails you can do something like this to change the local variable name when rendering a collection:

render :partial => “video_listing”, :collection => @recommendations, :variable_name => “video”

November 5, 2008
2 thanks

Rendering YAML

When you want to render XML or YAML you can use

render :xml, some_object.to_xml 

or

render :json, some_object.to_json 

However there is no equivalent for YAML. What you can do is render just plain text with a correct content-type:

render :text => some_object.to_yaml, :content_type => 'text/yaml' 

The content_type is debatable but this seems to be the most standard.

August 6, 2008 - (v2.1.0)
1 thank

RE: Using counters with collections

Note that as of Rails 2.1, it’s currently not possible to override the internal counter variable you get when using collections via passing it in through :locals.

This is a useful feature when you have a collection of items rendered but then wish to add another one - most likely via an AJAX request.

I’ve been informed it’s back in Edge, so hopefully it’ll re-appear again in Rails 2.2.

June 3, 2015 - (v4.0.2 - v4.2.1)
0 thanks

render with variables

perient view

Code example

<%= render 'time_select', locals: { select_name: 'from_tiem'}%> 

render view

Code example

<%= locals[:select_name] %> 

not:

Code example

<%= local_assigns[:select_name] %>  
February 19, 2014
0 thanks

Rendering JSONP

If you provide the :callback option with a nil value, then the default JSON object will be returned. As such, this makes creating JSONP response from the render syntax very easy in your controllers, like so:

render json: @object, callback: params[:jsoncallback]
November 26, 2009
0 thanks

Streaming Does Not Work with Mongrel

If you are trying to stream output via render :text => Proc and Mongrel, be sure to note that this does NOT work. Mongrel returns a StringIO, which by nature buffers everything.

Unsure of how to actually stream output with Rails in a consistent fashion.

August 5, 2014
0 thanks

Using render to handle ajax call using same js.erb(DRY)

Suppose your application have many pages using some common view and is updated using ajax,so you can use a single js in multiple views to avoid duplication

format.js { render 'profile/show_user_details' } 

And in my profiles/show_user_details.js i can use conditions instead of creating regular partials

<% if params[:controller]== "dashboard"%> $("admin_panel").show(); $("user_panel").hide(); <% elsif params[:controller]== "user"%> $("admin_panel").hide(); $("user_panel").show(); <% elsif params[:controller]== "video"%> $("admin_panel").hide(); $("user_panel").hide(); $("video_panel").show(); <% else %> $("admin_panel").hide(); $("user_panel").hide(); $("video_panel").hide(); <%end%> 
April 25, 2010
0 thanks

Avoid DoubleRenderError

One can not invoke render twice during an action. Thus if You have a complicated rendering logic but at the end would like to render some default content, or just would like to find out whether render has been called during the current action, use performed?. This also works with “empty” renderings such as head.

December 8, 2010
0 thanks

typo

ActionController::Steaming => ActionController::Streaming