我的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 %>
改为
<% @portfolio.shuffle.first(6).each do |portfo| %>