Reputation: 22224
My use case is simple, I want to have 4 columns in the footer of my website with a list of categories in each column.
Here's my code - it's doing what I want it to do, however I have noticed it's making 4 calls to the database, when it should be doing only one to load the initial Category collection.
- categories = Category.order('name ASC')
- perColumn = (categories.size / 3).to_i
.row
.col-md-3
ul
- for category in categories.limit(perColumn)
li
= link_to category.name, category
.col-md-3
ul
- for category in categories.offset(perColumn).limit(perColumn)
li
= link_to category.name, category
.col-md-3
ul
- for category in categories.offset(perColumn * 2).limit(perColumn)
li
= link_to category.name, category
.col-md-3
ul
- for category in categories.offset(perColumn * 3).limit(perColumn)
li
= link_to category.name, category
Terminal output:
(0.1ms) SELECT COUNT(*) FROM "categories"
Category Load (0.2ms) SELECT "categories".* FROM "categories" ORDER BY name ASC LIMIT 6
Category Load (0.2ms) SELECT "categories".* FROM "categories" ORDER BY name ASC LIMIT 6 OFFSET 6
Category Load (0.2ms) SELECT "categories".* FROM "categories" ORDER BY name ASC LIMIT 6 OFFSET 12
Category Load (0.2ms) SELECT "categories".* FROM "categories" ORDER BY name ASC LIMIT 6 OFFSET 18
Any suggestions?
Upvotes: 0
Views: 62
Reputation: 15955
ActiveRecord does not query the database until you actually use the recrod, so in this case categories
contains the information needed to execute your query but not the result itself. You add on to the categories
offset and limit your query three times before you actually use it, so it only uses the offset and limited query, thus needing to make three calls. If you want to only make on call, you can do this:
categories = Category.order('name ASC').to_a
and then instead of
for category in categories.offset(perColumn * X).limit(perColumn)
With
for category in categories.shift(perColumn)
Note that shift removes the first N=perColumn elements from the array and returns them, so you wont be able to use categories later.
My honest opinion is that your database software will be able to compute this result much quicker than your ruby code. You are prematurely optimizing, and those 4 db queries don't really matter that much.
Upvotes: 3