2017-04-11 56 views
0

在我的Rails應用普通老式Ruby對象(PO​​RO):我有以下方法:Rails的:建立路由輔助方法可用來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

'init'?或者你的意思是'初始化'? – tadman

+0

@tadman不,我從字面上理解'init'方法。我在下面回答了我自己的問題,所以你可以看看這個班會是什麼樣子。 – Neil

+0

使用'init'和'initialize'會引起混淆,特別是在其他語言中,'init'是初始化方法的調用方式。 – tadman

回答

4

你要麼必須做什麼,你在你的自我的答案描述(鏈接到revision I refer to),或注射一些背景到您的波羅斯。上下文是知道所有這些方法的地方。事情是這樣的:

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 
+0

看到我更新的答案。讓我知道,如果你知道如何做到這一點,那麼它看起來好像在PORO對象內是不可能的。 – Neil

+0

我再次更新了我的答案。往上看。另外,我相信你的答案不會「總是」通過'Rails.application.routes.url_helpers'建立路徑。我在使用乘客時遇到了問題,因爲它不知道域名。 – Neil

+0

是的,在這些情況下,你應該明確指定主機。或者將其設置爲[像這樣](http://stackoverflow.com/a/5725343/125816)。 –

1

問題在於與操作視圖相關的方法不適用於PORO。

爲了從actionview中獲得所有好東西:您需要使用view_context關鍵字。然後:你可以簡單地在的ActionView相關的方法從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 

欲瞭解更多信息,請參閱下面引用:

+1

自我發表答案並且甚至不承認Sergio用簡單的upvote做了什麼都很骯髒。他也是對的,主持人就是你在說的。你在這裏做什麼是非常不規則的,不建議。 – tadman

+0

他的方法有不知道域的限制。特別是如果使用乘客,網址將是錯誤的。另外:在更新我的答案之前:我確實向他發表了評論,他沒有迴應。 「骯髒」使它非常強大。 – Neil

+0

我認爲你誤解了他的代碼。這種東西不會漏出是有原因的。如果你想要這種功能,定義助手。這正是他們想要的。 – tadman