Ajout d'une action à un contrôleur existant (Ruby on Rails)
-
03-07-2019 - |
Question
Je ne connais pas encore Ruby on Rails, j'ai terminé le didacticiel du blog .
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 sur / 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.
La solution
Votre itinéraire n'est pas configuré pour autoriser cet itinéraire. En supposant que vous utilisiez l'échafaudage par défaut, placez cette ligne avant la ligne map.resources: posts
dans config / routes.rb:
map.connect "posts/:action", :controller => 'posts', :action => /[a-z]+/i
La regex pour : action
la limite à a-z (pour éviter d'attraper des choses comme / posts / 1). Il peut être amélioré si vous avez besoin de traits de soulignement ou de chiffres dans vos nouvelles actions.
Autres conseils
L’erreur que vous commettez est en fait assez commune.
En gros, 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 d’afficher un seul message: / posts / (post_id)
Ainsi, lorsque vous entrez l'URL / publications / début, 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 identifiant.
Un moyen rapide de résoudre ce problème consiste à vous assurer que votre config / routes.rb dispose du chemin 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, j'espère que cela vous aidera.
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.
Essayez ceci si vous utilisez les rails 3.0.3
dans votre route.rb
resource :posts do
collection do
get 'start'
end
end
cela pourrait aider
Je veux dire, parfois, Rails se bloque avec la mise en cache de routes, même dans l'environnement de développement .
Il peut être utile de redémarrer votre serveur Rails . Cela a fonctionné pour moi plus de fois que je ne peux compter quand je reçois cette erreur.
Ceci fonctionne:
map.resource :post, :collection => { :my_action => :get}
J'ai trouvé la solution à mon problème, dans le fichier routes.rb où
map.resource :post
J'ai ajouté avec l'argument de collection, il est donc resté ainsi:
map.resource :post, :collection => { :my_action => :get}