![](/img/trans.png)
[英]How do you efficiently (in a DB independent manner) select random records from a table?
[英]How to select 6 random records from table
我的portfolio_controller.rb
有一个这样的索引方法:
def index
@portfolio = PortfolioItem.all
end
如何在条件中指定该块中的代码应执行 6 次? 换句话说,如何使用循环从我的视图中的@portfolio
对象中准确访问 6 个值? 这是我到目前为止:
<% @portfolio.shuffle.each do |portfo| %>
使用all
,然后使用shuffle
,是一个糟糕的解决方案,原因有两个。
一个小小的改进是使用sample(6)
而不是shuffle.first(6)
,因为这从过程中删除了一个步骤。
然而,这里更大的问题是Portfolio.all.<something>
(其中<something>
方法需要将数据转换为 ruby Array
)会将所有数据提取到内存中 - 这是一个坏主意。 随着表的增长,这将成为一个更大的性能问题。
更好的想法是在 SQL 中执行“随机选择”(使用order
和limit
方法),而不是在 ruby 中。 这避免了将其他数据提取到内存中的需要。
不幸的是,确切的解决方案是特定于数据库的。 对于 PostgreSQL 和 SQLite,请使用:
Portfolio.order('RANDOM()').limit(6).each do |portfolio|
或者对于 MySQL,使用:
Portfolio.order('RAND()').limit(6).each do |portfolio|
您可以将其定义为Portfolio
模型中的助手 - 例如:
class Portfolio < ApplicationRecord
# ...
scope :random_sample, ->(n) { order('RANDOM()').limit(n) }
# ...
end
然后在你看来:
@portfolio.random_sample(6).each do |portfolio|
你可以这样:
<%(1..6).each do |i| %>
<% #your statements %>
<%end%>
<% @portfolio.shuffle.each_with_index do |portfo, index| %>
<%if index <= 6%>
<p><%= portfo.title %></p>
<%end%>
<% end %>
或者你可以这样做
<% @portfolio.shuffle.take(6).each do |portfo| %>
<p><%= portfo.title %></p>
<% end %>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.