19

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
pedalpete
  • 21,076
  • 45
  • 128
  • 239

2 Answers2

44

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.

sepp2k
  • 363,768
  • 54
  • 674
  • 675
  • 1
    Thanks Sepp2k, not only for providing the answer, but explaining the why so clearly. It is something I really struggle with understanding why rails does or expects certain bits, and often the answers online only give the 'this is how it's done' without the why. Your answer was perfect! – pedalpete Sep 17 '10 at 21:12
  • `link_to {:action => :create}, :method => :post` creates a link with the `data-method="POST"` attribute. Which is used by the rails javascript to create a discrete form and post it. Links themselves cannot be used to send anything other than GET requests which is what happens when the JS fails. – max Apr 16 '17 at 07:50
12

Assuming you have default resources set up in your routes file, i.e. something like this

resources :recipes

The following will generate a link that will create a recipe; i.e. will be routed to the create action.

<%= link_to "Create Recipe", recipes_path, :method => :post %>

For this to work, JS needs to be enabled in your browser.

The following will generate a link that will show all recipes; i.e. will be routed to the index action.

<%= link_to "All Recipes", recipes_path %>

This assumes the default which is a Get HTTP request.

Yusuf Saber
  • 592
  • 1
  • 6
  • 10