Подтвердить что ты не робот

Rails 4: найти все записи

Теперь, когда ActiveRecord:: Relation # все устарели в Rails 4, как вы должны перебирать все записи?

Используется для:

Foo.all.each do |foo|
  # whatever
end

Я могу приблизить его сейчас так, но он чувствует себя грязным:

Foo.where(true).each do |foo|
  # whatever
end

Есть ли лучший способ?

4b9b3361

Ответ 1

В соответствии с Rails Guide на Active Request Query Interface правильный путь к итерации по всем записям осуществляется с помощью find_each.

Использование Foo.all.each будет загружать таблицу целиком в память, создавая экземпляры всех строк; затем перебирать экземпляры. find_each делает это партиями, что более эффективно с точки зрения использования памяти.

Из руководства:

Метод find_each извлекает партию записей, а затем выводит каждую запись в блок по отдельности в качестве модели. В следующем примере find_each будет извлекать 1000 записей (текущий по умолчанию как для find_each, так и find_in_batches), а затем каждый отдельный экземпляр каждой записи записывать в блок как модель. Этот процесс повторяется до тех пор, пока все записи не будут обработаны:

User.find_each do |user|
  NewsLetter.weekly_deliver(user)
end

Литература:

Ответ 3

Примечания к выпуску для Rails 4:

Model.all теперь возвращает ActiveRecord:: Relation, а не массив записей. Используйте Relation # to_a, если вы действительно хотите массив.

Итак, ваш код будет выглядеть так:

Foo.all.to_a.each do |foo|
  # whatever
end

См. http://guides.rubyonrails.org/4_0_release_notes.html#active-record

Ответ 4

Это, по-видимому, предупреждение о некорректном предупреждении где-то в Rails. Начиная с Rails 4.0.2 предупреждающее сообщение все еще существует. Я получаю следующую ошибку, когда я пытаюсь запустить Foo.all:

ПРЕДУПРЕЖДЕНИЕ О ДЕПРЕКАЦИИ: Отношение # все устарело. Если ты хочешь eager-load отношение, вы можете вызвать #load (например, Post.where(published: true).load). Если вы хотите получить массив записей из отношения, вы можете вызвать #to_a (например, Post.where(published: true).to_a).

Я почти на 100% уверен, что я смотрел в RailsCasts, что #all был изменен, чтобы возвращать Relation in Rails 4 (вместо массива) - не упоминание об отказе.