2009-11-19 5 views
0

J'ai une application de blog assez standard avec le contrôleur et les modèles habituels de poste et de commentaires avec un modèle d'utilisateur pour laisser des commentaires.La manière la plus élégante de mettre à jour les commentaires dans une application de blog de rails

Ainsi, dans le modèle utilisateur J'ai

has_many :comments 

Et dans le modèle des commentaires

belongs_to :post 
belongs_to :user 

Tout cela est très simple.

Dans l'application que je crée, je veux que les commentaires agissent un peu différemment. Lorsque l'utilisateur laisse un commentaire pour la première fois, je vais créer un nouveau commentaire. Cependant, je veux seulement autoriser un commentaire par publication par utilisateur. Si l'utilisateur essaie de laisser un autre commentaire, nous devrions seulement mettre à jour le commentaire existant.

Pour ce faire, j'ai ajouté ceci au modèle de l'utilisateur

has_many :posts, :through => :comment 

Et dans le contrôleur les messages que j'ai ce qui suit dans l'action show.

if post = current_user.posts.find_by_permalink(params[:id]) 
    @comment = post.comments.find_by_user_id(current_user) 
else 
    @comment = Comment.new 
end 

Cela fonctionne en ce qu'il vérifie si l'utilisateur a déjà fait un commentaire sur ce post et si oui, il se traduira par une mise à jour du commentaire plutôt qu'une nouvelle posté.

Mais, le code ci-dessus ne me convient pas. Y a-t-il une solution plus élégante?

+1

Par "mettre à jour le commentaire existant", voulez-vous dire remplacer le contenu de leur commentaire par le nouveau contenu, ou fusionner les deux ensemble? –

Répondre

2

La façon dont vous faites ceci est bien, mais vous devez déplacer la logique dans le modèle. Je suggère également d'ajouter une validation en utilisant validates_uniqueness_of.

Dans Poste vous pouvez faire:

has_many :comments do 
    def find_or_build_for_user(user) 
     find_by_user_id(current_user.id) || self.comment.build(:user => user) 
    end 
end 

Ensuite, dans votre contrôleur que vous feriez:

@comment = post.comments.find_or_build_for_user(current_user) 

Les ci-dessus utilise des extensions d'association, vous pouvez en savoir plus sur eux ici:

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

Je ne sais pas si ce qui précède fonctionnera tel quel Je ne l'ai pas testé, mais il devrait vous orienter dans la bonne direction.

+0

C'est parfait. Je n'ai jamais su sur les extensions d'association, très utile. Merci. – KJF

+0

Ils peuvent être très utiles, mais essayez de ne pas les abuser. Vous pouvez également les placer dans un module séparé et utiliser l'option: extend de l'association. N'oubliez pas de garder votre contrôleur maigre et vos modèles gros! (http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model). – jonnii

Questions connexes