The order of the array before being shuffled needs to be the same if we want to have the same array after being shuffled with a certain seed. We were using `pluck(:id)`, which doesn't guarantee the order of the elements returned. Replacing it with `order(:id).pluck(:id)` adds an `ORDER BY` clause and so guarantees the order of the elements.
17 lines
462 B
Ruby
17 lines
462 B
Ruby
module Randomizable
|
|
extend ActiveSupport::Concern
|
|
|
|
class_methods do
|
|
def sort_by_random(seed = rand(10_000_000))
|
|
ids = order(:id).pluck(:id).shuffle(random: Random.new(seed))
|
|
|
|
return all if ids.empty?
|
|
|
|
ids_with_order = ids.map.with_index { |id, order| "(#{id}, #{order})" }.join(", ")
|
|
|
|
joins("LEFT JOIN (VALUES #{ids_with_order}) AS ids(id, ordering) ON #{table_name}.id = ids.id")
|
|
.order("ids.ordering")
|
|
end
|
|
end
|
|
end
|