module Randomizable
  extend ActiveSupport::Concern

  class_methods do
    def sort_by_random(seed = rand(10_000_000))
      ids = 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

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

Make random IDs with the same seed consistent
Make random IDs with the same seed consistent

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.
