DEV Community

Hrishi Mittal for Learnetto

Posted on • Edited on • Originally published at learnetto.com

How to make AJAX calls in Rails 5.1

Originally published at Learnetto.com.

Rails shipped without jQuery as a dependency for the first time with version 5.1. Rails used to rely on jQuery for Unobtrusive JavaScript features but now ships with its own library rails-ujs with the same features.

One of the most common use cases for jQuery in Rails was making AJAX calls through forms and links. If you’re using Rails 5.1 for the first time, you might get confused about how to make AJAX calls, especially things like data formats and including CSRF tokens.

So this little tutorial walks you through a few ways you can do so:

1. Use rails-ujs (no jQuery)

A new Rails 5.1 app automatically includes the rails-ujs script in the app’s application.js file:

//= require rails-ujs

Enter fullscreen mode Exit fullscreen mode

If you don’t want to include it there and use it only selectively, say if you’re making a separate React frontend with Rails’s new webpacker support, then you can do use rails-ujs by installing it as a package:

$ yarn add rails-ujs

Enter fullscreen mode Exit fullscreen mode

And then import and start it in your JavaScript file:

import Rails from ‘rails-ujs
Rails.start()

Enter fullscreen mode Exit fullscreen mode

Remove this line from application.js :

//= require rails-ujs

Enter fullscreen mode Exit fullscreen mode

Now let’s say we want to make an AJAX POST call to an API endpoint/things with some data which looks like this:

mydata = {
 thing: {
  field1: value1,
  field2: value2,
}}
Enter fullscreen mode Exit fullscreen mode

Making an AJAX POST call with rails-ujs looks identical to making it with jQuery:

Rails.ajax({
  type: "POST", 
  url: "/things",
  data: mydata,
  success: function(repsonse){...},
  error: function(repsonse){...}
})
Enter fullscreen mode Exit fullscreen mode

Except for one thing! As far as I can tell, you can’t simply send JSON data. So we need to convert mydata to application/x-www-form-urlencoded content type manually like this:

mydata = 'thing[field1]=value1&thing[field2]=value2'

Enter fullscreen mode Exit fullscreen mode

jQuery does this conversion automatically before submitting a request.

I assumed rails-ujs has some automatic way of doing it, but I couldn’t find anything in the docs or code.

If you know, let me know.

rails-ujs automatically takes care of including the CSRF token with the request.

2. Use jQuery

If the manual data conversion puts you off, you can still use jQuery. You may be relying on jQuery for other things in your app anyway, so here are couple of ways of using jQuery with Rails for making AJAX calls:

2.1 Use the jquery-rails gem

This gem used to be automatically included in previous versions of Rails. You can install it by adding it to your Gemfile:

gem 'jquery-rails'

Enter fullscreen mode Exit fullscreen mode

Then run:

$ bundle install

Enter fullscreen mode Exit fullscreen mode

And include jquery and jquery_ujs in your application.js file:

//= require jquery
//= require jquery_ujs

Enter fullscreen mode Exit fullscreen mode

That’s all you need. Now you can make your AJAX call in the usual way:

$.ajax({
  type: "POST", 
  url: "/things",
  data: mydata,
  success: function(data, textStatus, jqXHR){...},
  error: function(jqXHR, textStatus, errorThrown){...}
})
Enter fullscreen mode Exit fullscreen mode

jquery_ujs takes care of including the CSRF token and jquery converts the data to application/x-www-form-urlencoded content type automatically.

2.2. Use jquery package from npm

If you don’t want to use a gemified version of jQuery, you can install it as a JavaScript package from npm:

$ yarn add jquery
$ yarn add jquery-ujs

Enter fullscreen mode Exit fullscreen mode

Then import them in your JavaScript file:

import $ from ‘jquery
import {} from ‘jquery-ujs

Enter fullscreen mode Exit fullscreen mode

Make sure to remove the jquery-rails gem if you have it installed and remove jquery and jquery_ujs from application.js.Â

You may get an error saying jQuery is not defined. In your webpack config file add this to the config.plugins array:

new webpack.ProvidePlugin({
 $: jquery,
 jQuery: jquery
}),
Enter fullscreen mode Exit fullscreen mode

And now you will be able to use jQuery for making your AJAX calls.

3. Use axios

axios is a promise-based HTTP library. You can use it to make HTTP requests from node.js (on the server) and also AJAX requests from the browser.

It’s a good alternative if you don’t need any of jQuery’s other features. To use axios in a Rails 5.1 app (with webpacker), install it:

$ yarn add axios

Enter fullscreen mode Exit fullscreen mode

Then import it in your JavaScript file:

import axios from ‘axios

Enter fullscreen mode Exit fullscreen mode

Now we can make the AJAX call like this:

axios({
  method: 'POST', 
  url: '/things',
  data: mydata,
  headers: {
    'X-CSRF-Token': document.querySelector("meta[name=csrf-token]").content
  }
})
.then(function(response) {...},
.catch(function(error) {...}
})
Enter fullscreen mode Exit fullscreen mode

A few things to note here:

We have to include the CSRF token header. Unlike jquery_ujs and rails-ujs, it’s not automatically included with axios requests.

We can specify it as a default setting to avoid repeating it in all our AJAX calls:

const csrfToken = document.querySelector("meta[name=csrf-token]").content 

axios.defaults.headers.common[‘X-CSRF-Token] = csrfToken

Enter fullscreen mode Exit fullscreen mode

We can access the success and error responses using the promises syntax .then.

Another option is to use fetch, but it’s an experimental API and not available by default in all browsers. So you’re best off using Github’s polyfill library. I prefer axios to fetch because fetch responses need to be first converted to json and the error handling can also be confusing.

Top comments (0)