我想开始为Rails视图助手创建对象,而不是使用助手(某种“滚动自己的” Trailblazer或Hanami视图的Cell :: Object)。一切都按预期进行,直到我们开始混合块为止,奇怪的是,我们在erb和haml模板上得到了不同的结果!
这是一个vainilla Rails v5.2应用程序,仅添加了haml-rails,以简化问题:
<h1>ERB</h1>
<%= bordered do %>
<p>This works</p>
<% end %>
<hr />
<%= Builder.new.bordered do %>
<p>This not works</p>
<% end %>
app / views / home / erb.html.erb
%h1 HAML
= bordered do
%p This works
%hr
= Builder.new.bordered do
%p This not works
app / views / home / haml.html.haml
module HomeHelper
def bordered(&block)
content_tag(:div, style: 'border: 1px solid black') do
block.call
end
end
end
app / helpers / home_helper.rb
class Builder
include ActionView::Helpers
include ActionView::Context
def bordered(&block)
content_tag(:div, style: 'border: 1px solid black') do
block.call
end
end
end
app / presenters / builder.rb
如您所见,使用助手类时,输出会出错,但奇怪的是,我们使用的是哪种模板引擎,它们之间的差异就足够大了。有人能指出我正确的方向,以便了解正在发生的事情以及如何去做。想?谢谢
答案 0 :(得分:1)
Rails帮助器是在视图本身上执行的,这意味着如果要传递视图,则可以在相同的上下文中对其调用方法:
这是您解决问题的方法:
class Builder
def initialize(view_context)
@view_context = view_context
end
def bordered(&block)
@view_context.content_tag(:div, style: 'border: 1px solid black', &block)
end
end
现在,如果您想使用构建器,则可以通过创建视图,例如。视图本身中的Builder.new(self).bordered
。
或者,您可以使用Rails TagBuilder
(doc),但是您仍然需要视图上下文:
class Builder
def initialize(view_context)
@view_context = view_context
end
def bordered(&block)
tag_builder.div(style: 'border: 1px solid black', &block)
end
private
def tag_builder
@tag_builder ||= ::ActionView::Helpers::TagHelper::TagBuilder.new(@view_context)
end
end