0

Je les associations suivantes:Ne peut pas utiliser avec groupe has_many par Rails 5

class Student < ApplicationRecord 
    has_many :people_schools 
    has_many :schools, through: :people_schools 
end 

class PeopleSchool < ApplicationRecord 
    belongs_to :student 
    belongs_to :school 
end 

class School < ApplicationRecord 
    has_many :people_schools 
    has_many :students, through: :people_schools 
end 

Je suis en train d'obtenir une liste des étudiants organisée par leur école. Je l'ai essayé ce qui suit:

Student.joins(:schools).all.group('schools.name') 

mais je reçois l'erreur suivante:

ActiveRecord::StatementInvalid: PG::GroupingError: ERROR: column "students.id" must appear in the GROUP BY clause or be used in an aggregate function 

Comment puis-je résoudre ce problème?

+0

Un étudiant peut-il fréquenter de nombreuses écoles («has_many: schools») ou devrait-il toujours en être un («has_one: school»)? Ou même 'belongs_to: school' sans la table de jointure? – ulferts

Répondre

0

Lorsque les feux de l'association, il va générer une requête SQL comme

SELECT students.id, students. ... 
FROM students 
JOIN schools 
ON ... 
GROUP BY schools.name 

Dans sql lors du regroupement, une projection (SELECT) ne peut inclure des colonnes qui sont regroupées par ou agrégations (par exemple MAX, MIN) de colonnes (indépendamment du fait qu'elles sont groupées par). Par conséquent ajouter quelque chose comme ce qui suit se transformer en un sql valide:

# column that is grouped by 
Student.joins(:schools).group('schools.name').select('schools.name') 
# aggregate function 
Student.joins(:schools).group('schools.name').select('schools.name, COUNT(students.id)') 

Mais comment vous voulez le fixer dans votre cas dépend de ce que vous voulez sortir de la requête.

En réponse au commentaire

En supposant un étudiant est seul membre d'une seule école, ce qui nécessite une modification de l'association à un belongs_to :school (sans la table de jointure) ou un has_one :school (avec table de jointure).

Student.includes(:school).group_by(&:school) 

Ceci va générer une instruction SQL pour obtenir tous les élèves et leur école (impatiemment chargé pour l'optimisation). Seulement après que les modèles (Étudiant, École) sont des objets ruby ​​instanciés, la méthode group_by est évaluée, ce qui retournera un Hash où l'école est la clé référençant un tableau d'élèves.

+0

Il y a 12 écoles. J'essaie d'obtenir un tableau de 12 tableaux. Dans chacun de ces 12 tableaux sont des étudiants de chaque école. J'ai utilisé group_by pour le faire sans has_many à travers avant. – Philip7899