不幸的是沒有一個直接的解決方案。在查看ActionPack將初始化Builder對象的代碼時,縮進大小將被硬編碼爲2,而邊距大小未設置。令人遺憾的是,目前沒有任何機制可以覆蓋這一點。
這裏的理想解決方案是修復ActionPack以允許將這些選項傳遞給構建器,但這需要一些時間投入。我有2個可能的修復程序給你。既髒你可以選擇你覺得不太髒。
將部分呈現渲染修改爲字符串,然後對其執行一些正則表達式。這應該是這樣的
_bar.xml.builder
xml.bar do
xml.id(bar.id)
xml.name(bar.name)
xml.created_at(bar.created_at)
xml.last_updated(bar.updated_at)
end
FOOS/index.xml.builder
xml.foos do
@foos.each do |foo|
xml.foo do
xml.id(foo.id)
xml.name(foo.name)
xml.created_at(foo.created_at)
xml.last_updated(foo.updated_at)
xml.bars do
foo.bars.each do |bar|
xml << render(:partial => 'bars/bar',
:locals => { :bar => bar }).gsub(/^/, ' ')
end
end
end
end
end
注意GSUB在渲染行的末尾。這將產生以下結果
<?xml version="1.0" encoding="UTF-8"?>
<foos>
<foo>
<id>1</id>
<name>Foo 1</name>
<created_at>2010-06-11 21:54:16 UTC</created_at>
<last_updated>2010-06-11 21:54:16 UTC</last_updated>
<bars>
<bar>
<id>1</id>
<name>Foo 1 Bar 1</name>
<created_at>2010-06-11 21:57:29 UTC</created_at>
<last_updated>2010-06-11 21:57:29 UTC</last_updated>
</bar>
</bars>
</foo>
</foos>
這是一個有點哈克,肯定很骯髒,但有被包含在您的代碼中的優勢。接下來的解決辦法是猴子補丁ActionPack的得到Builder實例的工作,我們所希望的方式
配置/初始化/ builder_mods.rb
module ActionView
module TemplateHandlers
class BuilderOptions
cattr_accessor :margin, :indent
end
end
end
module ActionView
module TemplateHandlers
class Builder < TemplateHandler
def compile(template)
"_set_controller_content_type(Mime::XML);" +
"xml = ::Builder::XmlMarkup.new(" +
":indent => #{ActionView::TemplateHandlers::BuilderOptions.indent}, " +
":margin => #{ActionView::TemplateHandlers::BuilderOptions.margin});" +
"self.output_buffer = xml.target!;" +
template.source +
";xml.target!;"
end
end
end
end
ActionView::TemplateHandlers::BuilderOptions.margin = 0
ActionView::TemplateHandlers::BuilderOptions.indent = 2
這造成在Rails的初始化稱爲BuilderOptions一個新的類其唯一目的是爲縮進和保證金提供2個值(儘管我們只需要保證金值)。我曾嘗試將這些變量作爲類變量直接添加到Builder模板類中,但該對象被凍結,我無法更改這些值。
一旦創建了這個類,我們在TemplateHandler中修改編譯方法以使用這些值。然後
模板如下所示: -
xml.foos do
@foos.each do |foo|
xml.foo do
xml.id(foo.id)
xml.name(foo.name)
xml.created_at(foo.created_at)
xml.last_updated(foo.updated_at)
xml.bars do
ActionView::TemplateHandlers::BuilderOptions.margin = 3
foo.bars.each do |bar|
xml << render(:partial => 'bars/bar', :locals => { :bar => bar })
end
ActionView::TemplateHandlers::BuilderOptions.margin = 0
end
end
end
end
的基本思想是設定臨界值的縮進級別,我們是渲染局部當。生成的XML與上面顯示的相同。
請不要複製/粘貼此代碼,也不要根據您的Rails版本進行檢查,以確保它們來自相同的代碼庫。 (我認爲上面是2.3.5)
這個問題就解決了Rails中4 – hcarreras 2014-07-28 13:14:16