Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Problem with scoped routes and form_for helper

#6736

I have a route that looks like this:

  namespace :admin do
    scope ':project_name' do
      resources :submissions
    end
  end

in the application controller I have a before_filter method that will get @project based on this project_name.

In my submissions#new form I have the following

  = form_for admin_submission_path(@project.name, @submission), :html => { :multipart => true } do |f|

What I get is a ActionController::RoutingError that spits this out:

No route matches {:action=>"show", :controller=>"admin/submissions", :project_name=>"someproject", :id=>#<Submission id: nil, state: "pending", photo: nil, created_at: nil, updated_at: nil, project_id: 1, description: nil>}

Here's a snippet of the framework trace:

actionpack (3.0.7) lib/action_dispatch/routing/route_set.rb:425:in `raise_routing_error'
actionpack (3.0.7) lib/action_dispatch/routing/route_set.rb:398:in `generate'
actionpack (3.0.7) lib/action_dispatch/routing/route_set.rb:454:in `generate'
actionpack (3.0.7) lib/action_dispatch/routing/route_set.rb:482:in `url_for'
actionpack (3.0.7) lib/action_dispatch/routing/url_for.rb:131:in `url_for'
actionpack (3.0.7) lib/action_view/helpers/url_helper.rb:99:in `url_for'
actionpack (3.0.7) lib/action_dispatch/routing/route_set.rb:195:in `admin_submission_path'
actionpack (3.0.7) lib/action_view/template.rb:135:in `block in render'

It looks like when I use a dynamic scope, the url_for helper can't generate the correct path.

Reported by Jack Chu · April 22nd, 2011 @ 01:09 AM

State: invalid
Milestone: none
Assigned to: nobody
Importance: Low

Activity

  1. Andrew White
    Andrew White
    • State changed from new to invalid
    • Importance changed from to Low

    The error you're getting is because the @submission variable is a new record and the admin_submission_path url helper is expecting a value for :id. You're also using form_for in the wrong way - even if the url helper worked, the form_for helper would fail as you're not passing the correct arguments.

    Reading the form helper guide should help make things clearer.

    April 22nd, 2011 @ 06:13 AM

  2. Jack Chu
    Jack Chu

    Andrew, thanks for your reply.

    I looked over the guide and that helped me with the proper arguments for form_for, however I can't find a good example of how to use form_for and scoped routes anywhere. I also wanted it to handle both create/update at the same time (so it can be used in a _form partial for example). Maybe you should add a section with dealing with scopes after the "Dealing with Namespaces" section.

    For anyone with the same issue, from looking at the form_for api and guide, this seems to the way to handle it:

    = form_for @submission, :url => @submission.new_record? ? submissions_path(@project.name) : submission_path(@project.name, @submission), :html => { :multipart => true } do |f|
    

    Ternary operator in the url value checks to see if @submission is a new record and returns a create or edit path accordingly.

    April 22nd, 2011 @ 07:26 PM

  3. Jack Chu
    Jack Chu

    Oops, I just noticed the API seems to prefer #persisted? to #new_record?, so I guess this works better:

    = form_for @submission, :url => @submission.persisted? ? submission_path(@project.name, @submission) : submissions_path(@project.name), :html => { :multipart => true } do |f|
    

    April 22nd, 2011 @ 07:42 PM