120

我正在尝试生成包含一些 HTML 的 JSON 响应。因此,我有/app/views/foo/bar.json.erb

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

我希望它渲染/app/views/foo/_baz.html.erb,但它只会渲染/app/views/foo/_baz.json.erb。传球没用:format => 'html'

4

11 回答 11

105

从 Rails 3.2.3 开始,调用 render :partial 时(仅在respond_to块外工作)。

render formats: [ :html ]

代替

render format: 'html'
于 2012-02-19T05:27:23.753 回答
64

有什么问题

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

? 我只是尝试从 Atom 构建器模板中渲染 HTML ERB 部分,它工作正常。不需要弄乱全局变量(是的,我知道它们前面有“@”,但它们就是这样)。

不过,您的with_format &block方法很酷,并且具有您只指定格式的优点,而简单的方法也指定了模板引擎(ERB/builder/etc)。

于 2008-12-04T13:03:01.093 回答
34

Rails 4 将允许您传递格式参数。所以你可以做

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

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

您可以通过创建 config/initializers/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/

于 2013-05-15T18:50:19.530 回答
32

对于 Rails 3, with_format 块有效,但有点不同:

  def with_format(format, &block)
    old_formats = formats
    self.formats = [format]
    block.call
    self.formats = old_formats
    nil
  end
于 2010-08-06T20:40:26.680 回答
30

基于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与当地人一起工作,也没有一些道路迷茫。

于 2008-12-04T12:28:24.237 回答
25

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

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

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

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

于 2011-05-30T23:17:55.417 回答
16

只是详细说明 zgchurch 写的内容:

  • 考虑到例外情况
  • 返回被调用块的结果

认为它可能有用。

def with_format(format, &block)
  old_formats = formats
  begin
    self.formats = [format]
    return block.call
  ensure
    self.formats = old_formats
  end
end
于 2011-02-22T04:49:00.847 回答
10

你有两个选择:

1) 使用render :file

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

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

<% @template_format = "html" %>
<%= h render(:partial => '/foo/baz') %>
于 2008-12-04T11:54:01.920 回答
6

我有一个名为“api/item.rabl”的文件,我想从 HTML 视图中渲染它,所以我不得不使用:

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

file因为该文件的名称中没有下划线,formats而不是format(和传递和数组))

于 2013-10-18T18:57:29.180 回答
2

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

{
  someKey: 'some value',
  someHTML: "<%= h render('baz', formats: :html) -%>"
}
于 2012-05-22T07:56:06.860 回答
1

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

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

是的...完整的文件名也可以在这里使用...

于 2010-06-23T09:42:39.793 回答