Update a section of your page using AJAX in Rails 6

Rob Faldo
3 min readJan 4, 2021

--

Okay I’ve just found out something excellent. I’m writing a blog to share it, and also somewhere for me to revisit.

I’m making what feels like an embarrassing admission by exposing how I was solving this problem before stumbling into this far, far, far better solution. Just to mitigate the shame, I’ll mention that I’m mostly a back-end engineer and while I work in rails I don’t do too much on the frontend. Maybe you’re not familiar with this solution either, and may have your mind also blown.

The problem to solve

I have encountered this issue a few times when I’ve ventured into the frontend on side projects. I have a list of items on the page, and I want to filter them. I want to update the items section of the page (without reloading the page) with the new items.

What I’ve done in the past

Here’s the embarrassing admission. I’ve been making an AJAX call to the server and in my controller responding with json. I then have a javascript file that creates the elements manually. I’m talking like this:

const element = document.createElement("div")
element.id = "example-id"
element.className = "example-class"
element.textContent = "This is the text content"

Now this isn’t too bad if it’s a really simple element you’re rendering… but when is anything simple? It’s always nested elements and lots of complexity. I’ve ended up with 20+ lines of javascript looping through each item and creating it and attaching it to the page.

One of the worst things about this approach is that you have to now maintain 2 structures. The original (haml or erb file) that’s used on the initial render, and now the javascript code that rebuilds the section after the AJAX request.

A much better way

Okay so I’d googled ‘how to re-render a erb partial’ before and I don’t know if I gave up easy or didn’t have the vocabulary at the time to find the answer… but I found out that you can literally make an AJAX request and tell your app to respond with the re-rendered partial.

The best walkthrough I could find was this stackoverflow answer. This was the original article I found but I felt it left out steps.

The basics:

  1. You need to make an AJAX call to your controller
# Option 1 - use "remote: true" on things like forms and link (see docs). When the user clicks the link, it will make an AJAX request to the server.<%= link_to "an item", @item, id: "item", remote: true %># Option 2 - You can make an Ajax request using javascript. $("#item").click(function() {
let url = "/"
$.ajax({
url: url,
success: function(data) {
console.log('success')
},
error: function() {
console.log('failure')
}
});
}

2. You need to tell your controller to respond to javascript with the partial

class ItemsController < ApplicationController
def index # this is the action name
@items = Item.all
respond_to do |format|
format.js {render layout: false}
format.html { render 'index'} # I had to tell rails to use the index by default if it's a html request.
end
end
end

3. You need to create a .js.erb file that goes in the same views folder as the partial you’re rendering and follows this format {action name}.js.erb (e.g. if the controller action you’re calling is update then you’d call it update.js.erb) with the following

# Example format: 
- views
- items
- index.html.erb
- _items.html.erb # the partial you want to update
- index.js.erb
# index.js.erb$('.items-container').html("<%= j (render partial: 'items') %>")

4. In order to use jquery in the index.js.erb I had to set this in my application.js file

global.$ = jQuery;

This feels a bit dirty and there might be a better way. I’ll update this if I find one, if you know one please comment!

--

--