将Rails助手方法提取到单独的类

时间:2018-07-09 16:09:12

标签: ruby-on-rails ruby-on-rails-5

我想开始为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


ERB Result


HAML Result


如您所见,使用助手类时,输出会出错,但奇怪的是,我们使用的是哪种模板引擎,它们之间的差异就足够大了。有人能指出我正确的方向,以便了解正在发生的事情以及如何去做。想?谢谢

1 个答案:

答案 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 TagBuilderdoc),但是您仍然需要视图上下文:

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