2010-09-07 6 views
2

Bonjour Je veux écrire un petit blog avec Ruby on Rails (3), avec des messages et des commentaires soumis via un formulaire ajax.Rails entrée de formulaire ajax montré deux fois

Mais quand je soumets un commentaire, il est souvent montré deux fois, et je ne sais pas pourquoi. lorsque j'écris @ post.comments.uniq dans le fichier _create.js.rjs, cela fonctionne très bien, mais cela ne semble pas être une solution propre. Lorsque je recharge la page sans ajax après avoir inséré un commentaire, le commentaire n'apparaît pas deux fois. Seulement quand je l'insère via ajax.

Voici le code source de mon projet.

Blog::Application.routes.draw do 
    root :to => 'posts#index' 
    resources :posts do 
    resources :comments 
    end 
end 

config/routes.rb

ActiveRecord::Schema.define(:version => 20100907105618) do 

    create_table "comments", :force => true do |t| 
    t.text  "text" 
    t.integer "post_id" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "posts", :force => true do |t| 
    t.string "title" 
    t.text  "text" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

end 

db/schema.rb

class Comment < ActiveRecord::Base 
    belongs_to :post 
    default_scope :order => "id DESC" 
end 

app/modèles/comment.rb

class Post < ActiveRecord::Base 
    has_many :comments 
end 

app/models/post.rb

class PostsController < ApplicationController 
    def index 
    @posts = Post.all 
    end 
    def show 
    @post = Post.find(params[:id]) 
    end 
end 

app/controllers/posts_controller.rb

class CommentsController < ApplicationController 
    respond_to :js 
    def create 
    @post = Post.find(params[:post_id]) 
    # if I write here p @post.comments.inspect 
    # it shows that there where 2 comments with the same id, how could this be? 
    @post.comments.create(params[:comment]) 
    end 
end 

app/controllers/comments_controller.rb

<h2><%= @post.title %></h2> 

<p> 
    <%= @post.text %> 
</p> 

<%= form_for [@post, Comment.new], :remote => true do |f| %> 
    <%= f.text_area :text, :rows => 4 %><br /> 
    <%= f.submit "send" %> 
<% end %> 

<div id="comments_box"> 
    <% if @post.comments.any? %> 
    <%= render :partial => @post.comments %> 
    <% else %> 
    No Comments yet 
    <% end %> 
</div> 

app/views/posts/show.html.erb

<div id="comment_<%= comment.id %>"><%= comment.text %></div> 

app/views/commentaires/_comment.html.erb

page[:comment_text].clear 
page[:comments_box].replace_html :partial => @post.comments 
               #^write here @post.comments.uniq it works 
page.visual_effect(:highlight, "comment_#{@post.comments.first.id}") 

app/views/commentaires/créer. js.rjs

<% @posts.each do |post| %> 
    <%= link_to post.title, post %> 
<% end %> 

app/views/posts/index.html.erb

EDIT:

<!DOCTYPE html> 
<html> 
<head> 
    <title>Blog</title> 
    <%= stylesheet_link_tag :all %> 
    <%= javascript_include_tag :defaults %> 
    <%= csrf_meta_tag %> 
</head> 
<body> 

<%= yield %> 

app/views/layouts/application.html.erb

Répondre

0

Je ne suis toujours pas un profi dans des rails, mais vous pouvez vérifier que vous js lien à votre fichier de disposition d'application. J'avais l'habitude de lier une fois par défaut et après mon application.js et j'ai reçu toute l'action ajax deux fois. Cependant, je ne suis pas sûr de votre cas. Le code que vous avez collé semble bien.

+0

Merci pour votre réponse. J'ai ajouté le code du fichier de disposition dans la question ci-dessus. – ipsum

0

Je crois que ce qui se passe ici est ...

lorsque vous appelez

@post.comments.create(params[:comment]) 

Rails Ajoute un nouveau commentaire à la poste. Puis, lors de l'appel

:partial => @post.comments 

Les messages suivront tous les commentaires de la base de données appartenant à ce message.

On peut le voir dans le journal:

SQL (0.5ms) INSERT INTO "comments" ("created_at", "post_id", "text", "updated_at") VALUES ('2010-09-09 11:10:18.874471', 1, 'lots of pies', '2010-09-09 11:10:18.874471') 
Comment Load (0.9ms) SELECT "comments".* FROM "comments" WHERE ("comments".post_id = 1) ORDER BY id DESC 

Au lieu de cela, essayez de créer un nouveau commentaire et puis enregistrez comme ceci:

class CommentsController < ApplicationController 
    respond_to :js 
    def create 
    @post = Post.find(params[:post_id]) 
    @comment = @post.comments.new(params[:comment]) 
    @comment.save 
    end 
end 

Et dans la vue:

page[:comment_text].clear 
page[:comments_box].replace_html render(@post.comments) 
page.visual_effect(:highlight, "comment_#{@post.comments.first.id}") 

J'ai posté ceci comme exemple à Github http://github.com/GavinM/Comments-Demo

+0

Je pensais que la seule différence entre "nouveau" et "créer" est que "créer" enregistre directement l'objet, et je n'ai pas besoin d'appeler la méthode "save" explicite. – ipsum

Questions connexes