form_for with RESTful route calling the wrong action

Hi,

I am using RESTFUL routes with the following setup with a form_for tag,
but instead of calling the :create action my form is calling the :new
action. I have read and re-read the resources documentation, and I am
confident that I have the right combination of paths, and posting
methods, please take a look at this setup and let me know if I'm doing
something stupid or if this is an error w/rails routing.

,----[environment.rb]

# Specifies gem version of Rails to use when vendor/rails is not present
RAILS_GEM_VERSION = '2.1.0' unless defined? RAILS_GEM_VERSION

`----

,----[processing_service_levels/new.html.erb]

    <% form_for(:processing_service_levels, @level,
                :url => processing_service_level_path(@level),
                :html => { :method => :post}) do |f| %>

`----

,----[routes.rb]

  map.resources :processing_service_levels

`----

,----[processing_service_levels_controller.rb]

  # POST /processing_service_levels
  # POST /processing_service_levels.xml
  def create
    @level = ProcessingServiceLevel.new(params[:id])
    @level.process_hours = (Integer(params[:months]) * 30 * 24) +
      (Integer(params[:days]) * 24) + Integer(params[:hours])
    respond_to do |format|
      if @level.save
        flash[:notice] = 'Service level was successfully created.'
...

`----

,----[rendered html]

    <form action="/processing_service_levels/" method="post">
    ... form stuff ...
    <input name="commit" type="submit" value="Create" />

`----

I've restarted with web-server since adding the map.resources line to my
routes. I've tried specifying the path using the old style

:url => {:controller => :processing_service_levels, :action => :create, :id => @level}

but with no success. I've googled, and searched the archives of this
list, but I have had no success in finding out what's going wrong.

Please help me out!

Thanks -- Eric

inline...

Hi,

I am using RESTFUL routes with the following setup with a form_for tag,
but instead of calling the :create action my form is calling the :new
action. I have read and re-read the resources documentation, and I am
confident that I have the right combination of paths, and posting
methods, please take a look at this setup and let me know if I'm doing
something stupid or if this is an error w/rails routing.

,----[environment.rb]
> # Specifies gem version of Rails to use when vendor/rails is not present
> RAILS_GEM_VERSION = '2.1.0' unless defined? RAILS_GEM_VERSION
`----

What code do you have in your controller? It should be something like
this:

class ProcessingServiceLevelsController < ApplicationController

  def new
    @processing_service_level = ProcessingServiceLevel.new
  end

end

,----[processing_service_levels/new.html.erb]
> <% form_for(:processing_service_levels, @level,
> :url => processing_service_level_path(@level),
> :html => { :method => :post}) do |f| %>
`----

Given the above controller code, you can use this instead:

<% form_for @processing_service_level do |f| %>

That should create a POST action to /processing_service_levels, which
should call your create action.

Last resort, try restarting your web server (mongrel or webrick or
whatever).

Jeff

purpleworkshops.coom

inline...

Jeff <cohen.jeff@gmail.com> writes:

inline...

Hi,

I am using RESTFUL routes with the following setup with a form_for tag,
but instead of calling the :create action my form is calling the :new
action. I have read and re-read the resources documentation, and I am
confident that I have the right combination of paths, and posting
methods, please take a look at this setup and let me know if I'm doing
something stupid or if this is an error w/rails routing.

,----[environment.rb]
> # Specifies gem version of Rails to use when vendor/rails is not present
> RAILS_GEM_VERSION = '2.1.0' unless defined? RAILS_GEM_VERSION
`----

What code do you have in your controller? It should be something like
this:

class ProcessingServiceLevelsController < ApplicationController

  def new
    @processing_service_level = ProcessingServiceLevel.new
  end

end

the relevant methods in my processing_service_levels_controller.rb are

  # GET /processing_service_levels/new
  # GET /processing_service_levels/new.xml
  def new
    @processing_service_level = ProcessingServiceLevel.new
    @version = ProcessingServiceVersion.find(params[:version])
    @parent = @version.processing_service
    respond_to do |format|
      format.html # new.html.erb
      format.xml { render :json => @level }
    end
  end

  # POST /processing_service_levels
  # POST /processing_service_levels.xml
  def create
    @level = ProcessingServiceLevel.new(params[:id])
    @level.process_hours = (Integer(params[:months]) * 30 * 24) +
      (Integer(params[:days]) * 24) + Integer(params[:hours])
    respond_to do |format|
      if @level.save
        flash[:notice] = 'Service level was successfully created.'
        format.html { redirect_to(:controller => :processing_service_versions,
                                  :action => :show,
                                  :id => @version,
                                  :parent => @parent,
                                  :level => @level) }
        format.xml { render :json => @service, :status => :created, :location => @level }
      else
        format.html { render(:action => "new",
                             :version => @level.processing_service_version,
                             :parent => @level.processing_service_version.processing_service) }
        format.xml { render :json => @level.errors, :status => :unprocessable_entity }
      end
    end
  end

not that the create method has ever successfully been called :wink:

,----[processing_service_levels/new.html.erb]
> <% form_for(:processing_service_levels, @level,
> :url => processing_service_level_path(@level),
> :html => { :method => :post}) do |f| %>
`----

Given the above controller code, you can use this instead:

<% form_for @processing_service_level do |f| %>

I switched to the form_for argument you suggested, which renders to the
following html

  <form action="/processing_service_levels" class="new_processing_service_level" id="new_processing_service_level" method="post">

>
That should create a POST action to /processing_service_levels, which
should call your create action.

Is there a way to inspect which method (put, post, get etc...) is being sent?

When I submit this form I am still directed to the
processing_service_controllers/new action. I'm really not clear on
what's going on, and why this one particular model has issues when all
of my other models are working fine. Also the
processing_service_levels/edit form is submitting to the edit actions
instead of update.

Last resort, try restarting your web server (mongrel or webrick or
whatever).

I've been restarting my web-server after almost every change.

Thanks for the advice, if you have any other ideas please let me know -- Eric

Are you sure it's just not being redirected? If the .save fails
inside the create() action, it looks like the code will render the new
form again - so perhaps it's been misleading?

Can you check the development.log, and see if the #create action is
really ever getting called? At the end of the "Processing..." line in
the log, you should see "[POST]" to confirm that the POST method is
being used.

Sorry if you've already checked all this... just trying to think of
what to try next.

Jeff

Jeff <cohen.jeff@gmail.com> writes:

Is there a way to inspect which method (put, post, get etc...) is being sent?

When I submit this form I am still directed to the
processing_service_controllers/new action. I'm really not clear on
what's going on, and why this one particular model has issues when all
of my other models are working fine. Also the
processing_service_levels/edit form is submitting to the edit actions
instead of update.

Are you sure it's just not being redirected? If the .save fails
inside the create() action, it looks like the code will render the new
form again - so perhaps it's been misleading?

Can you check the development.log, and see if the #create action is
really ever getting called? At the end of the "Processing..." line in
the log, you should see "[POST]" to confirm that the POST method is
being used.

Thank for the help Jeff,

I checked the logs, and immediately after rendering the
processing_service_levels/new page, the next line is

Processing ProcessingServiceLevelsController#new (for 127.0.0.1 at 2008-10-07 13:55:32) [GET]

for more of the log see [1] below

which leads me to believe that the form is submitting directly to the
new action using GET. I don't see how this could be the case given the
raw html of the "new" page, unless maybe something is twisted inside of
the rails routing...

I've also tried sticking error raising code in the from of the udpate
action, but said code is never reached...

Thanks -- Eric

Sorry if you've already checked all this... just trying to think of
what to try next.

Jeff

[1]
,----[development log]

Processing ProcessingServiceLevelsController#new (for 127.0.0.1 at 2008-10-07 13:55:25) [GET]
  Session ID: f69ec3fdb850969c52d3e6173df8e72e
  Parameters: {"action"=>"new", "version"=>"20", "controller"=>"processing_service_levels"}
  User Columns (0.9ms) SHOW FIELDS FROM `users`
  User Load (0.1ms) SELECT * FROM `users` WHERE (`users`.`id` = 5) LIMIT 1
  ProcessingServiceLevel Columns (0.9ms) SHOW FIELDS FROM `processing_service_levels`
  ProcessingServiceVersion Columns (0.8ms) SHOW FIELDS FROM `processing_service_versions`
  ProcessingServiceVersion Load (0.1ms) SELECT * FROM `processing_service_versions` WHERE (`processing_service_versions`.`id` = 20)
  ProcessingService Columns (0.8ms) SHOW FIELDS FROM `processing_services`
  ProcessingService Load (0.1ms) SELECT * FROM `processing_services` WHERE (`processing_services`.`id` = 3)
Rendering template within layouts/application
Rendering processing_service_levels/new
Rendered processing_services/_processing_service (3.7ms)
Rendered processing_service_versions/_processing_service_version (3.7ms)
Rendered processing_service_levels/_form (4.0ms)
Rendered users/_user_bar (3.3ms)
Completed in 130ms (View: 35, DB: 4) | 200 OK [http://localhost/processing_service_levels/new?version=20]

Processing ProcessingServiceLevelsController#new (for 127.0.0.1 at 2008-10-07 13:55:32) [GET]
  Session ID: f69ec3fdb850969c52d3e6173df8e72e
  Parameters: {"month"=>"0", "commit"=>"Create", "processing_service_level"=>{"name"=>"Nothing", "description"=>"Nothing", "processing_service_version_id"=>"20"}, "hour"=>"0", "authenticity_token"=>***, "action"=>"new", "day"=>"0", "controller"=>"processing_service_levels"}
  User Columns (1.1ms) SHOW FIELDS FROM `users`
  User Load (0.1ms) SELECT * FROM `users` WHERE (`users`.`id` = 5) LIMIT 1
  ProcessingServiceLevel Columns (1.1ms) SHOW FIELDS FROM `processing_service_levels`

`----

Could your browser cache be screwing with you maybe? Any difference if you switch to a different browser?

My bad,

it looks like the creation form was nested inside of empty <form></form>
tags. These surrounding tags, must have been what was breaking the
submit action to GET rather than POST. I removed these tags and it
appears to be working.

Thanks for the help! Sorry about the noise -- Eric

"Eric Schulte" <schulte.eric@gmail.com> writes: