web-dev-qa-db-fra.com

Ajout d'une action à un contrôleur existant (Ruby on Rails)

Je suis nouveau sur Ruby on Rails, j'ai terminé le Blog Tutorial .

J'essaie maintenant d'ajouter une action supplémentaire au contrôleur, appelée "démarrer".

def start
end

J'ai ajouté une page de vue "app/views/posts/start.html.erb" ne contenant que du code HTML simple.

Quand je vais à/posts/start, j'obtiens l'erreur suivante.

ActiveRecord::RecordNotFound in PostsController#show 
Couldn't find Post with ID=start

Je comprends l'erreur, l'action show est en cours d'exécution et start n'est pas un identifiant valide. Pourquoi l'action de démarrage n'est-elle pas exécutée? Existe-t-il une partie de l'architecture ou de la configuration MVC qui me manque?

Ci-dessous mon posts_controller.rb

class PostsController < ApplicationController

  # GET /posts/start
  def start
  end

  # GET /posts
  # GET /posts.xml
  def index
    @posts = Post.find(:all)
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @posts }
    end
  end

  # GET /posts/1
  # GET /posts/1.xml
  def show
    @post = Post.find(params[:id])
    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @post }
    end
  end

end

Oui, j'ai redémarré le serveur et essayé avec Mongrel et Webrick.

36
Mark

Votre itinéraire n'est pas configuré pour autoriser cet itinéraire. En supposant que vous utilisez l'échafaudage par défaut, mettez cette ligne before la ligne map.resources :posts dans config/routes.rb:

map.connect "posts/:action", :controller => 'posts', :action => /[a-z]+/i

La regex pour :action le limite à a-z (pour éviter d'attraper des choses comme/posts/1). Cela peut être amélioré si vous avez besoin de traits de soulignement ou de chiffres dans vos nouvelles actions.

26
zenazn

L’erreur que vous commettez est en fait assez commune.

Fondamentalement, Rails mappe automatiquement les URL de vos échafaudages. Ainsi, lorsque vous avez créé les échafaudages Posts, Rails mappe les itinéraires d'URL correspondants. L’une de ces routes est l’URL permettant de consulter un seul message:/posts/(post_id).

Ainsi, lorsque vous entrez l'URL/posts/start, Rails pense que vous dites "Hé, donnez-moi la publication avec ID = start. Rails se plaint donc que la méthode show ne trouve pas de publication avec un tel ID.

Un moyen rapide de résoudre ce problème consiste à vous assurer que votre fichier config/routes.rb contient l'itinéraire pour l'action de démarrage avant les itinéraires d'échafaudage:

# Route for start action
map.connect '/posts/start', :controller => 'posts', :action => 'start'
# Default mapping of routes for the scaffold
map.resources :posts

Quoi qu'il en soit, espérons que cela aide.

45
David

Sur Rails 4.x, utilisez:

get '/posts/start', :controller => 'posts', :action => 'start'

Sur Rails 3.x, utilisez:

match '/posts/start', :controller => 'posts', :action => 'start'

au lieu de

map.connect '/posts/start', :controller => 'posts', :action => 'start'

cela a résolu mon problème.

33
Nailson Landim

Essayez ceci si vous utilisez Rails 3.0.3

dans votre route.rb

 resource :posts do
   collection do
     get 'start'
   end
 end

cela pourrait aider

8
Amanuel

Je veux dire, parfois, Rails devient collant avec la mise en cache de routes, même dans l'environnement development .

Il peut être utile de redémarrer votre serveur Rails . Cela a fonctionné pour moi plus de fois que je ne peux compter quand recevoir cette erreur.

2
ghayes

Cela marche:

map.resource :post, :collection => { :my_action => :get}
1
chernia

J'ai trouvé la solution à mon problème, dans le fichier routes.rb où

map.resource :post

J'ai ajouté avec l'argument collection, donc ça reste comme ça:

map.resource :post, :collection => { :my_action => :get}
0
Thiago Diniz