Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails .order(“RANDOM()”与will_paginate gem_Ruby On Rails_Ruby_Will Paginate - Fatal编程技术网

Ruby on rails .order(“RANDOM()”与will_paginate gem

Ruby on rails .order(“RANDOM()”与will_paginate gem,ruby-on-rails,ruby,will-paginate,Ruby On Rails,Ruby,Will Paginate,我想知道是否还有什么方法可以继续使用。order(“RANDOM()”)和将分页,这样当一个页面加载并对页面进行排序时,在重新加载主页之前,每个页面上的所有帖子都将保持不变 因此,要使localhost:3000/posts?page=1上的所有帖子保持不变,直到再次访问localhost:3000(根路径) 问题是它会对文章进行分页,但它会针对所选的每一页重新排序,所以您经常会在第1页和第2页看到文章。一种方法是设置数据库排序依据的顺序,以便每次都返回相同的随机数序列。您可以将此种子存储在用户

我想知道是否还有什么方法可以继续使用
。order(“RANDOM()”
)和
将分页,这样当一个页面加载并对页面进行排序时,在重新加载主页之前,每个页面上的所有帖子都将保持不变

因此,要使
localhost:3000/posts?page=1上的所有帖子保持不变,直到再次访问
localhost:3000(根路径)


问题是它会对文章进行分页,但它会针对所选的每一页重新排序,所以您经常会在第1页和第2页看到文章。

一种方法是设置数据库排序依据的顺序,以便每次都返回相同的随机数序列。您可以将此种子存储在用户会话中,并仅在需要时重置它。但是,有一个复杂的问题——即使设置随机种子每次都会产生相同的随机数顺序,也不能保证数据库每次都会以相同的顺序在您的行上执行它,除非您强制它这样做:

SELECT items.*
FROM (SELECT setseed(0.2)) t
   , (SELECT name, rank() OVER (ORDER BY name DESC)
      FROM foos ORDER BY name DESC) items
   JOIN generate_series(1, (SELECT COUNT(*) FROM foos))
     ON items.rank = generate_series
ORDER BY RANDOM()
LIMIT 10;
可以看出,这相当复杂,它迫使数据库将整个表具体化到内存中。它适用于较小的数据集,但如果你有一个大数据集,这是不可能的

相反,我建议您使用一种更像这样的解决方案:生成一页结果,将ID存储到会话中,当您需要生成下一页时,只需忽略您已经向用户显示的任何内容。代码如下所示:

class ThingsController < ApplicationController
  def index
    @page = params[:page].to_i
    session[:pages] ||= {}

    if ids = session[:pages][@page]
      # Grab the items we already showed, and ensure they show up in the same order.
      @things = Things.where(id: ids).sort_by { |thing| ids.index(thing.id) }
    else 
      # Generate a new page of things, filtering anything we've already shown.
      @things = Things.where(["id NOT IN (?)", shown_thing_ids])
                      .order("RANDOM()")
                      .limit(30) # your page size
      # Save the IDs into our session so the above case will work.
      session[:pages][@page] = @things.map(&:id)
    end
  end

  private
  def shown_thing_ids
    session[:pages].values.flatten
  end
end

希望有帮助!您也可以使用Redis或Memcache来存储页面数据,但是如果您希望每个用户的顺序是随机的,那么会话是一个不错的选择。

您运行的是什么数据库?在Postgres中,可以使用setseed()生成可重复的排序。在这种情况下,您可以在会话中生成一个
seed
值,仅当您希望更改顺序时才能重新生成该值。请告诉我您使用的是哪一个数据库,我可以提供更全面的解决方案。您可能希望将分页结果持久化到数据库中,以保持请求之间的顺序。非常感谢您的详细回复。我相信尝试这样做可能超出了我的能力和技能,我的数据库将相当大,所以这可能也是一个问题。再次感谢!
session.delete(:pages)