问题
I have the following associations:
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
I am trying to get a list of students organized by their school. I have tried the following:
Student.joins(:schools).all.group('schools.name')
but I get the following error:
ActiveRecord::StatementInvalid: PG::GroupingError: ERROR: column "students.id" must appear in the GROUP BY clause or be used in an aggregate function
How do I fix this?
回答1:
When the association fires, it will generate a SQL query like
SELECT students.id, students. ...
FROM students
JOIN schools
ON ...
GROUP BY schools.name
In sql when grouping, a projection (SELECT) can only include columns that are grouped by or aggregations (e.g. MAX, MIN) of columns (regardless of whether they are grouped by). Therefore adding something like the following would turn it into a valid sql:
# 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)')
But how you want to fix it in your case depends on what you want to get out of the query.
In answer to the comment
Assuming a student is only member of a single school, which requires changing the association to a belongs_to :school (without the join table) or a has_one :school (with join table).
Student.includes(:school).group_by(&:school)
This will issue an SQL statement to get all students and their school (eager loaded for optimization). Only after the models (Student, School) are instantiated ruby objects, is the group_by method evaluated, which will return a Hash where the school is the key referencing an Array of students.
来源:https://stackoverflow.com/questions/46572540/cannot-use-group-with-has-many-through-in-rails-5