假设我有一个名为Thing的Rails模型。Thing有一个url属性,可以可选地设置为Internet上某个地方的URL。在视图代码中,我需要执行以下操作的逻辑:
<% if thing.url.blank? %>
<%= link_to('Text', thing_path(thing)) %>
<% else %>
<%= link_to('Text', thing.url) %>
<% end %>
这种观点中的条件逻辑是丑陋的。当然,我可以构建一个helper函数,它会将视图更改为:
<%= thing_link('Text', thing) %>
这解决了冗长的问题,但我真的更喜欢在模型本身中拥有功能。在这种情况下,视图代码将是:
<%= link_to('Text', thing.link) %>
显然,这需要模型上的链接方法。以下是它需要包含的内容:
def link
(self.url.blank?) ? thing_path(self) : self.url
end
对于这个问题,thing_path()是Model代码中的一个未定义方法。我假设有可能将一些辅助方法“拉入”到模型中,但如何做到呢?路由只在应用程序的控制器和视图层运行,这有真实的原因吗?我能想到很多模型代码可能需要处理URL的情况(与外部系统集成等)。
7条答案
按热度按时间mpbci0fu1#
在Rails 3及更高版本中:
例如
5kgi1eie2#
我已经找到了答案关于如何做到这一点自己。在模型代码中,只需输入:
对于Rails <= 2:
对于Rails 3:
这就神奇地让
thing_path(self)
返回当前内容的URL,或者other_model_path(self.association_to_other_model)
返回其他URL。vsdwdz233#
你也可能会发现下面的方法比包含所有方法更简洁:
qrjkbowd4#
任何与视图中显示内容有关的逻辑都应该委托给helper方法,因为模型中的方法严格用于处理数据。
你可以这样做:
2uluyalo5#
我真的很喜欢干净的解决方案。
来自https://web.archive.org/web/20200221203515/https://www.hawkins.io/2012/03/generating_urls_whenever_and_wherever_you_want/
jm81lzqq6#
虽然可能有一种方法,但我倾向于将这种逻辑排除在模型之外。我同意你不应该把它放在视图(keep it skinny)中,但是除非模型返回一个url作为一段数据给控制器,否则路由的东西应该在控制器中。
vc9ivgsu7#
好吧,可能会有这样的情况,你会去模型或其他一些URL.但我真的不认为这属于模型,观点(或模型)听起来更合适。
关于路由,据我所知,路由是用于控制器中的操作(通常“神奇地”使用视图),而不是直接到视图。控制器应该处理所有请求,视图应该呈现结果,模型应该处理数据并将其提供给视图或控制器。我听到很多人在这里谈论模特的路线(我几乎开始相信它),但据我所知:路由到控制器。当然,很多控制器都是一个模型的控制器,通常被称为
<modelname>sController
(例如,“UsersController”是模型“User”的控制器)。如果您发现自己在视图中编写了大量的逻辑,请尝试将逻辑移到更合适的位置;请求和内部通信逻辑可能属于控制器,与数据相关的逻辑可以被放置在模型中(但不是显示逻辑,其包括链接标签等),而纯粹与显示相关的逻辑将被放置在助手中。