嵌套form_for的Rails路由错误 [英] Rails Routing Error for nested form_for

查看:64
本文介绍了嵌套form_for的Rails路由错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在已经被问了一千遍了,但这对我没有帮助。:)我去过一个小时。我的表单:

I now this has been asked a thousand times but that doesn't help me heh :) I've been at this an hour. My form:

= form_for @comment, :url_for => { :action => "create", :controller => "comments"}, :method => :post

我的耙路:

                   POST   /t/:trunk_id/r/:root_id/comments(.:format)          {:action=>"create", :controller=>"comments"}
trunk_root_comment GET    /t/:trunk_id/r/:root_id/comments/:id(.:format)      {:action=>"show", :controller=>"comments"}

错误:

undefined method `comments_path' for #<#<Class:0x007fed2c713128>:0x007fed2c71cc78>

如果我将表格命名为:

= form_for [:trunk_root, @comment], :url_for => { :action => "create", :controller => "comments"}, :method => :post do |f|

这应该使路线trunk_root_comments_path ..根据耙路正确。

which should make the route trunk_root_comments_path.. which is correct according to the rake routes.. I get:

No route matches {:controller=>"comments", :format=>nil}

非常感谢帮助。.几个小时都在看这个。.

Help is very much appreciated.. been looking at this for hours..

更新:

谢谢瑞安这么好的回答!对于我当时只是在扔东西的事情,有一个非常明确的解释,至少我现在了解得更多。实际上,我的耙路中已经有 trunk_root_comments_path可用,并且我尝试了您提到的几种组合,但我并没有真正感到震惊,因此您提供了帮助。我正在使用Mongo,但实际上没有Trunk模型,我只有一个名为@ root.trunk的根属性,尽管我有一个Trunk控制器,因此它是我的路由的一部分(可能是个不好的主意idk) 。

Thank you Ryan for such a great answer! A very clear explanation of something I was just sort of 'throwing things' at, now at least I understand better. I actually already had 'trunk_root_comments_path' available in my rake routes, and I had tried a couple of the combinations you mentioned, but I wasn't really grocking what I was missing, so you helped. I'm using Mongo and I don't actually have a Trunk model, I just have an attribute on roots called @root.trunk, though I have a trunk controller and therefore its a part of my routes(maybe a bad idea idk).

所以我尝试了您的TLDR并显示错误:

So I tried your TLDR and it said error:

Undefined method 'root_comments_path'

..原因不存在Trunk模型,我想是?..所以我将@ trunk等于正确的ID,与

.. cause no Trunk model exists, I assume?.. so I made @trunk just equal the correct id with

= form_for [@trunk, @root, @comment] do |f| 

<--我得到了'undefined method`politics_root_comments_path'..我很清楚..可能是有道理的..因为我失败了,所以我还必须尝试最明确的版本:

<- and I got 'undefined method `politics_root_comments_path''.. I figured well.. that probably makes sense.. since I'm failing I must as well try your most explicit version:

= form_for @comment, :url => (trunk_root_comments_path(:trunk_id => @root.trunk, :root_id => @root.id)) do |f| 

肯定能奏效...所以我不太确定该怎么做这对我来说奇怪的是,我在路线中具有相同深度的嵌套资源照片,并且我能够使用= form_for [:trunk_root,@photo],:html => {:class =>'root_form'}做| f | ..但出于某种原因我不能..无论如何,我会说您给了我足够的知识以理解100%,但我认为我从20%的理解变成了50 %的理解..我现在知道ID对路由很重要,命名的助手需要访问它们。我对url_helper的工作方式进行了介绍,但是我需要进一步阅读以真正完善它。现在,我也能够以更长的形式构造适当的路线,至少可以度过这种棘手的情况。因此,谢谢您:)

and sure enough that worked... so I'm not quite sure how to do it shorter then this.. the odd thing for me is I have another nested resource "photos" at the same level of depth in the routes and I was able to get that to work with = form_for [:trunk_root, @photo], :html => { :class => 'root_form' } do |f|.. but here for some reason I couldn't.. anyways I'd say you gave me enough to understand 100% but I think I went from 20% understanding to 50% understanding.. I know now that id's ARE important to routes, and the named helpers need access to them. I got an introduction to how the url_helper works, but would need to read more on it to really grock it fully I think. I'm also now able to construct proper routes in their longer form at least to get through tricky situations like this. So thank you :)

推荐答案

TL; DR您需要同时指定:trunk_id 和您URL中的 root_id 或使用 form_for 这样:

TL;DR You need to specify both a :trunk_id and a root_id in your URL or use form_for like this:

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

Rails试图从您提供的哈希值中构建URL,但该哈希值不会t匹配其路由表中的任何内容。您可以这样做:

Rails is attempting to build a URL from the hash you're giving it, but that hash doesn't match anything in its routing table. You could do this:

{ :controller => "comments", :action => "create", :trunk_id => trunk.id, :root_id => root.id }

但这确实有点 tl; dr

更酷的方法是:

trunk_root_comments_path(trunk, root)

其中 trunk root 分别是 Trunk Root 实例。

现在,如果您想成为超级邪恶的酷,请像这样:

Now, if you want to be super-wicked-cool, do it like this:

<%= form_for [trunk, root, comment] do |f| %>

科学!

所以这是如何运作的?小学,亲爱的:

Rails首先认识到我们正在使用 form_for 使用数组, 我们的意思是生意。 Rails使用传入的此数组并从中构建URL。它通过使用路由定义的路由帮助器来完成此任务。不幸的是,您已经以一种有趣的方式定义了您的路线,但效果并不理想,但是不要害怕!我们可以解决这个问题。

Rails first recognises that we're using form_for using an Array and that we mean business. Rails uses this array passed in and builds a URL out of it. It does this by using the routing helpers that are defined by the routes. Unfortunately, you've defined your routes in a funny way that don't play nice with this, but don't fear! We can fix this.

您可以在 config / routes.rb 中找到它:

post '/t/:trunk_id/r/:root_id/comments'

而不是这样:

post '/t/:trunk_id/r/:root_id/comments', :as => "trunk_root_comments"

您可能已经 已经拥有了:

You may alternatively already have this:

match '/t/:trunk_id/r/:root_id/comments', :via => :post

应该成为哪个:

match '/t/:trunk_id/r/:root_id/comments', :via => :post, :as => "trunk_root_comments"

无论哪种方式,您现在都不是一个,而是路线定义的两个(!!) 路径助手。它们分别是 trunk_root_comments_path trunk_root_comments_url 这些方法的名称对于我将要向您解释的内容非常重要。请注意!

Either way, you've now got not one, but two(!!) path helpers defined by the routes. These aretrunk_root_comments_path and trunk_root_comments_url respectively. The names of these methods are super important for what I am about to explain to you. Pay attention!

所以,回到我们的 form_for 小呼叫:

So, back to our little form_for call:

<%= form_for [trunk, root, comment] do |f| %>

Rails知道我们正在使用数组,因为它可以看到它。这个数组的作用可能像魔术一样似乎,但并非如此。

Rails knows that we're using an Array because it can see it. What it does with this Array may seem like magic, but isn't really.

Rails将获取此数组的每个元素,并从不同部分构建一个路由辅助方法 name 。这实际上不是 form_for 的一部分,但可以单独使用另一种称为 url_for 的方法:

Rails will take each element of this array and build a routing helper method name up from the different parts. This isn't actually part of form_for, but another method called url_for that you can use by itself:

 url_for([trunk, root, comment])

开头,由 url_for 生成的此路由帮助器方法名称只是一个空数组( [] )。没什么特别的。

In the beginning, this routing helper method name generated by url_for is simply an empty array ([]). Nothing special at all.

但是然后发生的事情是特殊的!

第一个元素将是 Trunk 类的持久化实例。 持久是指将直接映射到数据库中的记录的对象。是的ORM!

The first element is going to be a persisted instance of the Trunk class. By "persisted" I mean that it's an object that maps directly to a record in the database. Yay ORMs!

Rails会知道这一点,因此会将路由助手转换为: [:trunk]

Rails will know this, and so will turn the routing helper into this: [:trunk].

第二个元素将是 Root 类的持久化实例 。 Rails也知道这一点(该死,Rails是 smart !),然后将其附加到数组中,将其转换为 [:trunk,:root]

The second element is going to be a persisted instance of the Root class. Rails also knows this (damn, Rails is smart!) and will then append this to the array, turning it into [:trunk, :root]. Awesome.

Rails然后检查第三个(也是最后一个)元素。它会发现(在这种情况下)它是一个非持久性元素,即尚未保存到数据库中。 Rails对此进行了不同的处理,而是将 [:comments] 追加到数组,并将其转换为:

The third (and final) element is then checked by Rails. It sees that (in this case) it's a non-persisted element, i.e. it's not been saved to the database.. yet. Rails treats this differently and will instead append [:comments] to the array, turning it into this:

[:trunk, :root, :comments]

看看我在哪里

现在,Rails已经完成了它的工作(或者, thang ,如果您愿意的话),它将加入这三个部分像这样: trunk_root_comments ,并且为了很好的衡量,它会在其末尾放置 _path 并将其翻转进入最终的 trunk_root_comments_path 助手。

Now that Rails has done it's thing (or thang, if you like) it will join these three parts together like this: trunk_root_comments, and just for good measure it'll put _path on the end of it, turning it into the final trunk_root_comments_path helper.

然后!伙计,然后... Rails调用此方法并传递参数!就像这样:

And then! Man, and then... Rails calls this method and passes it arguments! Just like this:

trunk_root_comments_path(:trunk_id => trunk.id, :root_id => root_id)

这将生成资源的完整路径,如下所示:

This generates a full path to the resource like this:

/t/:trunk_id/r/:root_id/comments

bam!整圈!这就是Rails知道如何生成URL的方式,您不必再使用丑陋的哈希值。

And bam! Full circle! That's how Rails will know to generate the URL and you don't have to use ugly hashes anymore.

成功!

这篇关于嵌套form_for的Rails路由错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆