Я ищу лучший способ получить размер набора запросов в рельсах. Тем не менее, элементы обновляются в al oop, и мне нужно количество элементов перед обновлением. Вот пример кода (BUGGY!).
p = participations.where(invited_at: nil).limit(50)
p.each do |participation|
# Invite may raise an exception, but also contains operations that
# cannot be undone
participation.invite()
participation.invited_at = Time.zone.now
participation.save
end
DoStuff() if p.count > 0
Этот код не работает, потому что вызов на p.count
создает новый запрос к базе данных, который не учитывает записи, которые были обновлены в l oop. Поэтому, если имеется менее 50 записей, все они обновляются и DoStuff()
не вызывается.
Какой самый идиоматический c способ в рельсах для обработки этого:
- Переместите
if p.count
часть из l oop и введите l oop, только если есть какие-либо записи? - Замените
p.count
на p.size
(если я понимаю size
правильно, это не должно вызывать каких-либо дополнительных запросов) - Подсчитайте количество итераций в l oop и затем используйте это число
У меня такое ощущение, что 1 больше всего идиомати c в ruby, но я не очень разбираюсь в этом языке.
РЕДАКТИРОВАТЬ : улучшенный пример, немного ближе к исходному коду.
РЕДАКТИРОВАТЬ :
Проблема не в запросах на обновление, выполняемых участниками l oop. Эти запросы должны быть отдельными запросами, чтобы отслеживать, какие участия уже были обработаны, даже если возникла ошибка. Скорее проблема в том, что DoStuff()
следует вызывать всякий раз, когда в l oop были обработаны какие-либо записи. Однако, поскольку count
выполняет новый запрос ПОСЛЕ , записи были обработаны, если будет обработано менее 50 элементов, все будут обновлены и DoStuff()
не будет вызван.