Rails content_tag方法

时间:2016-08-03 13:34:40

标签: ruby-on-rails ruby methods

我正在浏览this gem的源代码,我发现使用content_tag会让我感到困惑。

def render(view)
  view.content_tag(name, attributes[:content], attributes.except(:content))
end

我不明白为什么在视图上调用content_tag。我通常使用它来帮助生成HTML标记,但我从未将其称为方法。

2 个答案:

答案 0 :(得分:2)

最常见的是,在视图的上下文中调用content_tag - 因此,您不需要调用view.content_tag,因为该视图知道如何回复content_tag(而简单地调用content_tag与调用self.content_tag相同。

您显示的render方法存在于继承自MetaTag的班级Tag中。 Tag是一个普通的旧Ruby对象(PO​​RO),所以它不知道如何回应content_tag

但是,正如您所看到的,render方法将视图作为参数。当然,view对象知道如何回复content_tag。因此,调用view.content_tagMetaTag能够呈现内容标记的方式。

这几乎是Presenter模式的一个实例(不同的人使用不同的术语)。 Ryan Bates在here上有一个很好的RailsCast。

对于你在评论中提出的问题,Rails并不知道" viewActionView::Base的一个实例。您有责任传入实际的视图实例。我倾向于传入控制器,以便我可以访问视图和参数。也许是这样的:

class FooController < ApplicationController

  def foo_action
    FooPresenter.present(self)
  end

end

和...

class FooPresenter
  class << self

    def present(controller)
      new(controller).present
    end

  end # class methods

  #===================================================================
  # instance methods
  #===================================================================

    def initialize(controller)
      @controller = controller
    end

    def present
      content_tag :div, data: {foo: params[:foo]}, class: 'bar'
    end

  private

    def controller()  @controller                end
    def view()        controller.view_context    end
    def params()      controller.params          end

    def method_missing(*args, &block)
      view.send(*args, &block)
    end

end

通过加入method_missing方法,我不再需要致电view.content_tag。我可以致电content_tag。 FooPresenter无法找到该方法,因此会将调用发送到view,其中将找到并执行该方法。

再一次,Ryan在解释所有这些方面做得很好。

答案 1 :(得分:1)

content_tag类是ActionView::Helpers::TagHelper类中的一种方法。我相信这堂课#39;对象自动包含在Rails视图中,或者Rails视图对象委托给该对象。

此特定gem将ActionView::Base对象作为其render方法的参数,以便该方法可以访问content_tag方法,该方法是ActionView::Helpers::TagHelper的一部分。这是Dependency Injection的一个很好的例子,这是面向对象编程的基本原则。