Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making AJAX requests in Rails without a form

So I have a posts scaffold generated in a Rails app and I've added an upvote and downvote column to the post model. I added an "upvote" button on the view file and I need to make an AJAX call and query the database when you hit the upvote button, but the upvote button has no real Rails <form> attached to it. How can I make this AJAX call and add the upvote to the database for the upvoted post?

When I make this AJAX call:

$('.up,.down').click(function(){
    $.ajax({
      type: 'POST',
      url: '/posts',
      dataType: 'JSON',
      data: {
        post: {
          upvote: 1
        }
      },
      success: function(){
        alert('success')
      }
    });
  });

It returns a 500 error. Where do I go form here?

like image 463
alt Avatar asked Sep 20 '25 10:09

alt


1 Answers

You could use the :remote => true attribute on the link_to helper for example:

<%= link_to post_upvote_path(post), :remote => true, :method => "put" %>
<%= link_to post_downvote_path(post), :remote => true, :method => "put" %>

then in config/routes.rb:

resources :posts do
  put "upvote", :to => "posts#upvote", as: :upvote
  put "downvote", :to => "posts#downvote", as: :downvote
end

then handle the voting in your posts controller, like you probably already are and grab the post id with params[:id] in the action

Here is an intro to rails flavored unobtrusive javascript

Update
To see the upvote and downvote routes that were created, go to the terminal and type

rake routes | grep vote

this will give you a list of all of your routes that have "vote" in the name. Or just type rake routes to get a list of all of them. The first column is the named route, just append '_path' to the end of it to use it in your app - like post_upvote_path above would be seen as

post_upvote  PUT  /posts/:id/upvote(.:format) posts#upvote

And in you PostsController you would want these actions:

class PostsController < ApplicationController
  ###
  # index, show... other RESTful actions here
  ###


  def upvote
    @post = Post.find params[:id]
    # code for however you are voting up the post here
  end

  def downvote
    @post = Post.find params[:id]
    # code for however you are voting down the post here
  end
end
like image 191
mraaroncruz Avatar answered Sep 23 '25 00:09

mraaroncruz