我需要查找特定资源的所有记录并以随机顺序显示它们,但是具有一致的分页(如果开始分页,则不会看到相同的记录两次)。每次用户访问页面时,显示顺序应该是随机的。我正在使用will_paginate。有什么建议吗?
答案 0 :(得分:5)
在用户会话cookie中存储随机数,然后将其用作数据库随机函数的种子。在用户关闭浏览器之前,这将是相同的,因此他们都会看到随机,一致的记录:
获取一个大的随机数:
cookies[:seed] = SecureRandom.random_number.to_s[2..20].to_i
将此种子用于例如MySQL的:
SomeModel.all.order("RAND ?", cookies[:seed])
答案 1 :(得分:2)
据我所知,这不是标准。我可以看到这样的用途,例如用于在线测试。
我建议每个会话/用户使用一个列表。因此,当用户首次进入该页面时,您将以随机顺序确定ID列表,并使用此列表显示所有连续视图,以显示该用户/会话的正确顺序。
我希望行数量有限,然后这是有意义的,例如测试。此外,当用户在完成测试之前离开测试时,她可以继续他离开的地方。但也许这与你无关。
希望这有帮助。
答案 2 :(得分:1)
如果您使用的是MySQL等具有随机函数的数据库,例如RAND()
,您可以将其添加到您的分页查询中,如下所示:
Resource.paginate( ... :order => "RAND()" ... )
查看以下有关性能问题的一些评论:https://rails.lighthouseapp.com/projects/8994/tickets/1274-patch-add-support-for-order-random-in-queries
答案 3 :(得分:1)
不确定您是否仍需要帮助。我过去做过的一个解决方案是使用RAND进行查询,但最初没有分页。然后存储这些记录ID并使用该存储列表从那里查找和分页。初始RAND查询可以设置为仅在页面为1或nil时运行。只是一个想法。
答案 4 :(得分:0)
我最终得到了这个适用于Postgres的解决方案:
session[:seed] ||= rand() # should be between [-1..1]
seed = session[:seed]
Product.select("setseed(#{seed})").first
Product.order('random()').limit(10).offset(params[:offset])