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

我试图生成一个包含一些 HTML 的 JSON 响应:

{
someKey: 'some value',
someHTML: "<%= h render(:partial => '/foo/baz') -%>"
}

我希望它呈现 /app/views/foo/_baz.html.erb,但它只会呈现 /app/views/foo/_baz.json.erb。通过 :format => 'html'没有帮助。

80307 次浏览

You have two options:

1)使用 render :file

render :file => "foo/_baz.json.erb"

2)通过设置@template _ format 变量将模板格式更改为 html

<% @template_format = "html" %>
<%= h render(:partial => '/foo/baz') %>

Roninek 的回答的基础上,我找到了以下最佳解决方案:

在/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

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

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

另一种解决方案是重新定义 render以接受 :format参数。

我不能让 render :file和当地人一起工作,如果没有一些道路摇摆不定。

怎么了

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

?我只是尝试从 Atom 构建器模板中呈现 HTML ERB 部分,它工作得很好。不要在需要的全局变量上浪费时间(是的,我知道它们前面有“@”,但它们就是全局变量)。

但是 with_format &block进场很酷,它的优点是只指定格式,而简单的方法也指定模板引擎(ERB/build/etc)。

当我试图在另一个 XML.Builder 视图文件中呈现 XML 部分时,遇到了这个线程。 以下是一个不错的方法

xml.items :type => "array" do
@items.each do |item|
xml << render(:partial => 'shared/partial.xml.builder', :locals => { :item => item })
end
end

And yeah... Full file name works here as well...

对于 Rails 3,with _ format 块可以工作,但是有一点不同:

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

只是在详细阐述 zgchurch 写的东西:

  • taking exceptions into account
  • 返回被调用块的结果

觉得可能有用。

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

在 Rails 3中,View 有一个 format 数组,这意味着您可以将其设置为查找[ : mobile,: html ]。设置将默认查找: mobile 模板,但回退到: html 模板。这个设置的效果会级联到内部的部分。

我能找到的最好但仍有缺陷的设置方法是将这一行放在每个完整移动模板的顶部(但不是部分)。

<% self.formats = [:mobile, :html] %>

缺陷是您必须将该行添加到多个模板中。如果有人知道一种方法来设置这一次,从 application _ controller。我很想知道。不幸的是,将这一行添加到移动布局中并不起作用,因为模板是在布局之前呈现的。

从 Rails 3.2.3开始,调用 render: part (只能在 respond_to块之外工作)。

render formats: [ :html ]

而不是

render format: 'html'

似乎传递一个 formats选项将会在新的 Rails 版本中正确地呈现它,至少3.2:

{
someKey: 'some value',
someHTML: "<%= h render('baz', formats: :html) -%>"
}

Rails 4将允许您传递一个 format 参数

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

注意,您可以在 Rails 3中执行类似的操作,但是它不会将该格式传递给任何子分支(如果 form 调用其他分支)。

通过创建 config/initializer/renderer.rb,您可以在 Rails 3中拥有 Rails 4功能:

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

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

我有一个名为‘ api/item.rabl’的文件,我想从 HTML 视图中呈现它,所以我必须使用:

render file: 'api/item', formats: [:json]

(file because the file have no underscore in the name, formats and not format (and passes and array))