不幸的是没有一个直接的解决方案。在查看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