简体   繁体   English

Ajax用于后投票/后投票(停止页面刷新)

[英]Ajax for post upvote/downvote (stopping page refresh)

I'm using "acts_as_votable" gem in my Rails application so that Users can vote on Posts. 我在Rails应用程序中使用“ acts_as_votable” gem,以便用户可以对帖子进行投票。 I'm trying to add Ajax functionality so that the entire page doesn't have to refresh when a user upvotes a post. 我正在尝试添加Ajax功能,以使用户在对帖子进行投票时不必刷新整个页面。

My upvote/downvote links are clickable and record the votes, but the render is not refreshing and the vote count still remains the same (I still have to refresh the page to see the count change). 我的upvote / downvote链接是可单击的并记录了投票,但是渲染没有刷新并且投票计数仍然保持不变(我仍然必须刷新页面才能看到计数变化)。

I can see my in Run log this error: 我可以在“运行日志”中看到此错误:

Rendered posts/downvote.js.erb (3.4ms)
Completed 500 Internal Server Error in 77ms (ActiveRecord: 8.4ms)

ActionView::Template::Error (undefined method `id' for nil:NilClass):
    1: $(document).ready(function(){
    2:     $('#vote_<%= p.id %>').html("<%= escape_javascript render :partial => 'vote' %>");
    3: });
  app/views/posts/downvote.js.erb:2:in `_app_views_posts_downvote_js_erb__811382410496335987_70314739481440'
  app/controllers/posts_controller.rb:44:in `downvote'


  Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-4.2.5/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb (1.0ms)
  Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-4.2.5/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb (0.7ms)
  Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-4.2.5/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb (17.0ms)

Here is what I have: 这是我所拥有的:

routes.rb 的routes.rb

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

posts_controller.rb posts_controller.rb

def upvote
  @post = Post.find(params[:id])
  @post.upvote_by current_user
    respond_to do |format|
        format.html { redirect_to :back }
        format.js 
    end
end

def downvote
  @post = Post.find(params[:id])
  @post.downvote_by current_user
    respond_to do |format|
        format.html { redirect_to :back }
        format.js 
    end
end

explore.html.erb (/views/pages/explore.html.erb) explore.html.erb(/views/pages/explore.html.erb)

<% if @posts.each do |p| %>
<div class="panel-body">
  <p class="post-content"><%= auto_link(p.content, :html => { :target => '_blank' }) %></p>

  <%= render :partial => '/posts/vote', :class => "vote", :locals => { p: p } %>

</div>
<% end %>

_vote.html.erb (/views/posts/_vote.html.erb) _vote.html.erb (/views/posts/_vote.html.erb)

<<div id="vote_<%= p.id %>" class="vote">
  <%= link_to 'Vote Up', like_post_path(p), :class => "upvote", :method => :put, :remote => true %>
  <span><%= p.score %></span>  <!--show the current vote-->
  <%= link_to 'Vote Down', dislike_post_path(p), :class => "downvote", :method => :put, :remote => true %>
</div>

upvote.js.erb (/views/posts/upvote.js.erb) upvote.js.erb (/views/posts/upvote.js.erb)

$(document).ready(function(){
    $('#vote_<%= p.id %>').html("<%= escape_javascript render :partial => 'vote' %>");
});

downvote.js.erb (/views/posts/downvote.js.erb) downvote.js.erb (/views/posts/downvote.js.erb)

$(document).ready(function(){
    $('#vote_<%= p.id %>').html("<%= escape_javascript render :partial => 'vote' %>");
});

Is there something wrong with my javascript, or am I rendering something wrong? 我的JavaScript是否有问题,还是我渲染了问题? Thank you in advance. 先感谢您。

The answer is there in the error, your p variable is nil in your javascript files is nil. 答案在错误中,您的p变量为nil,而您的javascript文件为nil。

The reason you are able to use p in your html files is because you are looping through the @posts collection providing each post within a variable named p. 之所以能够在html文件中使用p,是因为您正在遍历@posts集合,从而在名为p的变量中提供了每个帖子。

However in your js files you have no such loop, you therefore need to access the instance variable directly. 但是,在您的js文件中没有此类循环,因此您需要直接访问实例变量。

Also when you are rendering the _vote partial within the javascript file, you are not providing the p local variable, you will need to include that also. 同样,当您在javascript文件中呈现_vote部分时,您没有提供p局部变量,则还需要包括该变量。

change the downvote.js.erb code to: 将downvote.js.erb代码更改为:

$(document).ready(function(){
    $('#vote_<%= @post.id %>').html("<%= escape_javascript(render(:partial =>'vote', :locals => { p: @post })) %>");
});
  1. _vote.html.erb (/views/posts/_vote.html.erb) " << " in the first line will rise an syntax error. _vote.html.erb (/views/posts/_vote.html.erb)第一行中的“ << ”会引发语法错误。

  2. In your *.js.erb files just have @post from controller's action, not p like in your view. 在您的* .js.erb文件只是从控制器的行动,而不是P在视图@Post等。 Try update like below: 尝试如下更新:

upvote.js.erb (/views/posts/upvote.js.erb) upvote.js.erb (/views/posts/upvote.js.erb)

$(document).ready(function(){
  $('#vote_<%= @post.id %>').html("<%= escape_javascript render :partial => 'vote', locals: { p: @post } %>");
});

downvote.js.erb (/views/posts/downvote.js.erb) downvote.js.erb (/views/posts/downvote.js.erb)

$(document).ready(function(){
  $('#vote_<%= @post.id %>').html("<%= escape_javascript render :partial => 'vote', locals: { p: @post } %>");
});

Hope this help. 希望能有所帮助。 :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM