Reputation: 110960
I have the following model:
ProfileViews (id, user_id, viewer_id)
I am trying to return all user_views, which are grouped by viewer_id ... Note viewer_id can nil, which is something I want to return. I can say viewed 20 times by nil etc...
Why does this not work?
@profile_views = ProfileView.select('*').where(:user_id => current_user.id).group(:viewer_id)
Upvotes: 1
Views: 342
Reputation: 434665
Your query doesn't work because you're using PostgreSQL (or some similarly strict database) and your SELECT list doesn't match your GROUP BY. Everything in your SELECT must either be inside an aggregate function (such as COUNT
, AVG
, ...) or it must appear in your GROUP BY clause; some databases, such as MySQL and SQLite, will take a guess to remove the ambiguity but other databases, such as PostgreSQL, will not. I'd guess that you're seeing an error similar to:
ERROR: column "X" must appear in the GROUP BY clause or be used in an aggregate function
You're probably looking for something more like this:
@profile_views = ProfileView.where(:user_id => current_user.id)
.count(:group => :viewer_id)
That will give you a simple Hash in @profile_views
which maps viewer_id
(including nil
s) to the number of views.
That bit of AR is equivalent to this SQL:
select viewer_id, count(*)
from profile_views
where user_id = #{current_user.id}
group by viewer_id
You'll note that everything in the SELECT is either in the GROUP BY or an aggregate.
You can't get the ProfileView objects at the same time as the counts. When you add a GROUP BY, you're collapsing rows that have the same viewer_id
and once the rows have lost their identities, there is no way for the database to choose which row should be used to instantiate the ProfileView.
Upvotes: 1
Reputation: 7111
I do not think you can have select(*)
in a group statement. You might try select count(viewer_id)
or whatever grouping you are going for.
Update
You can see more examples here
Upvotes: 0