如何在Rails中呈现不同格式的部分?

时间:2008-12-03 23:26:31

标签: ruby-on-rails format render partial actionview

我正在尝试生成包含一些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'无济于事。

11 个答案:

答案 0 :(得分:98)

从Rails 3.2.3开始,在调用render:partial use

:formats => [:html]

而不是

:format => 'html'

答案 1 :(得分:64)

有什么问题
render :partial => '/foo/baz.html.erb'

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

你的with_format &block approach虽然很酷,但它的优势在于你只指定了格式,而简单方法也指定了模板引擎(ERB / builder / etc)。

答案 2 :(得分:32)

对于Rails 3,with_format块可以工作,但它有点不同:

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

答案 3 :(得分:29)

roninek's response的基础上,我找到了最佳解决方案:

在/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与当地人合作并且没有一些道路困难。

答案 4 :(得分:29)

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/

答案 5 :(得分:25)

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

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

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

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

答案 6 :(得分:16)

刚刚详细介绍了zgchurch所写的内容:

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

认为它可能有用。

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

答案 7 :(得分:9)

您有两种选择:

1)使用render :file

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

2)通过设置@template_format变量

将模板格式更改为html
<% @template_format = "html" %>
<%= h render(:partial => '/foo/baz') %>

答案 8 :(得分:5)

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

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

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

答案 9 :(得分:2)

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

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

答案 10 :(得分: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

是的......完整的文件名也适用于此...