Использование all
, за которым следует shuffle
, является плохим решением по двум причинам.
Небольшим улучшением было бы использование sample(6)
вместо shuffle.first(6)
, так как это удаляет шаг из процесса.
Тем не менее, большая проблема заключается в том, что Portfolio.all.<something>
(где метод <something>
требует преобразования данных в рубин 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|