gpt4 book ai didi

ruby-on-rails - Rails - link_to、路由和嵌套资源

转载 作者:行者123 更新时间:2023-12-03 10:07:48 24 4
gpt4 key购买 nike

正如我对嵌套资源的理解,在边缘 Rails 上,不应该

link_to 'User posts', @user.posts

指向
/users/:id/posts

?

route.rb 文件包含
map.resources :users, :has_many => :posts

如果这不是默认行为,是否可以通过其他方式完成?

最佳答案

与 Rishav 相同:

link_to "User Posts", [@user, :posts]

这是来自 my blog 的解释.

在 Rails 的早期,你会写这样的路由:
redirect_to :controller => "posts", :action => "show", :id => @post.id

这将做的是尽职尽责地重定向到 show里面的 Action PostsController并传递 id参数与
任何值(value) @post.id返回。典型的 302 响应。

然后 Rails 1.2 出现并允许您使用路由助手,如下所示:
redirect_to post_path(@post)

人民欢欣鼓舞。

这将有效地做同样的事情。 post_path这里将使用 @post 建立一条路线看起来像什么的物体
喜欢 /posts/1然后 redirect_to将向该路由发送回 302 响应,浏览器将遵循它。

然后后来的版本(我不记得是哪个),允许这样的语法:
redirect_to @post

人们第二次欢欣鼓舞。

魔术,但不是真的

Any sufficiently advanced technology is indistinguishable from magic.



虽然这看起来很神奇,但事实并非如此。这实际上非常非常整洁。 redirect_to方法,很像它的堂兄弟 link_toform_for都使用一种通用的方法来构建 URL,称为 url_for . url_for方法需要很多不同的
各种对象,例如字符串、散列甚至模型实例,如上例所示。

它对这些对象的处理非常简洁。在 redirect_to @post 的情况下调用上面,它检查 @post对象,看到它是 Post 的对象类(我们假设,无论如何)并检查该对象是否已保存在
数据库某处调用 persisted?在上面。

通过“持久化”,我的意思是 Ruby 对象在数据库中的某处有匹配的记录。 persisted? Active Record 中的方法是这样实现的:
def persisted?
!(new_record? || destroyed?)
end

如果对象不是通过诸如 Model.new 的调用创建的那么它就不会是新记录,如果它没有 destroy调用它的方法不会
也毁了。如果这两种情况都为真,那么这使得对象很可能以记录的形式持久化到数据库中。

如果已经持久化,则 url_for知道可以找到这个对象
某处,并且可以找到它的地方很可能在名为 post_path 的方法下。 .所以它调用这个方法,并通过
to_param此对象的值通常是 id .

简而言之,它有效地做到了这一点:
#{@post.class.downcase}_path(@post.to_param)

结果是这样的:
post_path(1)

当该方法被调用时,你会得到这个小字符串:
"/posts/1"

迷人的!

这称为多态路由。您可以将对象传递给 redirect_to 之类的方法。 , link_toform_for它会
尝试找出要使用的内容的正确 URL。

form_for 的形式

现在,当您编写 Rails 代码时,您可能已经使用过 form_for很久以前是这样的:
<% form_for @post, :url => { :controller => "posts", :action => "create" } do |f| %>

当然,随着 Rails 的进步,您可以将其简化为:
<% form_for @post, :url => posts_path do |f| %>

因为表单将默认具有 POST HTTP 方法,因此对 posts_path 的请求要去 create PostsController的 Action ,而不是 index Action ,如果它是 GET 会产生什么结果要求。

但为什么要停在那里?为什么不写这个?
<%= form_for @post do |f| %>

就个人而言,我认为没有理由不...如果事情像这样简单。 form_for方法使用 url_for在下面,就像 redirect_to找出表格应该放在哪里。它知道 @post对象属于 Post类(再次,我们假设)和它
检查对象是否被持久化。如果是,那么它将使用 post_path(@post) .如果不是,那么 posts_path .
form_for方法本身会检查传入的对象是否也被持久化,如果是,则默认为 PUT HTTP
方法,否则为 POST .

所以这就是 form_for可以足够灵活地在 new 上使用相同的语法和 edit看法。它变得越来越
这些天人们甚至把他们的整个人都放在一起更常见 form_for标记到单个部分并将其包含在 new 中和 edit页。

更复杂的形式

所以 form_for当你传递一个普通对象时相当简单,但是如果你传递一个对象数组会发生什么?像这样,对于
实例:
<%= form_for [@post, @comment] do |f| %>

好吧,两者都是 url_forform_for你有没有覆盖那里。
url_for方法检测到这是一个数组并分离出每个部分并单独检查它们。首先,这是什么 @post事物?好吧,在这种情况下,让我们假设它是 Post持久化且id为1的实例。 其次,这是什么 @comment目的?这是一个 Comment尚未持久化到数据库的实例。

什么 url_for这里要做的是通过将每个部分放在一个数组中,将其连接到一个路由方法中,然后使用必要的参数调用该路由方法,逐个构建 URL 帮助器方法。

首先,它知道 @post对象属于 Post类并被持久化,因此 URL 助手将以 post 开头.其次,它知道 @comment对象属于 Comment类并且不会被持久化,因此 comments会关注 post在 URL 助手构建中。 url_for 的零件现在知道的是 [:post, :comments] .
url_for方法将这些单独的部分与下划线组合在一起,使其成为 post_comments然后附加 _path到最后,导致 post_comments_path .然后它只将持久化对象传递给对该方法的调用,从而产生如下调用:
post_comments_path(@post)

调用该方法会导致:
"/posts/1/comments"

最好的部分? form_for仍然会知道使用 POST如果 @comment对象不是持久化对象,并且 PUT如果是。一个好的
要记住的是 form_for始终用于数组中指定的最后一个对象。在它之前的对象只是它的
嵌套,仅此而已。

添加的对象越多,次数越多 url_for会做硬码并建立路径......虽然我建议
你把它分成两部分。

象征形式

现在我们已经介绍了使用包含 form_for 的对象的数组。 ,我们来看看另一个常见的用法。一个包含
至少一个 Symbol 对象,像这样:
<%= form_for [:admin, @post, @comment] do |f| %>

什么 url_for这里的方法确实很简单。它看到有一个 Symbol并按原样接受它。第一部分 url将与符号相同: admin . url_for 的网址知道此时只是 [:admin] .

然后 url_for遍历数组的其余部分。在这种情况下,让我们假设两个 @post@comment被坚持
并且它们的 ID 分别为 1 和 2。和以前一样的课。 url_for然后添加 post到它正在构建的 URL,
comment也是,导致 [:admin, :post, :comment] .

然后连接发生,导致方法 admin_post_comment_path ,因为两者都是 @post@comment坚持在这里,
它们被传入,导致此方法调用:
admin_post_comment_path(@post, @comment)

这(通常)变成这条路:
/admin/posts/1/comments/2

您可以将多态路由的数组形式与 redirect_to 一起使用, link_toform_for方法。可能还有其他
我现在不记得的方法也可以这样做……它通常是 Rails 中通常需要 URL 的任何东西。

无需使用哈希在任何大于 2 的 Rails 版本中构建您的 URL;那是相当古老的学校。

相反,尝试使用您对多态路由的新知识并充分利用它。

关于ruby-on-rails - Rails - link_to、路由和嵌套资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1548009/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com