Maintenant qu'ActiveRecord :: Relation # all est déconseillé dans Rails 4, comment êtes-vous censé répéter tous les enregistrements?
Autrefois:
Foo.all.each do |foo|
# whatever
end
Je peux l'approcher maintenant comme ça, mais ça fait sale:
Foo.where(true).each do |foo|
# whatever
end
Y a-t-il une meilleure façon?
Selon le Rails Guide on Active Record Query Interface , la bonne façon de parcourir tous les enregistrements est d'utiliser find_each
.
En utilisant Foo.all.each
chargera la mémoire entière en mémoire, en instanciant toutes les lignes; puis parcourez les instances. find_each
le fait par lots, ce qui est plus efficace en termes d'utilisation de la mémoire.
Du guide:
Le
find_each
la méthode récupère un lot d'enregistrements et renvoie ensuite chacun enregistrement au bloc individuellement en tant que modèle. Dans l'exemple suivant,find_each
récupérera 1000 enregistrements (la valeur par défaut actuelle pour les deuxfind_each
etfind_in_batches
), puis céder chaque enregistrement individuellement au bloc en tant que modèle. Ce processus est répété jusqu'à ce que tous les enregistrements aient été traités:
User.find_each do |user|
NewsLetter.weekly_deliver(user)
end
Les références:
oui, Foo.all
.
all
est obsolète sur un ActiveRecord :: Relation (par exemple Foo.where(true)
), pas sur ActiveRecord :: Base.
http://api.rubyonrails.org/classes/ActiveRecord/Scoping/Named/ClassMethods.html#method-i-all
Notes de publication pour Rails 4:
Model.all renvoie maintenant un ActiveRecord :: Relation, plutôt qu'un tableau d'enregistrements. Utilisez la relation # to_a si vous voulez vraiment un tableau.
Ainsi, votre code ressemblera à ceci:
Foo.all.to_a.each do |foo|
# whatever
end
Voir http://guides.rubyonrails.org/4_0_release_notes.html#active-record
Cela semble être un avertissement de dépréciation incorrect quelque part dans Rails. À partir de Rails 4.0.2 le message d'avertissement existe toujours. J'obtiens l'erreur suivante lorsque j'essaie d'exécuter Foo.all:
AVERTISSEMENT DEPRECATION: La relation # all est déconseillée. Si vous souhaitez charger une relation avec impatience, vous pouvez appeler #load (par exemple
Post.where(published: true).load
). Si vous souhaitez obtenir un tableau d'enregistrements à partir d'une relation, vous pouvez appeler #to_a (par exemplePost.where(published: true).to_a
).
Je suis presque sûr à 100% d'avoir regardé dans un RailsCasts que #all était modifié pour renvoyer une relation dans Rails 4 (au lieu d'un tableau) - aucune mention de dépréciation.