喜欢/不喜欢使用AJAX的Ruby on Rails

问题描述:

我是Ruby on Rails的新手,我正在开发一个项目(Pinterest克隆),其中有一个模型用户和模型Pin。我正在使用acts_as_votable gem让用户上传或下载上传的图片,我称之为“针”。一切正常,但我刷新喜欢/不喜欢系统的页面,以更新喜欢/不喜欢的计数器。喜欢/不喜欢使用AJAX的Ruby on Rails

我想使用AJAX,这样我就不需要刷新页面。

引脚控制器有这样的:

def destroy 
    @pin.destroy 
    redirect_to root_path 
end 

def upvote 
    @pin.upvote_by current_user 
    redirect_to :back 
end 

def downvote 
    @pin.downvote_by current_user 
    redirect_to :back 
end 

private 

def pin_params 
    params.require(:pin).permit(:title, :description, :image) 
end 

def find_pin 
    @pin = Pin.find(params[:id]) 
end 

我使用HAML和针 - >显示观点有以下几点:

#pin_show.row 
.col-md-8.col-md-offset-2 
    .panel.panel-default 
     .panel-heading.pin_image 
      = image_tag @pin.image.url 
     .panel-body 
      %h1= @pin.title 
      %p.description= @pin.description 
     .panel-footer 
      .row 
       .col-md-6 
        %p.user 
         Submitted by 
         = @pin.user.name 
       .col-md-6 
        .btn-group.pull-right 
         = link_to like_pin_path(@pin), method: :put, class: "btn btn-default" do 
          %span.glyphicon.glyphicon-heart-empty 
           = @pin.get_upvotes.size 

         = link_to dislike_pin_path(@pin), method: :put, class: "btn btn-default" do 
          %span.glyphicon.glyphicon-thumbs-down 
           = @pin.get_downvotes.size 
         - if @pin.user == current_user  
          = link_to "Edit", edit_pin_path, class: "btn btn-default" 
          = link_to "Delete", pin_path, method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-default" 

而且我的routes.rb有此:

resources :pins do 
member do 
    put "like", to: "pins#upvote" 
    put "dislike", to: "pins#downvote" 
end 

end

当我有这种方法时,如何实现AJAX。我是新来的铁轨,我几乎卡在这里

Rails的不显眼的Javascript将听取与data-remote=true的链接,并提交那些作为JS请求。

= link_to like_pin_path(@pin), method: :put, data: { remote: true }... 

这些请求会在你的控制器格式JS,所以你的控制器动作不需要,如果它是格式JS重定向。

def upvote 
    @pin.upvote_by current_user 
    respond_to do |format| 
    format.html { redirect_to :back } 
    format.js { render 'vote' } 
    end 
end 

这将为您提供@pin支持。但是如果你想要点击反馈,你需要一些js。你可以有upvote方法呈现一个JS模板重新渲染模板:

的意见/销/ vote.js.erb

$(function() { 
    $('span.glyphicon.glyphicon-heart-empty').text("<%= @pin.get_upvotes.size %>"); 
    $('span.glyphicon.glyphicon-thumbs-down').text("<%= @pin.get_downvotes.size %>"); 
}); 

编辑:调试

如果JavaScript没有达到你期望的水平,有几种方法可以找出问题所在。

vote.js.erb

$(function() { 
    var upvotes = "<%= @pin.get_upvotes.size %>"; 
    var downvotes = "<%= @pin.get_downvotes.size %>" 
    debugger; 
}); 

如果您有启用JavaScript控制台,调试器将暂停执行,并允许你手动插入了jQuery。您将有权访问upvotesdownvotes,您可以粘贴$('.glyphicon-heart-empty')并确保找到正确的元素。

+0

谢谢你的回应。我做了你所陈述的改变,但是柜台并没有在'实时'显示改变(如你前面提到的反馈)。刷新页面时,即计数器数字发生变化时。然而,服务器显示投票'已被铸造'。我能错过什么吗? – 2015-02-24 15:28:46

+0

首先,确保JavaScript正在解雇。将警报或console.log放入匿名函数中。如果它没有发射,请确保您的upvote和downvote操作都呈现“投票”并且没有服务器错误。如果js正在发射,那么这只是调整jQuery的问题。 – evanbikes 2015-02-24 16:13:10

+0

“在匿名函数中放置警报或console.log”。我该如何做到这一点,如果你说我应该确保JavaScript正在解雇,你是什么意思?据我检查服务器,我没有看到任何错误,服务器日志显示vote.js.erb – 2015-02-24 16:21:19