2 votes

Méthode de relation d'enregistrement actif pour agréger les has_many associés

Considérez ces deux modèles :

class User < ApplicationRecord
  has_many :blogs
end

class Blog < ApplicationRecord
  belongs_to :user
end

J'aimerais faire quelque chose comme ça mais ça ne marchera pas :

my_users        = User.where(age: 35) 
all_assoc_blogs = my_users.blogs # errors out

Voici l'erreur :

Méthode non définie "Blogs" pour User::ActiveRecord_Relation :

Je comprends pourquoi cela ne fonctionne pas : vous pouvez seulement appeler blogs sur un seul user objet. Vous ne pouvez pas appeler blogs sur un objet de relation d'enregistrement actif de users .

En fin de compte, je veux un objet de relation d'enregistrement actif qui consiste en un agrégat de tous les blogs pour tous les utilisateurs dans l'application my_users objet de relation d'enregistrement actif. Existe-t-il un moyen simple de le faire ? C'est le seul moyen auquel je pense et il est assez laid :

my_users   = User.where(age: 35)
temp_blogs = []
my_users.each {|u| temp_blogs << u.blogs.to_a}
blog_ids = temp_blogs.flatten.pluck(:id)
Blog.where(id: blog_ids)

1voto

hernanvicente Points 374

L'enregistrement actif est celui pour lequel Metrodome vous renvoie une relation d'enregistrement actif, et non un résultat unique. Vous devez le faire :

my_users = User.where(age: 35).first

Vous devriez alors être en mesure d'obtenir les blogs d'un utilisateur avec :

my_users.blogs

Mais si votre intention est d'avoir tous les blogs de différents utilisateurs, vous devriez essayer :

my_user_ids = User.where(id: 35).pluck(:id)
Blog.where(user_id: my_user_ids)

1voto

piton4eg Points 158

Peut-être que cela vous aidera :

Blog.joins(:user).where(user: User.where(age: :35))

ou

Blog.joins(:user).merge(User.where(age: :35))

0voto

Neil Points 506

C'est ce que je recherchais :

my_users = User.where(age: 35)
Blog.where(user: my_users)

Ce qui me gênait, c'était que je devais changer de vitesse. J'ai d'abord saisi les données pertinentes users mais ensuite je passe ceux users en un Blog requête.

Puisque je veux finalement une relation d'enregistrement active de blogs le moyen le plus propre est de s'assurer que le modèle supérieur avec lequel je commence dans la requête est Blog .

0voto

Nick Ellis Points 699

Les autres réponses sont correctes, mais vous pouvez le faire plus efficacement et réduire les requêtes de votre base de données comme suit.

my_users = User.includes(:blogs).where(age: 35)  # this makes one db query to get all data
all_assoc_blogs = my_users.map(&:blogs)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X