2008-12-03 252 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(及通行證和陣列))