2010-09-17 13 views
18

Je construis une application de recette assez simple pour apprendre RoR, et j'essaye de permettre à un utilisateur de sauvegarder une recette en cliquant sur un lien plutôt que par un formulaire, donc je connecte la fonction 'create' des contrôleurs user_recipe via un link_to.link_to: action => 'create' va indexer plutôt que 'créer'

Malheureusement, pour une raison quelconque, link_to appelle la fonction d'index plutôt que create.

J'ai écrit le link_to comme

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

ce lien est sur le user_recipes/index.html.erb et appelle la fonction « créer » du même contrôleur. Cela ne semble pas faire de différence si j'inclue le: controller ou non.

Les contrôleurs se présentent comme suit

 
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 

Répondre

37

Dans le schéma standard REST l'action de l'index et l'action ont tous deux la même URL (/recipes) et ne diffèrent que cet indice est accessible en utilisant GET et créer créer est accessible utilisant POST. Donc, link_to :action => :create va simplement générer un lien vers /recipes qui amènera le navigateur à effectuer une requête GET pour /recipes lorsqu'il est cliqué et donc invoquer l'action d'index.

Pour appeler l'action de création, utilisez link_to {:action => :create}, :method => :post, en indiquant explicitement à link_to que vous souhaitez une demande de publication ou utilisez un formulaire avec un bouton d'envoi plutôt qu'un lien.

+1

Merci Sepp2k, non seulement pour fournir la réponse, mais en expliquant pourquoi aussi clairement. C'est quelque chose que j'ai vraiment du mal à comprendre pourquoi les rails font ou attendent certains bits, et souvent les réponses en ligne ne donnent que le «c'est comme ça» sans le pourquoi. Votre réponse était parfaite! – pedalpete

+0

'link_to {: action =>: créer},: method =>: post' crée un lien avec l'attribut' data-method = "POST" '. Ce qui est utilisé par les rails javascript pour créer un formulaire discret et le poster. Les liens eux-mêmes ne peuvent pas être utilisés pour envoyer autre chose que des requêtes GET, ce qui se passe lorsque le JS échoue. – max

9

En supposant que vous avez des ressources par défaut définies dans votre fichier itinéraires, à savoir quelque chose comme ça

resources :recipes 

Ce qui suit va générer un lien qui va créer une recette; c'est-à-dire sera routé vers l'action de création.

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

Pour que cela fonctionne, JS doit être activé dans votre navigateur.

Ce qui suit va générer un lien qui montrera toutes les recettes; c'est-à-dire sera routé vers l'action d'index.

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

Ceci suppose la valeur par défaut qui est une requête Get HTTP.