2008-12-03 239 views
109

我正在尝试生成包含一些HTML的JSON响应。因此,我有/app/views/foo/bar.json.erb如何在Rails中呈现不同格式的部分内容?

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

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

+0

问题标题比詹姆斯的特殊问题更一般。如果你正在寻找其他解决方案,请看看这里:http://stackoverflow.com/questions/7616097/how-to-render-new-js-coffee-erb-in-app-views – miguelsan 2013-08-08 13:14:47

回答

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与当地人合作,没有一些道路好奇。

+8

对我的口味太冒昧了。最好指定整个扩展名。 – 2010-05-07 17:50:18

+1

对于导轨3请参阅zgchurch的答案。 – lillq 2010-12-02 01:38:58

9

有两个选项:

1)使用渲染:文件=> “富/ _baz.json.erb”

2)变化的模板格式通过设置@template_format可变

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

<%@template_format = “html”%>为我工作,因为我的部分加载其他部分我没有更新其他渲染链。 – pagetribe 2011-03-14 00:44:06

63

这有什么错

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

?我只是试图从Atom构建器模板中渲染HTML ERB partial,并且它工作正常。不需要搞乱全局变量(是的,我知道他们在前面有“@”,但这就是他们)。

您的with_format &block approach虽然很酷,但其优点是只指定格式,而简单的方法也指定模板引擎(ERB/builder/etc)。

+0

这真的是最直接的方法,并为我无缝工作。 – 2009-06-23 23:04:56

+26

唯一的缺点是,如果你的局部渲染其他局部区域,它将失败,除非你进入并更改所有渲染局部调用以在其名称中包含“.html.erb”。 – chrisrbailey 2009-07-25 02:40:31

+0

肯定是+1,但是必须指定模板引擎,加上chrisbailey提出的关于嵌套partials的担忧,这让我很担心。 – 2010-01-13 22:29:07

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 

,是的......完整的文件名在这里工作,以及...

32

对于Rails 3中,在with_format块的工作,但它是一个有点不同:

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

就阐述什么zgchurch写道:

  • 考虑例外考虑
  • 返回被叫块的结果

认为它可能有用。

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

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

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

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

缺陷是您必须将该行添加到多个模板。如果有人从application_controller.rb知道一种设置方法,我很想知道它。不幸的是,将该行添加到您的移动版式是行不通的,因为模板是在版面之前呈现的。

91

使用Rails 3.2.3开始,调用渲染时:局部使用

:formats => [:html] 

,而不是

:format => 'html' 
2

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

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

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

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

注意,你可以做的Rails 3类似的东西,但它不会通过此格式的任何子谐音(如果表单调用其他的谐音)。

你可以通过创建配置/初始化/ renderer.rb在Rails 3的钢轨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

我有一个名为 'API/item.rabl' 和我想从一个HTML视图渲染它,所以我不得不使用:

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

file因为文件没有下划线的名字,formats而不是format(及通行证和阵列))