Rails - Ajax请求后JavaScript视图无法正确更新页面

时间:2013-05-17 06:32:40

标签: ajax ruby-on-rails-3

我有Questions,可以投票。当我在问题索引上列出每个问题时,我将“是”投票和“否”投票按钮放在一起。我正在尝试使用Ajax创建投票并呈现更新投票计数的js视图。

我正在观察此行为: 投票成功创建并保存。对每个问题进行的第一次“是”投票会正确调整该问题的计数,但在此之后创建任何“是”投票将不会更新计数,尽管投票对象被保存。 “否”按钮永远不会正确更新标签。随机地,单击“否”按钮会将该问题的no_vote计数增加到80.如果我刷新页面,则所有计数都会按预期更新为正确的值。

question.rb

class Question < ActiveRecord::Base
  attr_accessible :body, :title, :pass_percentage

  has_many :votes
  has_many :yes_votes, class_name: 'Vote', conditions: { is_yes: true }
  has_many :no_votes, class_name: 'Vote', conditions: { is_yes: false }

  ...

end

vote.rb

class Vote < ActiveRecord::Base
  attr_accessible :is_yes, :question_id

  belongs_to :question

  validates :is_yes, inclusion: { in: [true, false]}
  validates :question_id, presence: true
end

视图/问题/ index.html.erb

...

<%= will_paginate @questions %>
<ul class="questions">
    <% @questions.each do |question| %>
    <li>
        <section class="question_<%= question.id %> clearfix">
            <h2><%= link_to question.title, question_path(question) %></h2>
            <p><%= truncate(question.body, length: 70) %></p>
            <div class="vote-buttons">
                <%= render partial: 'shared/yes_vote',
                locals: { question: question } %>
                <%= render partial: 'shared/no_vote', 
                locals: { question: question } %>
            </div>
        </section>
    </li>
    <% end %>
</ul>

...

_yes_vote.html.erb

<div class="vote-btn yes-vote-btn">
<%= form_for question.votes.build(is_yes: true), remote: true do |f| %>
    <%= f.hidden_field :is_yes %>
    <%= f.hidden_field :question_id %>
    <%= f.submit "Yes", class: "btn btn-large btn-success" %>
<% end %>
<span class="yes-votes-count"><%= question.yes_votes.count %></p>
</div>

_no_vote.html.erb

<div class="vote-btn no-vote-btn">
<%= form_for question.votes.build(is_yes: false), remote: true do |f| %>
    <%= f.hidden_field :is_yes %>
    <%= f.hidden_field :question_id %>
    <%= f.submit "No", class: "btn btn-large btn-danger" %>
<% end %>
<span class="no-votes-count"><%= question.no_votes.count %></span>
</div>

votes_controller.rb

class VotesController < ApplicationController
    def new
        @vote = Vote.new
    end

    def create
        @vote = Vote.new(params[:vote])
        @question = @vote.question


        respond_to do |format|
            if @vote.save
                format.html { redirect_to :back }
                format.js
            else
                format.html { redirect_to :back, flash: { error: "There was an error" } }
                format.js
            end
        end
    end
end

questions_controller.rb

class QuestionsController < ApplicationController
    def index
        @questions = Question.paginate(page: params[:page])
    end

    ...

end

视图/表决/ create.js.erb

$(".question_<%= @question.id %> .yes-votes-count").html("<%= @question.yes_votes.count %>")
$(".question_<%= @question.id %> .no-votes-count").html("<%= @question.no_votes.count %>")

服务器日志:

Started POST "/votes" for 127.0.0.1 at 2013-05-17 02:53:38 -0400
Processing by VotesController#create as JS
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"QD+7gj3G5r68B7cpxxW5ighB5M0Djluxx5XymnG4vog=", "vote"=>{"is_yes"=>"true", "question_id"=>"2"}, "commit"=>"Yes"}
  Question Load (0.1ms)  SELECT "questions".* FROM "questions" WHERE "questions"."id" = 2 LIMIT 1
   (0.0ms)  begin transaction
  SQL (0.3ms)  INSERT INTO "votes" ("created_at", "is_yes", "question_id", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?)  [["created_at", Fri, 17 May 2013 06:53:38 UTC +00:00], ["is_yes", true], ["question_id", 2], ["updated_at", Fri, 17 May 2013 06:53:38 UTC +00:00], ["user_id", nil]]
   (0.1ms)  SELECT COUNT(*) FROM "votes" WHERE "votes"."question_id" = 2 AND "votes"."is_yes" = 't'
   (0.0ms)  SELECT COUNT(*) FROM "votes" WHERE "votes"."question_id" = 2
  Question Exists (0.0ms)  SELECT 1 AS one FROM "questions" WHERE ("questions"."title" = 'Crust or no crust?' AND "questions"."id" != 2) LIMIT 1
   (31.9ms)  commit transaction
  CACHE (0.0ms)  SELECT COUNT(*) FROM "votes" WHERE "votes"."question_id" = 2 AND "votes"."is_yes" = 't'
   (0.1ms)  SELECT COUNT(*) FROM "votes" WHERE "votes"."question_id" = 2 AND "votes"."is_yes" = 'f'
  Rendered votes/create.js.erb (1.2ms)
Completed 200 OK in 39ms (Views: 2.3ms | ActiveRecord: 32.6ms)

很抱歉代码很多。我尽量让它变得清晰。

为什么这不起作用?有没有更好的方法来编写create.js.erb视图?

2 个答案:

答案 0 :(得分:0)

你写了两个@vote.save条件。移动第一个并再次检查。
必须是验证问题,就好像您要保存两次相同的条目一样

答案 1 :(得分:0)

找出我的问题。问题发生在我的create.js.erb中。我需要使用.text()函数而不是.html()来替换元素的内容。

新代码:

$(".question_<%= @question.id %> .yes-votes-count").text("<%= @question.yes_votes.count %>")
$(".question_<%= @question.id %> .no-votes-count").text("<%= @question.no_votes.count %>")

如果有人看到了改进我的代码的方法,请发布一个答案,我会接受它。