Ruby-on-rails 如何使用带有参数的 Rails 命名路由助手?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8531306/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 02:30:20  来源:igfitidea点击:

How to use Rails named route helpers with parameters?

ruby-on-railsroutes

提问by Ant

given this route

鉴于这条路线

match 'posts/hello/:name/:title' => 'post#show', :as => :hello
  • what are the ways that I can call hello_path?

  • if i call hello_path(@post), what does it try to do?

  • 我可以打电话的方式是hello_path什么?

  • 如果我打电话hello_path(@post),它想做什么?

I was hoping that the :nameand :titlefiles will bind to the path automatically but it seems that rails only know how to get the :id out of the model object.

我希望:nameand:title文件会自动绑定到路径,但 Rails 似乎只知道如何从模型对象中获取 :id 。

instead, it only works if I call it like

相反,它只有在我称之为

<%= link_to "link2", hello_url(:name=> @post.name, :title=>@post.title) %>

(lack of proper documentation is really killing me)

(缺乏适当的文件真的让我很伤心)

回答by GregT

To answer your two questions:

回答你的两个问题:

  • At the command line, runrake routesto see what routes there are in your app. It will show you all the ways you can use the named routes, just add "_path" or "_url" to the name of the route which is shown on the left.
  • Calling hello_path(@post)will generate a URL to the showpage for that helloinstance.
  • 在命令行中,运行rake routes以查看您的应用程序中有哪些路由。它将向您展示使用命名路由的所有方式,只需在左侧显示的路由名称中添加“_path”或“_url”即可。
  • 调用hello_path(@post)将生成该实例的显示页面的 URL hello

The way you are calling it is the norm:

你称呼它的方式是常态:

<%= link_to "link2", hello_url(:name=> @post.name, :title=>@post.title) %>

However, this may work too:

但是,这也可能有效:

<%= link_to "link2", hello_url(@post.name, @post.title) %>

Here is some documentation (other than the Rails API) which should help. http://guides.rubyonrails.org/routing.html

这里有一些文档(Rails API 除外)应该会有所帮助。 http://guides.rubyonrails.org/routing.html

回答by declan

To answer your question of "what does hello_pathtry to do?"

回答您的问题“hello_path尝试做什么?”

hello_pathknows how many parameters it's supposed to get. This is from counting the named parameters in config/routes. It will accept either a hash or a list of arguments. If you give it a hash, the keys must match the names of the URL parameters. If you give it a list of arguments, it'll just match them up by position - the first argument with the first named parameter.

hello_path知道它应该得到多少参数。这是通过计算config/routes. 它将接受散列或参数列表。如果给它一个散列,键必须与 URL 参数的名称匹配。如果你给它一个参数列表,它只会按位置匹配它们——第一个参数与第一个命名参数。

Then, it will call to_paramon eachparameter individually before joining them all together (see code here, 4.0 branch).

然后,它会to_param在将每个参数连接在一起之前分别调用它们(请参阅此处的代码,4.0 分支)。

If you pass in an object when it's expecting 2 or more params, it won't even get around to calling to_param on the object. That's when you get errors with no stack trace that say something like
No route matches {:controller=>"posts", :action=>"show", :id=>#<Post ...>}

如果您在需要 2 个或更多参数时传入一个对象,它甚至不会在该对象上调用 to_param。那时你会收到没有堆栈跟踪的错误,比如
No route matches {:controller=>"posts", :action=>"show", :id=>#<Post ...>}

Working with 1 named parameter

使用 1 个命名参数

If you've only got one named parameter, things are pretty straightforward. If you need to look up your posts by name instead of id, you can just redefine to_param

如果您只有一个命名参数,则事情非常简单。如果您需要按名称而不是 id 查找您的帖子,您可以重新定义to_param

class Post < ActiveRecord::Base
  ...
  def to_param
    name
  end
end

Working with multiple named parameters

使用多个命名参数

But if the URL has more than one named parameter in it, then redefining to_paramisn't enough. Let's say you tried this:

但是如果 URL 中包含多个命名参数,那么重新定义to_param是不够的。假设你试过这个:

# app/models/post.rb
class Post < ActiveRecord::Base
  ...
  def to_param
    {name: name, title: title}
  end
end

# app/views/posts/index.html.erb
<%= post_path(post) %>

In this case, you'll get a routing error because you're not passing in enough arguments to post_path (see above). To get around this, I just call to_paramexplicitly:

在这种情况下,您将收到路由错误,因为您没有向 post_path 传递足够的参数(见上文)。为了解决这个问题,我只是to_param明确地调用:

 # app/views/posts/index.html.erb
 <%= post_path(post.to_param) %>

This is a little less slick than most Rails routing magic, but works perfectly well. If you later change the way you're looking up Posts, all you have to do is redefine to_param. No need to worry about all the places you've called post_path

这比大多数 Rails 路由魔法要少一些,但效果很好。如果您以后更改了查找帖子的方式,您所要做的就是重新定义 to_param。无需担心您已致电的所有地点post_path

Under the hood

引擎盖下

The relevant code to look at is actionpack/lib/action_dispatch/routing

要查看的相关代码是actionpack/lib/action_dispatch/routing

回答by James

You can also call it like this

你也可以这样称呼

hello_path(@post.name, @post.title)

Hope it helps.

希望能帮助到你。

回答by IAmNaN

The other answers (at the time of this writing) are fine, but your reply to GregT's answer shows a lack of understand about Rails, which is fine -- we've all been there.

其他答案(在撰写本文时)很好,但是您对 GregT 答案的回复表明您对 Rails 缺乏了解,这很好——我们都去过那里。

Specifically, three of the key principles behind Rails: convention over configuration, the model-view-controller architecture(MVC), and REST. It's stuff at the beginning of every beginning Rails book. Beginners often think they can just jump to the first chapter with code, but Rails differs from many other topics in that the first chapters explain important concepts and aren't just intro chapter filler. Because Rails isn't "code", it's a "framework of code".

具体来说,Rails 背后的三个关键原则:约定优于配置模型-视图-控制器架构(MVC) 和REST。这是每本 Rails 入门书籍开头的内容。初学者通常认为他们可以直接跳到带有代码的第一章,但 Rails 与许多其他主题的不同之处在于,第一章解释了重要的概念,而不仅仅是介绍章节的填充。因为 Rails 不是“代码”,而是“代码框架”。

"Convention over configuration" means if you follow certain conventions then you benefit from behaviors baked into Rails. Routing is one of those areas, if not the biggest, where convention benefits the developer although it is entirely configurable.

“约定优于配置”意味着如果您遵循某些约定,那么您将从 Rails 中的行为中受益。路由是那些领域之一,如果不是最大的,尽管约定是完全可配置的,但它对开发人员有利。

Paths following a specific routing format, are parsed into the controller, action and possibly an id, format, and additional parameters. By default and at minimum, a Rails (and also a Sinatra) path takes the following format and order:

遵循特定路由格式的路径被解析为控制器、动作以及可能的 id、格式和其他参数。默认情况下,Rails(以及 Sinatra)路径采用以下格式和顺序:

/controller_name/action_name

It's a little more complicated than that, with more options, and it looks more like this in actuality:

它比那更复杂一点,有更多的选择,实际上看起来更像这样:

/controller_name/action_name/(id)(.format)(?param=value)(&...)

...but it's more detail than is necessary for this answer.

...但它比这个答案所需要的更详细。

The controlleris the C in MVC, or the class that handles the request. The actionis one of the seven RESTful actions (index, show, new, create, edit, update, and destroy) within that controller. Not all actions require an id (index, newand create) and not all of them are getrequests (requests that generate a view, for instance destroy, createand updatedon't have views).

控制器是MVC中C,或类处理该请求。该动作是七个的RESTful动作(之一indexshownewcreateeditupdate,和destroy该控制器内)。并非所有的操作都需要一个id( indexnewcreate),而不是所有的人都get请求(即产生一个视图,例如请求destroycreate并且update没有意见)。

Putting it all together we see this example:

把它们放在一起,我们看到这个例子:

/articles/edit/1

...will route the request to the 'edit' action in the ArticlesController controller passing along id 1. It's expected that the controller will do some housekeeping, like authentication and authorization, then retrieve Article model (MCV) with ID 1 and pass it along to the "edit" view (MCV).

...将请求路由到传递 id 1 的 ArticlesController 控制器中的“编辑”操作。预计控制器将进行一些内务处理,例如身份验证和授权,然后检索ID 为 1 的文章模型 ( MCV) 并通过它沿着“编辑”视图(MC V)。

It's best, especially for new Rails developers, to stick to these conventions and perhaps add a few additional actions beyond those provided by REST.

最好,特别是对于新的 Rails 开发人员,坚持这些约定,并且可能添加一些超出 REST 提供的操作的附加操作。

You can step outside this convention by configuring in your routes.rb file an alternative routing scheme, not following REST, etc., but you'll be like a salmon swimming upstream -- it's a lot harder than going with the flow. If you go down that path (pun) you'll make a lot of additional work for yourself, probably reinvent the wheel somewhat, and lose advantages provided by the Rails framework. If you find yourself in that situation for whatever reason, perhaps Rails isn't the right tool for your job.

您可以通过在 routes.rb 文件中配置替代路由方案,而不是遵循 REST 等来超越此约定,但是您将像逆流而上的鲑鱼一样——这比顺其自然要困难得多。如果你沿着这条路走下去(双关语),你会为自己做很多额外的工作,可能会重新发明轮子,并失去 Rails 框架提供的优势。如果您出于某种原因发现自己处于这种情况,那么 Rails 可能不是适合您工作的工具。