Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6945953
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T13:30:08+00:00 2026-05-27T13:30:08+00:00

I now this has been asked a thousand times but that doesn’t help me

  • 0

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

my rake routes:

                   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"}

The error:

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

If I name space the form to:

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

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..

UPDATE:

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).

So I tried your TLDR and it said error:

Undefined method 'root_comments_path'

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

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

<- 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| 

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 🙂

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T13:30:09+00:00Added an answer on May 27, 2026 at 1:30 pm

    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 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 }
    

    But that’s really a bit tl;dr.

    The cooler way to do it is this:

    trunk_root_comments_path(trunk, root)
    

    Where trunk and root are Trunk and Root instances respectively.

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

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

    Science!

    So how does this work? Elementary, my dear:

    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.

    The way you can do it is this where you have this in config/routes.rb:

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

    Instead put this:

    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
    

    Which should become this:

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

    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!

    So, back to our little form_for call:

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

    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 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])
    

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

    But then what happens is special!

    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 will know this, and so will turn the routing helper into this: [:trunk].

    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.

    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]
    

    See where I’m going with this now?

    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.

    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
    

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

    Success!

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Well I guess this has been asked a thousand times, but for some reason
Now I know this has been asked a few times, but i'm still not
This has probably been asked a thousand times... But i'm sure i have all
Now I know this has been asked before. But I've made doubly sure that
Now this question has been asked before but I am not able to get
I know this has been asked many times but its been more for MVC1.
I know this has been asked a few times here. But none of the
This has been asked a couple of times, but none provide coded test cases.
This question has been asked, in one form or another, a dozen times here,
I'm sure this question has been asked many times, but I can't figure this

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.