Rails 路由助手(即 mymodel_path(model))可以在模型中使用吗?

发布于 2024-07-09 15:22:49 字数 800 浏览 6 评论 0原文

假设我有一个名为 Thing 的 Rails 模型。 事物有一个 url 属性,可以可选将其设置为 Internet 上某个位置的 URL。 在视图代码中,我需要执行以下操作的逻辑:

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

视图中的条件逻辑很丑陋。 当然,我可以构建一个辅助函数,这会将视图更改为:

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

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

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

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

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

就问题而言,thing_path() 是模型代码中未定义的方法。 我假设可以将一些辅助方法“引入”到模型中,但是如何实现呢? 路由仅在应用程序的控制器和视图层运行是否有真正的原因? 我可以想到很多模型代码可能需要处理 URL(与外部系统集成等)的情况。

Say I have a Rails Model called Thing. Thing has a url attribute that can optionally be set to a URL somewhere on the Internet. In view code, I need logic that does the following:

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

This conditional logic in the view is ugly. Of course, I could build a helper function, which would change the view to this:

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

That solves the verbosity problem, but I would really prefer having the functionality in the model itself. In which case, the view code would be:

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

This, obviously, would require a link method on the model. Here's what it would need to contain:

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

To the point of the question, thing_path() is an undefined method inside Model code. I'm assuming it's possible to "pull in" some helper methods into the model, but how? And is there a real reason that routing only operates at the controller and view layers of the app? I can think of lots of cases where model code may need to deal with URLs (integrating with external systems, etc).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

在你怀里撒娇 2024-07-16 15:22:49

在 Rails 3 及更高版本中:

Rails.application.routes.url_helpers

例如

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

In Rails 3 and higher:

Rails.application.routes.url_helpers

e.g.

Rails.application.routes.url_helpers.posts_path
Rails.application.routes.url_helpers.posts_url(:host => "example.com")
画中仙 2024-07-16 15:22:49

我已经找到了有关如何自己执行此操作的答案。 在模型代码中,只需输入:

For Rails <= 2:

include ActionController::UrlWriter

For Rails 3:

include Rails.application.routes.url_helpers

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

I've found the answer regarding how to do this myself. Inside the model code, just put:

For Rails <= 2:

include ActionController::UrlWriter

For Rails 3:

include Rails.application.routes.url_helpers

This magically makes thing_path(self) return the URL for the current thing, or other_model_path(self.association_to_other_model) return some other URL.

梓梦 2024-07-16 15:22:49

您可能还会发现以下方法比包含每种方法更干净:

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

  def url
    url_helpers.thing_path(self)
  end
end

You may also find the following approach cleaner than including every method:

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

  def url
    url_helpers.thing_path(self)
  end
end
薄情伤 2024-07-16 15:22:49

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

您可以执行以下操作:

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

Any logic having to do with what is displayed in the view should be delegated to a helper method, as methods in the model are strictly for handling data.

Here is what you could do:

# 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) %>
本王不退位尔等都是臣 2024-07-16 15:22:49

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

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/generate_urls_whenever_and_wherever_you_want/

I really like following clean solution.

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

It's from https://web.archive.org/web/20200221203515/https://www.hawkins.io/2012/03/generating_urls_whenever_and_wherever_you_want/

机场等船 2024-07-16 15:22:49

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

While there might be a way I would tend to keep that kind of logic out of the Model. I agree that you shouldn't put that in the view (keep it skinny) but unless the model is returning a url as a piece of data to the controller, the routing stuff should be in the controller.

莳間冲淡了誓言ζ 2024-07-16 15:22:49

(编辑:忘记我之前的胡言乱语...)

好吧,在某些情况下您可能会转到模型或其他一些网址...但我真的不认为这属于模型、视图(或者模型)听起来更合适。

关于路线,据我所知,路线是针对控制器中的操作(通常“神奇地”使用视图),而不是直接针对视图。 控制器应该处理所有请求,视图应该呈现结果,模型应该处理数据并将其提供给视图或控制器。 我听到很多人在这里谈论模型的路由(以至于我几乎开始放弃它),但据我了解:路由到控制器。 当然,许多控制器都是一个模型的控制器,通常称为sController(例如“UsersController”是模型“User”的控制器)。

如果您发现自己在视图中编写了大量逻辑,请尝试将逻辑移至更合适的位置; 请求和内部通信逻辑可能属于控制器,数据相关逻辑可以放置在模型中(但不是显示逻辑,其中包括链接标签等),而纯粹与显示相关的逻辑将放置在助手中。

(Edit: Forget my previous babble...)

Ok, there might be situations where you would go either to the model or to some other url... But I don't really think this belongs in the model, the view (or maybe the model) sounds more apropriate.

About the routes, as far as I know the routes is for the actions in controllers (wich usually "magically" uses a view), not directly to views. The controller should handle all requests, the view should present the results and the model should handle the data and serve it to the view or controller. I've heard a lot of people here talking about routes to models (to the point I'm allmost starting to beleave it), but as I understand it: routes goes to controllers. Of course a lot of controllers are controllers for one model and is often called <modelname>sController (e.g. "UsersController" is the controller of the model "User").

If you find yourself writing nasty amounts of logic in a view, try to move the logic somewhere more appropriate; request and internal communication logic probably belongs in the controller, data related logic may be placed in the model (but not display logic, which includes link tags etc.) and logic that is purely display related would be placed in a helper.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文