ActiveRecord: taille contre nombre

Dans Rails, vous pouvez trouver le nombre d’enregistrements à l’aide de Model.size et Model.count . Si vous avez affaire à des requêtes plus complexes, y a-t-il un avantage à utiliser une méthode plutôt qu’une autre? Comment sont-ils différents?

Par exemple, j’ai des utilisateurs avec des photos. Si je veux afficher un tableau des utilisateurs et combien de photos ils ont, l’exécution de plusieurs instances de user.photos.size sera- user.photos.size elle plus rapide ou plus lente que user.photos.count ?

Merci!

Vous devriez lire cela , c’est toujours valide.

Vous adapterez la fonction que vous utilisez en fonction de vos besoins.

Fondamentalement:

  • Si vous chargez déjà toutes les entrées, disons User.all , vous devez utiliser la length pour éviter une autre requête de firebase database.

  • Si vous n’avez rien chargé, utilisez count pour effectuer une requête de comptage sur votre firebase database.

  • si vous ne voulez pas vous soucier de ces considérations, utilisez une size qui s’adaptera

Comme les autres réponses l’indiquent:

  • count effectuera une requête SQL COUNT
  • length calculera la longueur du tableau résultant
  • size tentera de choisir le plus approprié des deux pour éviter les requêtes excessives

Mais il y a encore une chose. Nous avons remarqué un cas où la size agit différemment pour count / length , et j’ai pensé que je la partagerais car il est assez rare pour être négligé.

  • Si vous utilisez a :counter_cache sur une association has_many , size utilisera directement le nombre mis en cache, sans faire de requête supplémentaire.

     class Image < ActiveRecord::Base belongs_to :product, counter_cache: true end class Product < ActiveRecord::Base has_many :images end > product = Product.first # query, load product into memory > product.images.size # no query, reads the :images_count column > product.images.count # query, SQL COUNT > product.images.length # query, loads images into memory 

Ce comportement est documenté dans les guides Rails , mais je l’ai manqué la première fois ou je l’ai oublié.

Parfois, la size “choisit la mauvaise” et renvoie un hash (ce qui ferait le count )

Dans ce cas, utilisez length pour obtenir un entier au lieu du hachage .

Les stratégies suivantes appellent toutes la firebase database pour exécuter une requête COUNT(*) .

 Model.count Model.all.size records = Model.all records.count 

Ce qui suit n’est pas aussi efficace qu’il va charger tous les enregistrements de la firebase database dans Ruby, qui compte alors la taille de la collection.

 records = Model.all records.size 

Si vos modèles ont des associations et que vous souhaitez rechercher le nombre d’objects appartenant (par exemple, @customer.orders.size ), vous pouvez éviter les requêtes de firebase database (lectures de disque). Utilisez un cache de compteur et Rails gardera la valeur de cache à jour et renverra cette valeur en réponse à la méthode de size .