简体   繁体   English

如何从表中选择6条随机记录

[英]How to select 6 random records from table

My portfolio_controller.rb has an index method like this:我的portfolio_controller.rb有一个这样的索引方法:

def index
  @portfolio = PortfolioItem.all
end

How can I specify in the condition that the code in this block should be executed 6 times?如何在条件中指定该块中的代码应执行 6 次? In other words, how can I access exactly 6 values from the @portfolio object in my view, using a loop?换句话说,如何使用循环从我的视图中的@portfolio对象中准确访问 6 个值? This is what I have so far:这是我到目前为止:

<% @portfolio.shuffle.each do |portfo| %>

Using all , followed by shuffle , is a bad solution for two reasons.使用all ,然后使用shuffle ,是一个糟糕的解决方案,原因有两个。

A slight improvement would be to use sample(6) instead of shuffle.first(6) , as this removes a step from the process.一个小小的改进是使用sample(6)而不是shuffle.first(6) ,因为这从过程中删除了一个步骤。

However, the bigger issue here is that Portfolio.all.<something> (where the <something> method requires converting the data into a ruby Array ) will fetch all of the data into memory - which is a bad idea.然而,这里更大的问题是Portfolio.all.<something> (其中<something>方法需要将数据转换为 ruby Array )会将所有数据提取到内存中 - 这是一个坏主意。 As the table grows, this will become a bigger performance issue.随着表的增长,这将成为一个更大的性能问题。

A better idea is to perform the "random selection" in SQL (with the order and limit methods), rather than in ruby.更好的想法是在 SQL 中执行“随机选择”(使用orderlimit方法),而不是在 ruby​​ 中。 This avoids the need to fetch other data into memory.这避免了将其他数据提取到内存中的需要。

The exact solution is database-specific, unfortunately.不幸的是,确切的解决方案是特定于数据库的。 For PostgreSQL and SQLite, use:对于 PostgreSQL 和 SQLite,请使用:

Portfolio.order('RANDOM()').limit(6).each do |portfolio|

Or for MySQL, use:或者对于 MySQL,使用:

Portfolio.order('RAND()').limit(6).each do |portfolio|

You could define this as a helper in the Portfolio model - for example:您可以将其定义为Portfolio模型中的助手 - 例如:

class Portfolio < ApplicationRecord
  # ...

  scope :random_sample, ->(n) { order('RANDOM()').limit(n) }

  # ...
end

And then in your view:然后在你看来:

@portfolio.random_sample(6).each do |portfolio|

You can something like this :你可以这样:

 <%(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 %>

Or You can do it as或者你可以这样做

<% @portfolio.shuffle.take(6).each do |portfo| %>
    <p><%= portfo.title %></p>
<% end %>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM