link_to :action => 'create' going to index rather than 'create'

pedalpete picture pedalpete · Sep 17, 2010 · Viewed 31.2k times · Source

I am building a fairly simple recipe app to learn RoR, and I am attempting to allow a user to save a recipe by clicking a link rather than through a form, so I am connecting the user_recipe controllers 'create' function through a link_to.

Unfortunately, for some reason the link_to is calling the index function rather than the create.

I've written the link_to as

<%= "save this recipe", :action => 'create', :recipe_id => @recipe %>

this link is on the user_recipes/index.html.erb and is calling the 'create' function of the same controller. It doesn't seem to make a difference if I include the :controller or not.

The controllers look like this

def index
    @recipe = params[:recipe_id]
    @user_recipes = UserRecipes.all # change to find when more than one user in db
    respond_to do |format|
         format.html #index.html.erb
         format.xml { render :xml => @recipes }
    end
end

def create
    @user_recipe = UserRecipe.new
    @user_recipe.recipe_id = params[:recipe_id]
    @user_recipe.user_id = current_user
    respond_to do |format|
      if @menu_recipe.save
        format.html { redirect_to(r, :notice => 'Menu was successfully created.') }
        format.xml  { render :xml => @menu, :status => :created, :location => @menu }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @menu.errors, :status => :unprocessable_entity }
      end
    end

Answer

sepp2k picture sepp2k · Sep 17, 2010

In the standard REST scheme the index action and the create action both have the same url (/recipes) and only differ in that index is accessed using GET and create is accessed using POST. So link_to :action => :create will simply generate a link to /recipes which will cause the browser to perform a GET request for /recipes when clicked and thus invoke the index action.

To invoke the create action use link_to {:action => :create}, :method => :post, telling link_to explicitly that you want a post request, or use a form with a submit button rather than a link.