轨道 - 的link_to,路线和嵌套资源(Rails - link_to, routes and

2019-07-21 21:19发布

由于我对嵌套资源的认识,对边缘轨道,不应该

link_to 'User posts', @user.posts

指向

/users/:id/posts

在routes.rb中文件包含

map.resources :users, :has_many => :posts

如果这不是默认行为,可以在做其他事情来完成?

Answer 1:

沿着相同的路线为Rishav:

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

下面是解释我的博客 。

真的早在Rails中,你会写这样的路线:

redirect_to :controller => "posts", :action => "show", :id => @post.id

这是什么会做的是尽职尽责地重定向到show里面行动PostsController和沿传递id参数与任何的价值@post.id回报。 典型302响应。

然后在Rails 1.2版来了,并允许您使用路由帮手,就像这样:

redirect_to post_path(@post)

而人们欢欣鼓舞。

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

再后来的版本(我不记得是哪一个),使用的语法如下:

redirect_to @post

而人们欢欣鼓舞第二次。

魔术,但不是真的

任何足够先进的技术都与魔法无异。

虽然这看起来很神奇,其实并非如此。 这是什么东西做的其实是非常,非常整齐。 该redirect_to方法,就像它的表兄弟link_toform_for都使用一个通用的方法建立的网址,叫url_for 。 的url_for方法需要许多不同品种的对象,例如字符串,散列或甚至模型的实例,如在上面的例子。

它与这些对象做什么的话,是相当整齐。 在的情况下redirect_to @post上面打电话,它考察@post对象,认为它是一个对象Post类(我们假设,反正),并检查该对象是否已在数据库中调用了某个地方仍然存在persisted? 在上面。

通过“坚持”,我的意思是一个Ruby对象在数据库中的匹配记录的地方。 在persisted? 在活动记录方法的实现是这样的:

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_tolink_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 ,而不是index的动作,这是会是什么结果,如果它是一个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可以足够灵活以对既有相同的语法, newedit视图。 它变得越来越普遍,这些天,人们甚至把他们的整个form_for标记成一个单一的部分,包括它在这两个newedit页面。

一个更复杂的形式

所以form_for是当你通过一个正常的对象相当简单,但如果你传递对象的数组,会发生什么? 与此类似,比如:

<%= form_for [@post, @comment] do |f| %>

同时,双方url_forform_for有你覆盖有太多。

url_for方法检测到这是一个阵列,并且每个部分分离出并单独检查它们。 首先,这是什么@post的事情吗? 那么,在这种情况下,我们假设这是一个Post 坚持并有1秒的ID实例,这是什么@comment对象? 这是一个Comment还没有被保存到数据库实例。

什么url_for将在这里做的是通过将每个部分在一个阵列,其连接到路由方法,然后调用所需的参数是路由方法建立由部分网址助手方法片。

首先,它知道@post对象是中Post类,并且是持续的,因此网址助手将首先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 ,让我们来看看另一种普遍使用。 包含至少一个符号的对象,这样的阵列:

<%= form_for [:admin, @post, @comment] do |f| %>

什么url_for方法在这里所做的是很简单的。 它认为,有一个Symbol ,带着它,因为它是。 在第一部分url将只是一样的符号: admin 。 该URL url_for在这点知道的仅仅是[:admin]

然后url_for穿过阵列的剩余部分。 在这种情况下,我们假设两种@post@comment被持久化,他们分别为1和2的ID。 相同的类如前。 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_tolink_toform_for方法。 有可能是我不记得现在可以做到这一点其他的方法......这是在Rails的东西一般,通常会采取网址。

有没有必要建立任何的Rails版本大于2个使用散列您的网址; 这是很老的学校。

相反,尝试新的多态的路由的知识,并用它来最好的你的优势。



Answer 2:

这应该工作:

 
 link_to "User Posts", user_posts_path(@user)

更多详情请访问:

http://guides.rubyonrails.org/routing.html



Answer 3:

link_to使用url_for它采用polymorphic_url

polymorphic_url

  • 建立辅助方法 ,使用活动记录对象的类名

  • 来电助手与活动记录的对象作为参数

因此,有人说,你应该使用:

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

的量,路径是:

user_posts_path(@user)
^^^^ ^^^^^      ^^^^^
1    2          3
  1. @user因为它是一个活动记录
  2. 转换为字符串,因为符号
  3. 添加为调用参数,因为活动记录

这营造良好的辅助方法。



Answer 4:

这是如何链接到最新的Rails嵌套资源:

的link_to '消灭评论',post_comment_path(comment.post,评论)

注:这是一个局部的,这样就不会有一个@



文章来源: Rails - link_to, routes and nested resources