REST bug with form_for

Hi all, I am running on Windows XP sp2 with ruby 1.8.6, and rails
1.2.3

I am using REST, and have this in my view

<% form_for(:project,
:url => project_path(:user_id => @project.my_user, :id =>
@project),
:html => {:method => :put}) do |f| %>

The browser correctly gives

But yet when I hit the Submit button to update, I get this error:

project_url failed to generate from
{:controller=>“projects”, :user_id=>nil, :action=>“show”, :id=>“1”},
expected: {:controller=>“projects”, :action=>“show”}, diff:
{:user_id=>nil, :id=>“1”}

Something is very wrong, because the routing should be sending it to
the update – not the show action.

My guess is that this is a Windows specific bug.
Please advise.

Can you show your routes.rb file?

Here’s routes.rb (note that the commented out streamlined version
doesn’t help):

ActionController::Routing::Routes.draw do |map|

map.resources :users, :collection => {:login => :get, :confirm_login
=> :post} do | user |
user.resources :projects do | project |
project.resources :calendar_entries, :to_do_items
project.resources :research_items do | research_item |
research_item.resources :url_links
end
end
end

map.resources :users do | users |

users.resources :projects

end

end

My guess is that this is a Windows specific bug.

99% of the time in a programming language, bugs are NOT OS SPECIFIC.

Show us the controller code for the action that it’s posting to please.
Somewhere in there you’re not setting a user_id object correctly.

On Dec 5, 2007 7:20 AM, Paul D. [email protected] wrote:

 project.resources :calendar_entries, :to_do_items

{:controller=>“projects”, :user_id=>nil, :action=>“show”, :id=>“1”},


Ryan B.

Furthermore, using a breakpoint called from controller.temp1() in
\views\projects\edit.rhtml:

<% form_for(:project,
:url => project_path(:user_id => @project.my_user, :id =>
@project),
:html => {:method => :put}) do |f| %>
<% controller.temp1() %>

wherein projects_controller.rb,

def temp1()
breakpoint()
end

The url works just fine giving me “/users/2/projects/1” as follows:

Executing break point at C:/SVNWorkingCopy/app/controllers/
projects_controller.rb:8 in `temp1’
irb(#ProjectsController:0x4867e9c):001:0> project_path(:user_id =>
@project.my_user, :id => @project)
=> “/users/2/projects/1”
irb(#ProjectsController:0x4867e9c):002:0>

=========================

Ok, here’s projects_controller.rb:

=========================
class ProjectsController < ApplicationController

live_tree(
:project_tree,
:model => :project)

def temp1()
#breakpoint()
end

GET /users/1/projects

GET /users/1/projects.xml

def index
find_user_from_params()
find_parent()
@child_projects = projects_sorted_by_title()
end

GET /users/1/projects/1

GET /users/1/projects/1.xml

def show
find_project_and_parent()
end

GET /users/1/projects/new

def new
find_parent()
@project = Project.new
end

GET /users/1/projects/1;edit

def edit
find_project()
#@user = @project.my_user
#breakpoint()
end

POST /users/1/projects

POST /users/1/projects.xml

def create
find_parent()
@project = Project.new(params[:project])
@user.add_child_to_parent_project(@project, @parent_project)

if @project.save
  flash[:notice] = 'Project was successfully created.'
  redirect_to project_url(:user_id => @user, :id => @project)
else
  render :action => "new"
end

end

PUT /users/1/projects/1

PUT /users/1/projects/1.xml

def update
find_project()
if @project.update_attributes(params[:project])
flash[:notice] = ‘Project was successfully updated.’
redirect_to project_url(:user_id => @user, :id => @project)
else
render :action => “edit”
end
end

DELETE /users/1/projects/1

DELETE /users/1/projects/1.xml

def destroy
find_project_and_parent()
find_user()
@project.my_user.remove_child_project(@project)
@project.destroy()
redirect_to projects_url(:parent_project_id =>
@parent_project, :user_id => @user)
end

private

def find_user_from_params()
an_id = params[:user_id]
redirect_to login_users_url unless an_id
@user = User.find(an_id)
end

def find_project()
@project = Project.find(params[:id])
end

def find_project_and_parent()
find_project()
@parent_project = @project.parent
end

def find_parent()
an_id = params[:parent_project_id]
@parent_project = ((an_id.nil?) ? nil : Project.find(an_id))
end

def projects_sorted_by_title()

@user.children_for_parent_project__sorted_by_title(@parent_project)
end

end

And while we’re at it, here’s application.rb:

=========================

Filters added to this controller apply to all controllers in the

application.

Likewise, all the methods added will be available for all

controllers.

class ApplicationController < ActionController::Base

Pick a unique cookie name to distinguish our session data from

others’
session :session_key => ‘_pjd1_session_id’

end

=========================

the project_url is also called on the redirect from the update
method.

it does not look like you are setting the @user variable in that
method.

daniel

Yup, that was it.
I should have put a break in the update method to see if it was
getting there.
Thanks all.