Rails returning several duplicate records when usi

2019-08-05 18:50发布

问题:

So, I have an app that has several movie clips and users can search for specific topics etc... I'm using Ajax to handle pagination so that users can make a search query and scroll to view more results (similar to twitter).

The issue is when a user searches for i.e. "Funny" a bunch of records will come up and as the user scrolls down Ajax will load duplicates of the records a long with new records.

Here's the code:

if $('.pagination').length
  $(window).scroll ->
    url = $('.pagination .next_page').attr('href')
    if url && $(window).scrollTop() > $(document).height() - $(window).height() - 50
      $('.loader').removeClass('hidden')
      $.getScript(url)
  $(window).scroll()

Here's an screenshot

How can I prevent rails from duplicating records in this case? I've tried uniq and several other methods to no avail.

Thanks!

Update here's some additional code that may be helpful in debugging this:

https://gist.github.com/pblogs/e202ee1f03339ba977ec

回答1:

To debug this issue, you really have to look at whether it's a javascript or a Rails problem

It seems from your debugging that your browser is sending two separate requests to your controller, which would denote that you have some sort of javascript issue. However, I've encountered Rails sending back "multiple" responses before as well

The key to solving the issue will be to determine what is causing the issue:


JS

If it's a JS problem, there are two potential issues you'll have:

  1. Turbolinks
  2. Your script firing twice

Firstly, I would ensure Turbolinks is not playing a problem here:

#app/assets/javascripts/application.js.coffee

#Paginate
paginate = ->
  if $('.pagination').length
    $(window).scroll ->
      url = $('.pagination a.next_page').attr('href')
      if url && $(window).scrollTop() > $(document).height() - $(window).height() - 50
        $('.loader').removeClass('hidden')
        $.getScript(url)
    $(window).scroll()

$(document).on "page:load ready", paginate

This will ensure the call is only called once per page load (it ties into Turbolinks Hooks). This means that if you want to ensure Turbolinks will not fire twice after partially reloading the page, it will do so.

Secondly, you want to ensure your script is only going to be called once. Specifically, I would investigate this line:

if url && $(window).scrollTop() > $(document).height() - $(window).height() - 50

This determines when the script will fire. You need to make sure that the scroll is only called once, which this line will determine.

--

Rails

The second potential point of concern will be Rails.

If you're sending a request to Rails, you need to appreciate that may have a tendency to send back multiple responses if something like Turbolinks gets in the way

I would make sure my controller is set up as such:

#app/controllers/your_controller.rb
class YourController < ApplicationController
   def your_action
      ...
      respond_to do |format|
         format.js
         format.html
      end
   end
end


回答2:

Make sure you are replacing contents instead of appending another set of results to existing ones in your .js.erb