Запись формы ajax Rails показана дважды - PullRequest
2 голосов
/ 07 сентября 2010

Здравствуйте, я хочу написать небольшой блог на Ruby on Rails (3), в котором посты и комментарии отправляются с помощью формы ajax.

Но когда я отправляю комментарий, его часто показывают дважды, и я не понимаю, почему. когда я пишу @post.comments.uniq в файле _create.js.rjs, он работает нормально, но это не совсем чистое решение Когда я перезагружаю страницу без ajax после вставки комментария, комментарий также не отображается дважды. Только когда я вставляю его через ajax.

Вот исходный код моего проекта.

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

конфиг / 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

дб / schema.rb

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

приложение / модели / comment.rb

class Post < ActiveRecord::Base
  has_many :comments
end

приложение / модели / post.rb

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

приложение / контроллеры / 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

приложение / контроллеры / 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>

приложение / просмотров / сообщений / show.html.erb

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

приложение / просмотров / комментарии / _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}")

приложение / просмотр / комментарии / create.js.rjs

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

приложение / просмотров / сообщений / index.html.erb

РЕДАКТИРОВАТЬ:

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

<%= yield %>

приложение / просмотров / макеты / application.html.erb

Ответы [ 2 ]

0 голосов
/ 09 сентября 2010

Я верю, что здесь происходит ...

при звонке

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

Rails добавляет новый комментарий к сообщению. Затем при звонке

:partial => @post.comments

Rails будет вызывать все комментарии из БД, которые принадлежат этому посту.

Мы можем видеть это в журнале:

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

Вместо этого попробуйте создать новый комментарий и затем сохранить его так:

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

А на виду:

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

Я отправил это в качестве примера на Github http://github.com/GavinM/Comments-Demo

0 голосов
/ 07 сентября 2010

Я до сих пор не профи в рельсах, но вы можете проверить, какие JS вы ссылаетесь на файл макета приложения. Я имел обыкновение связывать один раз по умолчанию и после моего application.js и получал все действия ajax дважды. Однако я не уверен в вашем случае. Вставленный код выглядит хорошо.

...