Rails:使 PORO 可以使用 Route Helper 方法

Nei*_*eil 1 ruby ruby-on-rails

在我的 rails 应用程序中的普通旧 Ruby 对象 (PORO) 中:我有以下方法:

def some_method
  content_tag(:li, link_to("Do something", somewhere_path(object.id)))
end
Run Code Online (Sandbox Code Playgroud)

首先:对象不理解该方法content_tag,所以我添加了以下内容,使对象理解该方法:

include ActionView::Helpers::TagHelper
Run Code Online (Sandbox Code Playgroud)

然后对象不理解,link_to所以我添加了以下内容,使对象理解该方法:

include ActionView::Helpers::UrlHelper
Run Code Online (Sandbox Code Playgroud)

现在,它不理解我的路线:somewhere_path(object.id)

问题:如何让 Rails 应用程序中的 PORO 理解生成路线的助手?

后续问题:是否有更简单的方法将所有这些功能包含到我的 PORO 对象中?也许有一种方法可以只使用include一个主要模块并获得所有这些功能(而不是可能需要 3 个不同的模块)。

Ser*_*sev 5

您要么必须按照您在自我回答中描述的内容(我指的是修订版的链接),要么在您的 PORO 中注入一些上下文。上下文是知道所有这些方法的东西。像这样的东西:

class ProjectsController
  def update
    project = Project.find(params[:id])
    presenter = Presenters::Project.new(project, context: view_context) # your PORO
    # do something with presenter
  end
end
Run Code Online (Sandbox Code Playgroud)

你的 PORO 看起来像这样:

module Presenters
  class Project
    attr_reader :presentable, :context
    def initialize(presentable, context:)
      @presentable = presentable
      @context = context
    end

    def special_link
      context.somewhere_path(presentable)
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

我,两个都不喜欢。但有时我们不得不选择一个较小的邪恶。

如果有人碰巧知道使用一个 include 语句访问所有这些方法的当前方法,请告诉我。

为什么是。有一种方法。

module MyViewCompatibilityPack
  include ActionView::Helpers::TagHelper
  include ActionView::Helpers::UrlHelper

  def url_helpers
    Rails.application.routes.url_helpers
  end
end

class MyPoro
  include MyViewCompatibilityPack

  ...
end
Run Code Online (Sandbox Code Playgroud)