Javascript Rails:在用户对PIN投票后更新投票数

Javascript Rails:在用户对PIN投票后更新投票数,javascript,jquery,ruby-on-rails,ruby,ajax,Javascript,Jquery,Ruby On Rails,Ruby,Ajax,我有一个非常简单的rails应用程序,用户可以在其中向上投票。我实现的系统运行良好,但我希望在每次投票后通过ajax方法更新投票数 以下是我现在的投票制度: 应用程序内/controllers/pins\u controller.rb: def upvote @pin = Pin.friendly.find(params[:id]) @pin.votes.create(user_id: current_user.id) respond_to do |format| for

我有一个非常简单的rails应用程序,用户可以在其中向上投票。我实现的系统运行良好,但我希望在每次投票后通过ajax方法更新投票数

以下是我现在的投票制度:

应用程序内/controllers/pins\u controller.rb:

def upvote
  @pin = Pin.friendly.find(params[:id])
  @pin.votes.create(user_id: current_user.id)
    respond_to do |format|
    format.json { render json: { count: @pin.votes_count } }
 end
end
<%= link_to upvote_pin_path(pin), method: :post, remote: true do %>

        <% if pin.votes.where(user_id: current_user.id).empty? %>

            <span class="text-decoration: none;"><i class="fa fa-star"></i>

        <% else %>

            <span class="text-decoration: none;"><i class="fa fa-star" style="color:#c0392b"></i>

        <% end %>

<% end %>
            <span class="votes-count">
              <%= pluralize(pin.votes.count, "") %>
            </span>
在我的应用程序/views/pins/index.html.erb:

def upvote
  @pin = Pin.friendly.find(params[:id])
  @pin.votes.create(user_id: current_user.id)
    respond_to do |format|
    format.json { render json: { count: @pin.votes_count } }
 end
end
<%= link_to upvote_pin_path(pin), method: :post, remote: true do %>

        <% if pin.votes.where(user_id: current_user.id).empty? %>

            <span class="text-decoration: none;"><i class="fa fa-star"></i>

        <% else %>

            <span class="text-decoration: none;"><i class="fa fa-star" style="color:#c0392b"></i>

        <% end %>

<% end %>
            <span class="votes-count">
              <%= pluralize(pin.votes.count, "") %>
            </span>

因此,每次有人向上投票时,只有在刷新页面后,投票才可见。有什么想法吗


我知道我应该在我的视图中调用upvote.js.erb文件中的ajax方法,但这就是我丢失的地方。

在ajax完成后,您应该在一个带有类的范围内使用PinVote进行搜索

$(".fa.fa-star").click(function(){
     var _this=$(this)
     $.ajax({
       .....
        success:function(msg){
            _this.parent().parent().find('.votes-count').html(msg); //Accesing the parent then you should acces a span to your votes
         }
     })
})

我个人更喜欢避免那些凌乱的.js.erb文件,尽管您当然可以这样做。但是,一旦进行了大量Ajax调用,就会得到大量文件。Ryan Bates有一个关于这项技术的惊人的剧组

如果没有,这是食谱。您需要在控制器操作中放置一个
respond\u to
块。现在,不管请求是如何传入的,您都将重定向到pin路径,我假设它是本例中的当前路径,它将重新加载页面。这就是你想要避免的

默认情况下,Ajax请求作为javascript或js请求类型传入控制器。如果需要,可以切换该类型(JSON是一种流行的替代方法),但现在让我们保持简单。因此,为js请求配置
respond_to
块:

# app/controllers/pins_controller.rb
def upvote
  @pin = Pin.friendly.find(params[:id])

  if @pin.votes.create(user_id: current_user.id)
    respond_to do |format|
      format.html {
        flash[:notice] =  "Thanks for your recommendation."
        redirect_to(pin_path)
      }

      format.js {
        @count = @pin.votes.count.to_s
        render nothing: true, count: @count # anything else you put in here will be available in the `success` callback on the JQuery ajax method.
      }
    end
  else 
    format.html {
      flash[:notice] =  "Unable to process your request. Please try again."
      redirect_to(pin_path)
    }

    format.js {
      render nothing: true # anything else you put in here will be available in the `error` callback on the JQuery ajax method.
    }
  end
end
既然控制器已传回该值,您需要在Ajax请求中检索该值:

     $.ajax({
       .....
       success:function(data){
         $('span.votes-count').text(data.count)
       }

当您使用此方法时,有两件事(至少)对您不可用。flash消息和ruby多元化方法。为了解决第二个问题,您需要在控制器中使用Ruby复数并返回所需的文本。要绕过第一个问题,您需要设置一些模仿Rails flash消息技术的javascript,并将flash消息传递回Ajax调用。

谢谢您的回答,但我仍然无法理解-我对Rails非常陌生,对Ajax功能更是如此。。。我在upvote buton中添加了remote:true,但是投票数没有更新,这就是我需要通过ajax方法更新的内容。我不知道rails是如何工作的,你能把代码在app/views/pins/index.html.erb中打印的html放进去吗?也许我可以在这方面提供更多帮助好的-所以我在index.html.erb1中用更多的代码编辑了我的问题。-好的,谢谢,我会研究这个。我会通知你的。再次感谢您的时间和建议。首先,感谢您详细的回答。所以我把你的代码添加到我的控制器上。然后,我在javascript文件的vots.js文件中添加了ajax请求。我不确定应该将什么作为#我的_目标_元素id。您能详细介绍一下我应该使用的Ajax请求吗?谢谢。我更改了success调用以使其更符合您的示例。感谢您的努力,因此我使用此ajax请求进行了更新,但仍需要刷新页面以显示更新的投票数。该死对不起:’)不,没有。我几乎每天都使用这种技术。如果你还在挣扎,我建议你从Ryan Bates Railscast开始。说清楚,我不是在测试我给你的代码。您需要根据您的特定环境调整该技术。