I am trying to accomplish what I think to be the most direct, though certainly not the most elegant, replication of a reddit style vote button. I have code that works without the AJAX, but I would like users to be able to click the vote buttons and they change appropriately without reloading the page (Hence the AJAX).
The problem occurs when I try to remove the vote button clicked on and replace with the appropriate 'highlighted' vote button. The reason I am replaceing the vote button is because I need to change it to a button that will unvote if clicked on.
(I have simplified this to just handle just upvoting since downvoting is the same mexhanic). Here is my view:
<% @posts.each do |post| %>
<%= post.content %>
<% if current_user.voted_as_when_voted_for post %>
<%= render 'upvoted', post: post %>
<% else %>
<%= render 'upvote', post: post %>
<% end %>
<% end %>
The voted_as_when_voted_for method returns true if they have upvoted the post. Here is the upvote and upvoted forms:
<%= link_to image_tag('upvoted.png', size: '18'), remove_like_post_path(post), method: :put, remote: true, id: "upvoted#{post.id}" %>
<%= link_to image_tag('upvote.png', size: '18'), like_post_path(post), method: :put, remote: true, id: "upvote#{post.id}" %>
Here is my controller:
def upvote
@post = Post.find(params[:id])
@post.liked_by current_user
respond_to do |format|
format.html { redirect_to @post.parent }
format.js {}
end
end
def remove_upvote
@post = Post.find(params[:id])
@post.unliked_by current_user
respond_to do |format|
format.html { redirect_to @post.parent }
format.js {}
end
end
upvote.js.erb: and upvoted.js.erb:
$('#upvote<%= @post.id %>').remove().append('<%= j render("upvoted") %>');
$('#upvoted<%= @post.id %>').remove().append('<%= j render("upvote") %>');
With those files I get the following console errors:
PUT http://localhost:3000/posts/96/like 500 (Internal Server Error)
NameError in Posts#upvote
undefined local variable or method `post' for #<#<Class:0x007fde1836cbf0>:0x007fde18c00af0>
_upvote.html.erb and _upvoted.html.erb
<%= link_to image_tag('upvote.png', size: '18'), like_post_path(post), method: :put, remote: true, id: "upvote#{post.id}" %>
<%= link_to image_tag('upvoted.png', size: '18'), like_post_path(post), method: :put, remote: true, id: "upvoted#{post.id}" %>
I also tried something like this based on the link below:
$('#upvote<%= @post.id %>').remove().after('<%= j render "upvoted", post: @post %>');
When I use that code, the upvote is succesfully removed, but the upvoted form is not added on. So it seems that I need to use the instance variable, but something is still not quite working.
What am I missing??
This person seemed to have a similar problem: Rails Ajax Render Partial