I’ve set up a simple demo app (with users and messages) to test using jQuery, Ajax, and Rails together. The idea is that when you mouseover a user row on the user index page, the page will use Ajax to load that user’s first message. This functionally ‘works’, but the number of server GET requests to fetch the data doubles on each mouseover, until the page slows to a crawl. Can anyone help me figure out why this is happening?
The user index.html.erb that displays the output looks this:
...
<% @users.each do |user| %>
<tr class="user_name" id="<%=user.id %>">
<td><%= user.name %></td>
<td><%= user.email %></td>
<td><%= link_to 'Show', user %></td>
<td><%= link_to 'Edit', edit_user_path(user) %></td>
<td><%= link_to 'Destroy', user, confirm: 'Are you sure?', method: :delete %></td>
</tr>
<% end %>
</table>
<div id="first_message"></div>
...
My jQuery-based Ajax code (in assets/ajax.js) looks like this:
$(document).ready(function () {
$('.user_name').mouseover(function() {
var userId = $(this).attr('id');
$('#first_message').load(window.location + userId + "/first_message");
});
});
I added the following route to handle loading the message:
match 'users/:id/first_message' => 'users#first_message'
The controller to handle the request looks like this:
class UsersController < ApplicationController
def first_message
@user = User.find(params[:id])
respond_to do |format|
format.html # first_message.html.erb
end
end
Finally the html response page (first_message.html.erb) for the Ajax request looks like this:
<h3> <%= @user.name %>'s first message: </h3>
<% if @user.messages.length > 0 %>
<%= @user.messages[0].content %>
<% else %>
...
<% end %>
Any thoughts?
I would assume that this line below is loading in your
first_message.html.erbfile in it’s entirety, including the layout which requires yourajax.jsfile. Because of this, yourajax.jsfile gets included over and over again.You can either turn your
first_messageview into a partial, or you can tell it not to render the layout with all the JS files, etc: