ruby-on-rails 可以使用Rails Routing Helpers(即mymodel_path(model))可以在模型中使用吗?

p5cysglq  于 2023-10-21  发布在  Ruby
关注(0)|答案(7)|浏览(131)

假设我有一个名为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的情况(与外部系统集成等)。

mpbci0fu

mpbci0fu1#

在Rails 3及更高版本中:

Rails.application.routes.url_helpers

例如

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

5kgi1eie2#

我已经找到了答案关于如何做到这一点自己。在模型代码中,只需输入:
对于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。

vsdwdz23

vsdwdz233#

你也可能会发现下面的方法比包含所有方法更简洁:

class Thing
  delegate :url_helpers, to: 'Rails.application.routes' 

  def url
    url_helpers.thing_path(self)
  end
end
qrjkbowd

qrjkbowd4#

任何与视图中显示内容有关的逻辑都应该委托给helper方法,因为模型中的方法严格用于处理数据。
你可以这样做:

# 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) %>
2uluyalo

2uluyalo5#

我真的很喜欢干净的解决方案。

class Router
  include Rails.application.routes.url_helpers

  def self.default_url_options
    ActionMailer::Base.default_url_options
  end
end

router = Router.new
router.posts_url  # http://localhost:3000/posts
router.posts_path # /posts

来自https://web.archive.org/web/20200221203515/https://www.hawkins.io/2012/03/generating_urls_whenever_and_wherever_you_want/

jm81lzqq

jm81lzqq6#

虽然可能有一种方法,但我倾向于将这种逻辑排除在模型之外。我同意你不应该把它放在视图(keep it skinny)中,但是除非模型返回一个url作为一段数据给控制器,否则路由的东西应该在控制器中。

vc9ivgsu

vc9ivgsu7#

  • (编辑:忘记我以前的胡言乱语.)*

好吧,可能会有这样的情况,你会去模型或其他一些URL.但我真的不认为这属于模型,观点(或模型)听起来更合适。
关于路由,据我所知,路由是用于控制器中的操作(通常“神奇地”使用视图),而不是直接到视图。控制器应该处理所有请求,视图应该呈现结果,模型应该处理数据并将其提供给视图或控制器。我听到很多人在这里谈论模特的路线(我几乎开始相信它),但据我所知:路由到控制器。当然,很多控制器都是一个模型的控制器,通常被称为<modelname>sController(例如,“UsersController”是模型“User”的控制器)。
如果您发现自己在视图中编写了大量的逻辑,请尝试将逻辑移到更合适的位置;请求和内部通信逻辑可能属于控制器,与数据相关的逻辑可以被放置在模型中(但不是显示逻辑,其包括链接标签等),而纯粹与显示相关的逻辑将被放置在助手中。

相关问题