Aaron
Aaron

Reputation: 14029

Mysterious SELECT COUNT(*) appearing in my controller for has_many relationship

I'm unable at the moment to track down when I started seeing a SELECT COUNT(*) call in my development log but it is happening and there doesn't seem to be a reason for it. I'd like to know if this is normal and/or why it is happening. I don't think it's a major problem but why have an extra call to the database if I don't need it.

In my controller I have

def some_action
  @activities = user.activities
end

In the User class, I have that it has_many :activities

and when I call this action, my log output is

User Load (0.4ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
(0.3ms)  SELECT COUNT(*) FROM "activities" WHERE "activities"."user_id" = 1
Activity Load (0.3ms)  SELECT "activities".* FROM "activities" WHERE "activities"."user_id" = 1

All I can tell you for sure is that it didn't use to do that SELECT COUNT(*) call and as far as I can tell, there is nothing trying to get that count.

I'm using Rails 3.2.6 and PostgreSQL 9.

Upvotes: 1

Views: 107

Answers (1)

Aaron
Aaron

Reputation: 14029

I've found the reason for the count query is due to Rails' lazy loading and the order in which I'm using my data.

While I iterate over all the @activities, the first thing I do with the instance variable in my view template is check if there are any to go through. If not I display something different to the user.

@activities.empty? is performing the count and comparing it to 0 which is more efficient than loading all the records into an array and then checking that. I can optionally change my action to be

@activities = user.activities.all

which prevents the COUNT call and loads all records before constructing the view.

Upvotes: 1

Related Questions