Ruby-on-rails 可以在模型中使用 Rails 路由助手(即 mymodel_path(model))吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/341143/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can Rails Routing Helpers (i.e. mymodel_path(model)) be Used in Models?
提问by Aaron Longwell
Say I have a Rails Model called Thing. Thing has a url attribute that can optionallybe set to a URL somewhere on the Internet. In view code, I need logic that does the following:
假设我有一个名为 Thing 的 Rails 模型。Thing 有一个 url 属性,可以选择将其设置为 Internet 上某处的 URL。在视图代码中,我需要执行以下操作的逻辑:
<% 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).
就问题而言, thing_path() 是模型代码中的未定义方法。我假设可以将一些辅助方法“引入”模型中,但是如何?路由仅在应用程序的控制器和视图层运行是否有真正的原因?我可以想到很多模型代码可能需要处理 URL(与外部系统集成等)的情况。
回答by Paul Horsfall
In Rails 3, 4, and 5 you can use:
在 Rails 3、4 和 5 中,您可以使用:
Rails.application.routes.url_helpers
e.g.
例如
Rails.application.routes.url_helpers.posts_path
Rails.application.routes.url_helpers.posts_url(:host => "example.com")
回答by Aaron Longwell
I've found the answer regarding how to do this myself. Inside the model code, just put:
我已经找到了有关如何自己执行此操作的答案。在模型代码中,只需输入:
For Rails <= 2:
对于 Rails <= 2:
include ActionController::UrlWriter
For Rails 3:
对于 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.
这会神奇地thing_path(self)返回当前事物的 URL,或者other_model_path(self.association_to_other_model)返回其他一些 URL。
回答by matthuhiggins
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
回答by Josh Delsman
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) %>
回答by Swar Shah
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 http://hawkins.io/2012/03/generating_urls_whenever_and_wherever_you_want/
它来自http://hawkins.io/2012/03/generating_urls_whenever_and_wherever_you_want/
回答by Ryan Montgomery
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.
虽然可能有一种方法我倾向于将这种逻辑排除在模型之外。我同意你不应该把它放在视图中(保持瘦),但除非模型将 url 作为一条数据返回给控制器,否则路由的东西应该在控制器中。
回答by Stein G. Strindhaug
(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.
好吧,在某些情况下,您可能会转到模型或其他一些 url ……但我真的不认为这属于模型,视图(或模型)听起来更合适。
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").
关于路线,据我所知,路线是用于控制器中的操作(通常“神奇地”使用视图),而不是直接用于视图。控制器应该处理所有请求,视图应该呈现结果,模型应该处理数据并将其提供给视图或控制器。我听说这里有很多人在谈论到模型的路由(到了我几乎开始怀疑它的地步),但据我所知:路由去往控制器。当然,很多控制器都是一个模型的控制器,通常被称为<modelname>sController(例如“UsersController”是模型“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.
如果您发现自己在视图中编写了大量令人讨厌的逻辑,请尝试将逻辑移到更合适的地方;请求和内部通信逻辑可能属于控制器,数据相关的逻辑可以放在模型中(但不是显示逻辑,包括链接标签等),而纯粹与显示相关的逻辑将放在帮助器中。

