How does f.submit work?

Hello everyone,

I’m learning rails with Agile Web Development with Rails book. Right now I’m doing example from chapter 11 where they create interface for adding new users. I wrote all code exactly as it is in the book. However, I’m having a problem – once I hit “Add User” button, the page is just redirected to the list of users and the user is not actually added. I’m trying to diagnose the problem. The code they have for the button is

<%= f.submit "Add User" , :class => "submit" %>

This ends up generating this HTML:

<input class="submit" id="user_submit" name="commit" type="submit" value="Add User" />

What I’m trying to userstand is what happens once this button is clicked. There’s no action in the controller called “submit”. However, there are actions new/edit/create and update. Is “submit” some kind of special action which redirects to of of these CRUD methods? The book doesn’t explain that. I’m using Rails 2.1.0.

Any feedback would be appreciated,
Thanks.

Hi,

can I take it you’re using the third edition of Agile Web Development? I have the second edition so the code is different.

Could you post the code from your add_user action?

This is a basic html thing, submit sends the data from the current form to the address specified by that form’s action. By default, POST is used.

<form action=“/users”>
<input type=“submit” value =“send now!” />
</form>

Clicking that button would send a POST request to /users. Typically this maps to UsersController.create in RESTful Rails applications.

Yes I’m using the bete version of the third edition. I was able to resolve this issue my restarting the server and clearing session data. But if you are interested, here is the code:



class UsersController < ApplicationController
  # GET /users
  # GET /users.xml
  def index
    @users = User.find(:all, :order => :name)

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @users }
    end
  end

  # GET /users/1
  # GET /users/1.xml
  def show
    @user = User.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @user }
    end
  end

  # GET /users/new
  # GET /users/new.xml
  def new
    @user = User.new

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @user }
    end
  end

  # GET /users/1/edit
  def edit
    @user = User.find(params[:id])
  end

  # POST /users
  # POST /users.xml
  def create
    @user = User.new(params[:user])

    respond_to do |format|
      if @user.save
        flash[:notice] = "User #{@user.name} was successfully created."
        format.html { redirect_to(:action=>:index) }
        format.xml  { render :xml => @user, :status => :created, :location => @user }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @user.errors, :status => :unprocessable_entity }
      end
    end
  end

  # PUT /users/1
  # PUT /users/1.xml
  def update
    @user = User.find(params[:id])

    respond_to do |format|
      if @user.update_attributes(params[:user])
        flash[:notice] = "User #{@user.name} was successfully updated."
        format.html { redirect_to(:action=>:index) }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @user.errors, :status => :unprocessable_entity }
      end
    end
  end

  # DELETE /users/1
  # DELETE /users/1.xml
  def destroy
    @user = User.find(params[:id])
    @user.destroy

    respond_to do |format|
      format.html { redirect_to(users_url) }
      format.xml  { head :ok }
    end
  end
end


samsm:
Thanks for your reply. I know how http form works. I was just wondering where exactly POST action mapped to create? Is it it a “hard-coded” behavior? The only two lines I have in the routes.rb is
map.connect ‘:controller/:action/:id’
map.connect ‘:controller/:action/:id.:format’

Yeah, it’s built into rails conventions. If you look at your controller code you can see the scaffold generates comments that indicate which HTTP call is related to which action.

If you type ‘rake routes’ into your command line you’ll get a list of all the routes currently available in your application, from the list its easy to see that /users with a standard GET call returns the index action for the users controller, whereas /users with a POST call invokes the create action.

Hope that helps.