J'essayais de sélectionner des objets uniq par un attribut, en utilisant @videos.uniq{|p| p.author}
time = Time.new(2014, 12)
start_time = time.beginning_of_month
end_time = time.end_of_month
videos = Video.where("created_at > ? AND created_at < ?", start_time, end_time).where("likes > ?", 15)
selected_videos = videos.uniq{|p| p.author}
puts videos.count, videos.class, selected_videos.count
#=> 23, Video::ActiveRecord_Relation, 23
videos_first = videos.first(23)
selected_videos = videos_first.uniq{|p| p.author}
puts videos_first.count, videos_first.class, selected_videos.count
#=> 23, array, 10
.uniq
n'est pas pour ActiveRecord_Relation
. Et le problème est que la requête renvoie un Video::ActiveRecord_Relation
, mais il me faut array
.
Ceci pourrait certainement être réalisé en utilisant to_a
, mais est-ce élégant?
.uniq
pour activerecord:relation
?Si vous devez accéder au résultat de la requête, utilisez simplement #to_a
sur l'instance ActiveRecord :: Relation.
Sur guides Rails , vous pouvez trouver des modifications importantes sur Rails 4.0: "Model.all renvoie désormais une ActiveRecord :: Relation, plutôt qu'un tableau d'enregistrements. Utilisez Relation #to_a si vous voulez vraiment un tableau. Dans certains cas, cela peut causer une panne lors de la mise à jour. "Ceci est valable pour d'autres méthodes de relation telles que: où.
selected_videos = videos.to_a.uniq{|p| p.author}
.uniq
N'a pas beaucoup de sens quand il est appliqué à l'ensemble de l'enregistrement actif.
Étant donné qu'au moins un des trois attributs - id
, created_at
Et updated_at
- est différent pour chaque ligne, appliquant videos.uniq{|p| p.author}
Où videos
est un ActiveRecord::Relation
incluant tous les champs, retournera toutes les lignes du ActiveRecord::Relation
.
Lorsque l'objet ActiveRecord::Relation
Comporte un sous-ensemble de valeurs, uniq
pourra en déterminer les valeurs distinctes.
Par exemple: videos.select(:author).uniq.count
donnera 10 dans votre exemple.
La différence entre ActiveRecord::Relation#uniq
Et Array#uniq
Réside dans le fait que la version Array accepte un bloc et utilise la valeur de retour d'un bloc à des fins de comparaison. La version ActiveRecord :: Relation de uniq ignore simplement le bloc.