How to Have Form Contents Submitted to Another Action?

I have a form auto generated like this :

<% form_for(@role) do |f| %>
  <p>
    <b>Rolename</b><br />
    <%= f.text_field :rolename %>
  </p>
<b>Level</b><br />
    <%= f.text_field :level %>
  </p>
  <%= f.submit "Update" %>
   <%= link_to(image_tag("Simple_Buttons/Update.png", :class =>
"generic_button"),{:controller=>'roles', :action=>'modify',
:id=>@role})%>
  </p>
<% end %>

As you can see that there are two submit buttons 1) is the default
button that goes to update method in the controller and the other is the
image button link that points to a specific method (in this case modify
instead of update).

The problem with the second button is that :level field is not picked up
at all. Why is that happening ? Here is my update and modify which are
the same :

  def modify
    @role = Role.find(params[:id])
    logger.debug(">>>>>>modify role name #{@role.rolename} ; level
#{@role.level}" )
    respond_to do |format|
      if @role.update_attributes(params[:role])
      logger.debug(">>>>>>>>after if role name #{@role.rolename} ; level
#{@role.level}")
        flash[:notice] = 'Role was successfully updated.'
        format.html { redirect_to(@role) }
        format.xml { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml { render :xml => @role.errors, :status =>
:unprocessable_entity }
      end
    end
  end

Pretty auto generated. Nothing fancy. What am I doing wrong here?

Ather Shiraz wrote:

I have a form auto generated like this :

<% form_for(@role) do |f| %>
  <p>
    <b>Rolename</b><br />
    <%= f.text_field :rolename %>
  </p>
<b>Level</b><br />
    <%= f.text_field :level %>
  </p>
  <%= f.submit "Update" %>
   <%= link_to(image_tag("Simple_Buttons/Update.png", :class =>
"generic_button"),{:controller=>'roles', :action=>'modify',
:id=>@role})%>
  </p>
<% end %>

As you can see that there are two submit buttons 1) is the default
button that goes to update method in the controller and the other is the
image button link that points to a specific method (in this case modify
instead of update).

The problem with the second button is that :level field is not picked up
at all. Why is that happening ? Here is my update and modify which are
the same :

  def modify
    @role = Role.find(params[:id])
    logger.debug(">>>>>>modify role name #{@role.rolename} ; level
#{@role.level}" )
    respond_to do |format|
      if @role.update_attributes(params[:role])
      logger.debug(">>>>>>>>after if role name #{@role.rolename} ; level
#{@role.level}")
        flash[:notice] = 'Role was successfully updated.'
        format.html { redirect_to(@role) }
        format.xml { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml { render :xml => @role.errors, :status =>
:unprocessable_entity }
      end
    end
  end

Pretty auto generated. Nothing fancy. What am I doing wrong here?

You are sticking a link (<a href="..."><img src="foo.jpg" /></a>) in a
form, and expecting the form to submit when you click it. This is not
how HTML forms work.

So you want to trigger 2 different actions depending which button is
clicked? The problem is that the form is set to go to a sepcific URL,
regardless of what you do in that form. The form tag html itself has an
"action" attribute that is the url the form will post to. To change
that URL, you would need some sort of javascript.

  <%= submit_tag 'Modify', :onclick => "$('myform').action =
'/my/alt/submit/url'; $('myform').submit(); return false" %>

But a cleaner way, at least I think this works, is to simply have them
handled by the same action.

  <%= submit_tag 'Update' %>
  <%= submit_tag 'Modify' %>

When your form gets submitted, you have a params[:commit] that will
either contain 'Update' or 'Modify'. Do what you need based on that.

I'm not sure how that works with an image based form submit button
though. But you would create such beast with a:

  <%= image_submit_tag 'image/url.jpg' %>

instead of a link_to.

So you want to trigger 2 different actions depending which button is
clicked?

No. I just want the form to submit to ONE method which is "modify"
instead of "update" so I dont want two actions I just want one of them.
I dont want the default action going to update. I would like it to point
to the modify method please.

The problem is that the form is set to go to a sepcific URL,
regardless of what you do in that form. The form tag html itself has an
"action" attribute that is the url the form will post to. To change
that URL, you would need some sort of javascript.

Thanks for the hint . I went to :
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html
and I tried <%form_for :role,@role, :url=> {:action=>"modify" } do |f|%>

However it gives me the following error[1]. ("couldnt find role without
an ID")

Now the exact same code when I put it in "update" method of the
controller it updates fine without giving this error [1] Maybe I need to
pass some variable :id in the url above?

Again my view looks like this :

<h1>Editing role</h1>
<% form_for(@role) do |f| %>
  <p>
    <b>Rolename</b><br />
    <%= f.text_field :rolename %>
  </p>
  <p>
    <b>Level</b><br />
    <%= f.text_field :level %>
  </p>
  <p>
<%= image_submit_tag("Simple_Buttons/Update.png") %>
  </p>
<% end %>

And I would like the following method to trigger (which works fine in
update) :

  def modify
    @role = Role.find(params[:id])
    logger.debug(">>>>>>inside modify role name #{@role.rolename} ;
level #{@role.level}" )
    respond_to do |format|
      if @role.update_attributes(params[:role])
      logger.debug(">>>>>>>> inside modify after if role name
#{@role.rolename} ; level #{@role.level}")
        flash[:notice] = 'Role was successfully updated.'
        format.html { redirect_to(@role) }
        format.xml { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml { render :xml => @role.errors, :status =>
:unprocessable_entity }
      end
    end
  end
[1]
ActiveRecord::RecordNotFound in RolesController#modify

Couldn't find Role without an ID

RAILS_ROOT: C:/ruby/letter4sure
Application Trace | Framework Trace | Full Trace

c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1248:in
`find_from_ids'
c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:504:in
`find'
app/controllers/roles_controller.rb:47:in `modify'
-e:2:in `load'
-e:2

c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1248:in
`find_from_ids'
c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:504:in
`find'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:1158:in
`send'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:1158:in
`perform_action_without_filters'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:697:in
`call_filters'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:689:in
`perform_action_without_benchmark'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/benchmarking.rb:68:in
`perform_action_without_rescue'
c:/ruby/lib/ruby/1.8/benchmark.rb:293:in `measure'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/benchmarking.rb:68:in
`perform_action_without_rescue'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/rescue.rb:199:in
`perform_action_without_caching'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/caching.rb:678:in
`perform_action'
c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/query_cache.rb:33:in
`cache'
c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/query_cache.rb:8:in
`cache'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/caching.rb:677:in
`perform_action'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:524:in
`send'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:524:in
`process_without_filters'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:685:in
`process_without_session_management_support'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/session_management.rb:123:in
`process'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:388:in
`process'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:171:in
`handle_request'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:115:in
`dispatch'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:126:in
`dispatch_cgi'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:9:in
`dispatch'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel/rails.rb:76:in
`process'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel/rails.rb:74:in
`synchronize'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel/rails.rb:74:in
`process'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel.rb:159:in
`process_client'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel.rb:158:in
`each'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel.rb:158:in
`process_client'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel.rb:285:in
`run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel.rb:285:in
`initialize'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel.rb:285:in
`new'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel.rb:285:in
`run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel.rb:268:in
`initialize'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel.rb:268:in
`new'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel.rb:268:in
`run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel/configurator.rb:282:in
`run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel/configurator.rb:281:in
`each'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel/configurator.rb:281:in
`run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/bin/mongrel_rails:128:in
`run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel/command.rb:212:in
`run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/bin/mongrel_rails:281
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:489:in
`load'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:489:in
`load'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:342:in
`new_constants_in'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:489:in
`load'
c:/ruby/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/commands/servers/mongrel.rb:64
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in
`gem_original_require'
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in
`require'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:496:in
`require'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:342:in
`new_constants_in'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:496:in
`require'
c:/ruby/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/commands/server.rb:39
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in
`gem_original_require'
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in
`require'
script/server:3

c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1248:in
`find_from_ids'
c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:504:in
`find'
app/controllers/roles_controller.rb:47:in `modify'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:1158:in
`send'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:1158:in
`perform_action_without_filters'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:697:in
`call_filters'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:689:in
`perform_action_without_benchmark'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/benchmarking.rb:68:in
`perform_action_without_rescue'
c:/ruby/lib/ruby/1.8/benchmark.rb:293:in `measure'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/benchmarking.rb:68:in
`perform_action_without_rescue'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/rescue.rb:199:in
`perform_action_without_caching'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/caching.rb:678:in
`perform_action'
c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/query_cache.rb:33:in
`cache'
c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/query_cache.rb:8:in
`cache'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/caching.rb:677:in
`perform_action'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:524:in
`send'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:524:in
`process_without_filters'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:685:in
`process_without_session_management_support'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/session_management.rb:123:in
`process'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:388:in
`process'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:171:in
`handle_request'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:115:in
`dispatch'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:126:in
`dispatch_cgi'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:9:in
`dispatch'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel/rails.rb:76:in
`process'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel/rails.rb:74:in
`synchronize'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel/rails.rb:74:in
`process'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel.rb:159:in
`process_client'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel.rb:158:in
`each'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel.rb:158:in
`process_client'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel.rb:285:in
`run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel.rb:285:in
`initialize'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel.rb:285:in
`new'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel.rb:285:in
`run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel.rb:268:in
`initialize'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel.rb:268:in
`new'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel.rb:268:in
`run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel/configurator.rb:282:in
`run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel/configurator.rb:281:in
`each'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel/configurator.rb:281:in
`run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/bin/mongrel_rails:128:in
`run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/lib/mongrel/command.rb:212:in
`run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.1.4-x86-mswin32-60/bin/mongrel_rails:281
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:489:in
`load'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:489:in
`load'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:342:in
`new_constants_in'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:489:in
`load'
c:/ruby/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/commands/servers/mongrel.rb:64
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in
`gem_original_require'
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in
`require'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:496:in
`require'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:342:in
`new_constants_in'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:496:in
`require'
c:/ruby/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/commands/server.rb:39
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in
`gem_original_require'
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in
`require'
script/server:3
-e:2:in `load'
-e:2

Request

Parameters:

{"x"=>"46",
"y"=>"26",
"authenticity_token"=>"68408397cd9117caeecac0da1f3b771a69457a9d",
"role"=>{"level"=>"10005",
"rolename"=>"Administrator"}}

Show session dump

Ather Shiraz wrote:

So you want to trigger 2 different actions depending which button is
clicked?

No. I just want the form to submit to ONE method which is "modify"
instead of "update" so I dont want two actions I just want one of them.
I dont want the default action going to update. I would like it to point
to the modify method please.

The problem is that the form is set to go to a sepcific URL,
regardless of what you do in that form. The form tag html itself has an
"action" attribute that is the url the form will post to. To change
that URL, you would need some sort of javascript.

Thanks for the hint . I went to :
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html
and I tried <%form_for :role,@role, :url=> {:action=>"modify" } do |f|%>

However it gives me the following error[1]. ("couldnt find role without
an ID")

Well, that url does not give the id of the record you are modifying. So

  Role.find(params[:id])

fails. Try:

  <% form_for :role,@role, :url=> {:action=>"modify", :id => @role} do