#ruby-on-rails #ruby
#ruby-on-rails #ruby
Вопрос:
Итак, у меня есть массив «идентификаторов победителей», этот массив представляет пользователей, которые выиграли в предыдущем раунде турнира. Затем у меня есть массив объектов под названием «участие в турнире», он представляет всех пользователей, которые участвовали в турнире (таблица соединений многие ко многим).
Для каждого «идентификатора победителя» я хочу выполнить итерацию по массиву «участие в турнире» и найти участие в турнире с идентификатором пользователя, который соответствует «идентификатору победителя», затем поместить его в новый массив под названием «участие в раунде»…
Я пробовал приведенный ниже код, но мне всегда возвращается исходный массив winner_ids….
@challenges = Challenge.where(tournament_id: @tournament.id)
@winner_ids = @challenges.pluck(:winner_id)
@tournament_participations = @tournament.tournament_participations
@round_participations = []
@round_participations = @winner_ids.each do |winner_id|
@round_participation = @tournament_participations.where(user_id: winner_id)
@round_participations << @round_participation
end
Комментарии:
1. Попробуйте удалить присваивание
@round_participations = @winner_ids.each
.2. Я бы поискал решение, в котором вы используете базу данных для извлечения правильных записей вместо того, чтобы вытаскивать все и делать это в ruby, который вообще не будет масштабироваться. Если вы приведете нам пример схемы, данных и желаемого результата, мы сможем дать вам лучший ответ, чем исправление вашей ошибочной попытки.
3. Очевидно, сегодня я слишком долго сидел за компьютером… Удаление присвоения round_participation сработало, и теперь у меня есть массив объектов для участия в турнирах, спасибо Бруно ниже! @max У меня сложилось впечатление, что чем меньше обращений к базе данных, тем лучше, поэтому вам лучше всего извлекать данные за один вызов и работать с ними в Ruby, отсюда и методология. Я также недавно пытался еще больше повысить скорость с помощью таких методов, как . используйте pluck (используется выше), чтобы попытаться работать только с теми атрибутами, которые вам нужны… Если это не так, мы могли бы посмотреть на другой способ.
4. Ограничение количества вызовов базы данных, как правило, является хорошим способом повышения производительности. Но извлечение всех записей из базы данных приведет к исчерпанию памяти на вашем сервере (приложения) и приведет к его сбою, если у вас нетривиальный объем данных. Кроме того, базы данных действительно хороши в сортировке, объединении и выполнении подобных действий очень быстро, в то время как извлечение всего, а затем выполнение этого в Ruby довольно медленно. Итак, ваш вывод неверен.
5. Кроме того, этот код на самом деле является действительно хорошим примером запроса N 1.
@tournament_participations.where(user_id: winner_id)
вызовет дополнительный цикл обращения к базе данных для каждой итерации. Вместо этого вам следует выполнить один запрос к базе данных, который объединяет соответствующие таблицы, что вы, скорее всего, сможете сделать, просто правильно настроив свои ассоциации. Это немного важнее, чемpluck
просто выбирать нужные столбцы, что все равно, что накладывать макияж на свинью.
Ответ №1:
each
возвращает перечислимое, на которое оно было вызвано; в данном случае @winner_ids.each
возвращается @winner.ids
. Вам не нужно присваивать результат итерации @round_participations
.
Кроме того, ознакомьтесь с map
методом.
Ответ №2:
Используйте метод map вместо .each.
Метод map можно использовать для создания нового массива на основе исходного массива, но со значениями, измененными предоставленным блоком. Смотрите пример ниже.
В случае каждого метода
irb(main):001:0> arr = [1, 2, 3, 4, 5]
=> [1, 2, 3, 4, 5]
irb(main):002:0> arr.each { |a| print a -= 10, " " }
-9 -8 -7 -6 -5
=> [1, 2, 3, 4, 5]
вы можете видеть, что после итераций он вернул исходный массив. Но в случае map
irb(main):005:0> arr = [1, 2, 3, 4, 5]
=> [1, 2, 3, 4, 5]
irb(main):006:0> arr.map { |a| 2*a }
=> [2, 4, 6, 8, 10]
map может преобразовывать содержимое массива, что означает, что он может выполнять операцию над каждым элементом в массиве.
Комментарии:
1. Спасибо sk1712! Избавление от назначения сработало, но также могло бы использовать .map 🙂