Я бы не стал делать это (или что-нибудь еще!) В ActiveRecord, добавив это вашему пользователю.
count
считает количество элементов в вашей таблице исохраняя этот номер в c
.Тогда rand(c)
дает случайное целое число в интервале [0,c)
(то есть 0 <= rand(c) < c
).:offset
работает так, как вы думаете.
rand
не очень дорого, но выполнение order by random()
внутри базы данных может быть очень дорогим.Рассматриваемый метод random
- это просто удобный способ получить случайную запись / объект из базы данных.
Добавление его к вашему собственному пользователю будет выглядеть примерно так:
def self.random
n = scoped.count
scoped.offset(rand(n)).first
end
Это позволит вам связать random
после нескольких областей видимости:
u = User.canadians_eh.some_other_scope.random
, но результатом random
будет один пользователь, поэтому ваша цепочка на этом остановится.
Если вам нужно несколько пользователей, вам нужно будет звонить random
несколько раз, пока вы не наберете нужное количество пользователей.Вы можете попробовать это:
def self.random
n = scoped.count
scoped.offset(rand(n))
end
us = User.canadians_eh.random.limit(3)
, чтобы получить трех случайных пользователей, но пользователи будут объединены в кластеры в любом порядке, в котором база данных окажется после ваших других областей, и это, вероятно, не то, что вам нужно.Если вы хотите три, вам лучше использовать что-то вроде этого:
# In User...
def self.random
n = scoped.count
scoped.offset(rand(n)).first
end
# Somewhere else...
scopes = User.canadians_eh.some_other_scope
users = 3.times.each_with_object([]) do |_, users|
users << scopes.random
scopes = scopes.where('id != :latest', :latest => users.last.id)
end
Вы просто захватите случайного пользователя, обновите цепочку областей действия, чтобы исключить их, и повторяйте, пока не закончите.Вы, конечно, захотите сначала убедиться, что у вас было три пользователя.
Возможно, вы захотите вывести порядок из своей области действия canada
: одна область действия, одна задача.