在我的rails app中的普通旧Ruby对象(PORO)中:我有以下方法:
def some_method
content_tag(:li, link_to("Do something", somewhere_path(object.id)))
end
首先:对象不理解方法content_tag
,所以我添加了以下内容,使对象理解了该方法:
include ActionView::Helpers::TagHelper
然后对象不理解link_to
所以我添加了以下内容使对象理解了该方法:
include ActionView::Helpers::UrlHelper
现在,它不了解我的路线:somewhere_path(object.id)
。
问题:如何让我的rails应用中的PORO了解生成路由的助手?
后续问题:是否有更简单的方法将所有这些功能都包含在我的PORO对象中?也许有一种方法只能include
一个主要模块并获得所有这些功能(而不是需要需要3个不同的模块)。
答案 0 :(得分:3)
您必须在自我回答中做出您所描述的内容(链接到revision I refer to),或在您的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
你的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
我,我不喜欢他们。但有时我们必须选择较小的邪恶。
如果有人碰巧知道当前使用一个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
答案 1 :(得分:0)
问题是PORO无法使用与行动视图相关的方法。
为了从动作视图中获取所有优秀内容:您需要使用view_context
关键字。然后:您只需调用view_context
:
class BuildLink
attr_accessor :blog, :view_context
def initialize(blog, view_context)
@blog = blog
@view_context = view_context
end
def some_method
content_tag(:li, link_to(“Show Blog“, view_context.blog_path(blog)))
end
end
例如:从您的控制器中,您可以像这样调用此PORO:
BuildLink.new(@blog, view_context).some_method
有关详细信息,请参阅以下参考资料:
view_context
,如this article view_context
进行讨论