Changer la route

Les routes gèrent les requêtes HTTP du style http://localhost:3000/posts/new. La route des commentaires est imbriquée dans celle d’un post. Dans routes.rb je modifie la première ligne :

map.resources :posts, :has_many => :comments

J’établis la route des commentaires comme descendant de celle des posts.

Nouveau Controller

Hier j’ai créé mon Model Comment. Maintenant je veux mon Controller Comments. Il faudra m’expliquer pourquoi le Controller est au pluriel et pourquoi le Model est au singulier. Bref, voici un script pour générer tout ça :

script/generate controller Comments index show new edit

Mon Controller Comments avec 4 méthodes prédéfinies : affichage de tous les commentaires (index), affichage d’un commentaire (show), création d’un commentaire (new), édition d’un commentaire (edit).

Fichiers créés

J’ai un fichier pour Controller : app/controllers/comments_controller.rb.
J’ai 4 fichiers de View, 1 pour chaque méthode : app/views/comments/index.html.erb, app/views/comments/show.html.erb, app/views/comments/new.html.erb et app/views/comments/edit.html.erb.

Des méthodes vides

Le script m’a généré les fichiers mais mes méthodes sont vides.

class CommentsController < ApplicationController
  def index
  end
 
  def show
  end
 
  def new
  end
 
  def edit
  end
 
end

Des méthodes pour mes commentaires

Le tuto fournit des méthodes pour faire fonctionner ces commentaires. Ecoutez, je ne pense pas pouvoir faire mieux, donc je vais reprendre le même code et essayer de comprendre ce qu’il fait :

class CommentsController < ApplicationController 
	def index 
		@post = Post.find(params[:post_id])  
		@comments = @post.comments 
	end  
 
	def show 
		@post = Post.find(params[:post_id])  
		@comment = @post.comments.find(params[:id])  
	end  
 
	def new 
		@post = Post.find(params[:post_id])  
		@comment = @post.comments.build 
	end  
 
	def create 
		@post = Post.find(params[:post_id])  
		@comment = @post.comments.build(params[:comment])  
		if @comment.save 
			redirect_to post_comment_url(@post, @comment)  
		else  
			render :action => "new"  
		end  
	end  
 
	def edit 
		@post = Post.find(params[:post_id])  
		@comment = @post.comments.find(params[:id])  
	end  
 
	def update 
		@post = Post.find(params[:post_id])  
		@comment = Comment.find(params[:id])  
		if @comment.update_attributes(params[:comment])  
			redirect_to post_comment_url(@post, @comment)  
		else  
			render :action => "edit"  
		end  
	end  
 
	def destroy 
		@post = Post.find(params[:post_id])  
		@comment = Comment.find(params[:id])  
		@comment.destroy 
		respond_to do |format| 
			format.html { redirect_to post_comments_path(@post) } 
			format.xml { head :ok } 
		end  
	end 
end

Le code est plus compliqué que celui du Post parce qu’il faut gérer l’association avec les posts justement. C’est pour ça qu’il y a @post tout le temps : chaque commentaire doit en permanence savoir à quel post il est associé. Par exemple, l’index ne montre pas tous les commentaires du site mais uniquement l’ensemble des commentaires d’un seul post. Toutes ces méthodes s’appliquent donc dans le cadre d’un post à part entière.

Par contre, je ne vois pas trop d’où sort la méthode .build ou encore .comments. Ca vient peut-être de la classe ApplicationController ? Je ne sais pas trop.