Укладка каждого на каждом на каждом в Ruby

#ruby-on-rails #ruby #loops

#ruby-on-rails #ruby #циклы

Вопрос:

Я перебираю некоторые ActiveRecord модели, подобные этой:

(Например, предположим, что вы не можете напрямую получить все жанры animal. Это повторение связанного вопроса, а не ассоциативный материал):

 Animal.all.each do |animal|
    animal.families.each do |family|
        family.genres.each do |genre|
            genre.gsub("o","a")
            genre.save!
        end
    end
end
  

Я не думаю, что это лучший способ сделать это. Есть ли какое-либо решение для улучшения? Как один итератор, который будет работать .each на each модели?

Комментарии:

1. Если у вас нет необходимости группировать жанры по семейству, зачем вы вкладываете каждый из них?

Ответ №1:

Один из способов ускорить это — попытаться сначала выполнить все запросы.

 animals = Animal.includes(families: genres)
animals.each do |animal|
  animal.families.each do |family|
    family.genres.each do |genre|
      genre.gsub("o","a")
      genre.save!
    end
  end
end
  

Ответ №2:

Как насчет использования flat_map :

 Animal.all.flat_map(amp;:families).flat_map(amp;:genres).each do |genre|
  genre.gsub("o","a")
  genre.save!
end
  

(это, конечно, полностью игнорирует любые ActiveRecord связанные решения, которые будут лучше)