可以轨道路由助手(即mymodel_path(模型))在模型中使用?

假设我有一个叫做Thing的Rails模型。 Thing有一个url属性,可以select将其设置为Internet上的某个URL。 在查看代码,我需要逻辑,执行以下操作:

<% if thing.url.blank? %> <%= link_to('Text', thing_path(thing)) %> <% else %> <%= link_to('Text', thing.url) %> <% end %> 

这个视图中的条件逻辑是丑陋的。 当然,我可以build立一个辅助函数,将视图改为:

 <%= thing_link('Text', thing) %> 

这解决了冗长的问题,但我真的更喜欢在模型本身的function。 在这种情况下,视图代码将是:

 <%= link_to('Text', thing.link) %> 

显然,这将需要模型上的链接方法。 以下是它需要包含的内容:

 def link (self.url.blank?) ? thing_path(self) : self.url end 

至于这个问题,thing_path()是Model代码中的一个未定义的方法。 我假设可以将一些辅助方法“拉进”模型,但是如何? 是否有一个真正的原因,路由只能在应用程序的控制器和视图层? 我可以想象很多模型代码可能需要处理URL(与外部系统集成等)的情况。

在Rails 3和4中,你可以使用:

 Rails.application.routes.url_helpers 

例如

 Rails.application.routes.url_helpers.posts_path Rails.application.routes.url_helpers.posts_url(:host => "example.com") 

我已经find了自己如何做到这一点的答案。 在模型代码中,只需要放置:

对于Rails <= 2:

 include ActionController::UrlWriter 

对于Rails 3:

 include Rails.application.routes.url_helpers 

这神奇地使thing_path(self)返回当前事物的URL,或other_model_path(self.association_to_other_model)返回一些其他的URL。

您也可能会发现下面的方法比包括每个方法更清洁:

 class Thing delegate :url_helpers, to: 'Rails.application.routes' def url url_helpers.thing_path(self) end end 

任何与视图中显示内容有关的逻辑都应该委托给一个辅助方法,因为模型中的方法严格地用于处理数据。

这是你可以做的:

 # In the helper... def link_to_thing(text, thing) (thing.url?) ? link_to(text, thing_path(thing)) : link_to(text, thing.url) end # In the view... <%= link_to_thing("text", @thing) %> 

虽然可能有一种方法,我倾向于保持这种模式的逻辑。 我同意你不应该把它放在视图( 保持瘦 ),但除非模型是作为一个数据返回一个url到控制器,路由的东西应该在控制器。

(编辑:忘记我以前的喋喋不休…)

好吧,可能会出现这种情况,你可能会去模型或其他url…但是我不认为这属于模型,视图(或者模型)听起来更合适。

关于路线,据我所知,路线是控制器中的行为(通常“神奇地”使用一个视图),而不是直接的视图。 控制器应处理所有请求,视图应呈现结果,模型应处理数据并将其提供给视图或控制器。 我听到很多人在这里讨论到模型的路线(至less我已经开始讨论这个问题了),但是据我所知,路线走向pipe制员。 当然,很多控制器是一个模型的控制器,通常称为<modelname>sController (例如,“UsersController”是模型“User”的控制器)。

如果你发现自己在视图中编写了令人讨厌的逻辑,试着把逻辑移到更合适的地方。 请求和内部通信逻辑可能属于控制器,数据相关逻辑可能放置在模型中(但不包括显示逻辑,包括链接标签等),纯粹与显示有关的逻辑将被放置在帮助器中。

Interesting Posts