我现在已经被问了一千次但这对我没有帮助嘿:)我已经在这一个小时了。我的表格:
= 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|
应该根据rake路线制作路线trunk_root_comments_path ..这是正确的..我得到:
No route matches {:controller=>"comments", :format=>nil}
非常感谢帮助..已经看了好几个小时..
更新:
谢谢Ryan这么棒的答案!一个非常明确的解释,我只是“扔东西”,现在至少我理解得更好。我实际上已经在我的佣金路线中提供了'trunk_root_comments_path',并且我尝试过你提到的几种组合,但我并没有真正讨厌我所缺少的东西,所以你帮了忙。我正在使用Mongo,我实际上没有Trunk模型,我只有一个名为@root.trunk的根属性,虽然我有一个中继控制器,因此它是我的路由的一部分(也许是一个坏主意idk) 。
所以我尝试了你的TLDR,它说错误:
Undefined method 'root_comments_path'
..因为没有Trunk模型存在,我假设?..所以我让@trunk等于正确的id
= form_for [@trunk, @root, @comment] do |f|
&lt; - 我得到'未定义的方法`politics_root_comments_path''..我认为......这可能是有道理的......因为我失败了我必须尝试你最明确的版本:
= form_for @comment, :url => (trunk_root_comments_path(:trunk_id => @root.trunk, :root_id => @root.id)) do |f|
并且确实有效......所以我不太确定如何做到这一点......对我来说奇怪的是我在路线的同一深度处有另一个嵌套资源“照片”我能够使用= form_for [:trunk_root,@ photo],:html =&gt; {:class =&gt; 'root_form'}做| f | ..但是由于某种原因,我不能......反正我会说你给了我足够的理解100%,但我想我从20%的理解到50%的理解..我现在知道id对路由很重要,而命名的助手需要访问它们。我介绍了url_helper的工作原理,但是我需要阅读更多信息,以便充分了解它。我现在也能够以更长的形式构建适当的路线,至少可以解决这种棘手的情况。谢谢你:)。
答案 0 :(得分:10)
TL; DR您需要在网址中指定:trunk_id
和root_id
,或者像这样使用form_for
:
<%= form_for [@trunk, @root, @comment] do |f| %>
Rails正在尝试从您提供的哈希中构建一个URL,但该哈希与其路由表中的任何内容都不匹配。你可以这样做:
{ :controller => "comments", :action => "create", :trunk_id => trunk.id, :root_id => root.id }
但那确实有点 tl; dr 。
更酷的方法是:
trunk_root_comments_path(trunk, root)
trunk
和root
分别是Trunk
和Root
个实例。
现在,如果你想成为 super-wicked-cool ,那就这样做:
<%= form_for [trunk, root, comment] do |f| %>
科学!
那么这是如何工作的?小学,亲爱的:
Rails首先认识到我们正在使用form_for
使用数组,我们指的是业务。 Rails使用传入的数组并从中构建一个URL。它通过使用路由定义的路由助手来实现。不幸的是,你已经用一种有趣的方式定义了你的路线,但这并不好玩,但不要害怕!我们可以解决这个问题。
您可以通过config/routes.rb
:
post '/t/:trunk_id/r/:root_id/comments'
取而代之的是:
post '/t/:trunk_id/r/:root_id/comments', :as => "trunk_root_comments"
你可以或已经拥有:
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
。 这些方法的名称对于我要向您解释的内容非常重要。注意!
所以,回到我们的小form_for
电话:
<%= form_for [trunk, root, comment] do |f| %>
Rails知道我们正在使用数组,因为它可以看到它。它对这个数组的作用可能似乎就像魔法一样,但事实并非如此。
Rails将获取此数组的每个元素,并从不同的部分构建路由助手方法 name 。这实际上不是form_for
的一部分,而是另一种名为url_for
的方法,可以单独使用:
url_for([trunk, root, comment])
最初,url_for
生成的路由助手方法名称只是一个空数组([]
)。没什么特别的。
但接下来发生的事情是特别的!
第一个元素将是Trunk
类的持久化实例。通过“持久化”,我的意思是它是一个将直接映射到数据库中的记录的对象。是的ORMs!
Rails会知道这一点,因此会将路由助手变为:[:trunk]
。
第二个元素将是Root
类的持久化实例。 Rails也知道这个(该死的,Rails是 smart !)然后将它附加到数组,将其转换为[:trunk, :root]
。真棒。
然后Rails检查第三个(也是最后一个)元素。它看到(在这种情况下)它是一个非持久化元素,即它尚未保存到数据库中。 Rails以不同的方式对待它,而是将[:comments]
附加到数组,将其转换为:
[:trunk, :root, :comments]
现在看看我现在要去哪里?
现在Rails做了它的事情(或 thang ,如果你愿意的话)它将这三个部分加在一起:trunk_root_comments
,只是为了好的措施它会放最后_path
,将其转变为最终的trunk_root_comments_path
帮助者。
然后!男人,然后...... Rails调用这个方法并传递参数!就像这样:
trunk_root_comments_path(:trunk_id => trunk.id, :root_id => root_id)
这会生成资源的完整路径,如下所示:
/t/:trunk_id/r/:root_id/comments
bam!全圈!这就是Rails知道生成URL的方式,你不必再使用丑陋的哈希了。
成功!
答案 1 :(得分:0)
不确定您是否设置了此路线,但请尝试:
= form_for @comment, :url => trunk_root_comments_path