Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I render a partial of a different format in Rails?

People also ask

What is use of partials in Rails?

A partial allows you to separate layout code out into a file which will be reused throughout the layout and/or multiple other layouts. For example, you might have a login form that you want to display on 10 different pages on your site.

What is render partial in Ruby on Rails?

Ruby on Rails Views Partials Partial templates (partials) are a way of breaking the rendering process into more manageable chunks. Partials allow you to extract pieces of code from your templates to separate files and also reuse them throughout your templates.

How can you tell Rails to render without a layout *?

By default, if you use the :text option, the text is rendered without using the current layout. If you want Rails to put the text into the current layout, you need to add the layout: true option.


Beginning with Rails 3.2.3, when calling render :partial (only works outside of the respond_to block).

render formats: [ :html ]

instead of

render format: 'html'

What's wrong with

render :partial => '/foo/baz.html.erb'

? I just tried this to render an HTML ERB partial from inside an Atom builder template and it worked fine. No messing around with global variables required (yeah, I know they have "@" in front of them, but that's what they are).

Your with_format &block approach is cool though, and has the advantage that you only specify the format, whereas the simple approach specifies the template engine (ERB/builder/etc) as well.


Rails 4 will allow you to pass a formats parameter. So you can do

render(:partial => 'form', :formats => [:html])} 

Note you can do something similar in Rails 3 but it wouldn't pass that format to any sub partials (if form calls other partials).

You can have the Rails 4 ability in Rails 3 by creating config/initializers/renderer.rb:

class ActionView::PartialRenderer
  private
  def setup_with_formats(context, options, block)
    formats = Array(options[:formats])
    @lookup_context.formats = formats | @lookup_context.formats
    setup_without_formats(context, options, block)
  end

  alias_method_chain :setup, :formats
end

See http://railsguides.net/2012/08/29/rails3-does-not-render-partial-for-specific-format/


For Rails 3, the with_format block works, but it's a little different:

  def with_format(format, &block)
    old_formats = formats
    self.formats = [format]
    block.call
    self.formats = old_formats
    nil
  end

Building on roninek's response, I've found the best solution to be the following:

in /app/helpers/application.rb:

def with_format(format, &block)
  old_format = @template_format
  @template_format = format
  result = block.call
  @template_format = old_format
  return result
end

In /app/views/foo/bar.json:

<% with_format('html') do %>
  <%= h render(:partial => '/foo/baz') %>
<% end %>

An alternate solution would be to redefine render to accept a :format parameter.

I couldn't get render :file to work with locals and without some path wonkiness.