Rails:用户在针脚上投票后更新votes_count

时间:2014-11-09 15:54:53

标签: javascript jquery ruby-on-rails ruby ajax

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

这是我的upvote系统,就像现在一样:

app / controllers / pins_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

在我的app / views / pins / index.html.erb中:

<%= 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方法,但这就是我丢失的地方。

2 个答案:

答案 0 :(得分:0)

我个人更喜欢避免那些凌乱的.js.erb文件,尽管你当然可以这样做。但是,一旦你进行了大量的Ajax调用,你就会得到大量的文件。 Ryan Bates对这种技术有一个非凡的截屏视频here

没有这样做,这里是食谱。您需要在控制器操作中放置respond_to块。现在,现在请求如何进入,你重定向到引脚路径,我假设是这种情况下的当前路径,它重新加载页面。那是你想要避免的。

默认情况下,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调用。

答案 1 :(得分:-1)

你应该把你的pinvotes放在一个带有类的范围内,以便在ajax完成后进行搜索

$(".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
         }
     })
})