# How to preload Rails scopes

DevFeed: [How to preload Rails scopes](<https://devfeed.tech/articles/how-to-preload-rails-scopes-26272.md>)

Original publisher: [Read original article](<https://www.justinweiss.com/articles/how-to-preload-rails-scopes/>)

Author: Justin Weiss

Published: 2015-06-23T20:17:34Z

Content type: tutorial

Language: en

Sources: [Justin Weiss](<https://devfeed.tech/sources/justin-weiss.md>)

Topics: [Rails](<https://devfeed.tech/topics/rails.md>), [App](<https://devfeed.tech/topics/app.md>), [SQL](<https://devfeed.tech/topics/sql.md>)

Tags: [activerecord](<https://devfeed.tech/tags/activerecord.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [performance](<https://devfeed.tech/tags/performance.md>), [rails](<https://devfeed.tech/tags/rails.md>)

## AI overview

This tutorial explains why Rails scopes can cause N+1 queries when loading related records. It shows how to wrap a scope in an association so it can be preloaded, reducing the example from six SQL calls to two, and recommends keeping the scope definition in one place.

## Source excerpt

This article is also available in Korean, thanks to Soonsang Hong! Rails' scopes make it easy to find the records you want: app/models/review.rbclass Review < ActiveRecord::Base belongs_to :restaurant scope :positive, -> { where("rating > 3.0") } end irb(main):001:0> Restaurant.first.reviews.positive.count Restaurant Load (0.4ms) SELECT `restaurants`.* FROM `restaurants` ORDER BY `restaurants`.`id` ASC LIMIT 1 (0.6ms) SELECT COUNT(*) FROM `reviews` WHERE `reviews`.`restaurant_id` = 1 AND (rating > 3.0) => 5 But if you're not careful with them, you'll seriously hurt your app's performance. Why? You can't really preload a scope. So if you tried to show a few restaurants with their positive reviews: irb(main):001:0> restauraunts = Restaurant.first(5) irb(main):002:0> restauraunts.map do |restaurant| irb(main):003:1* "#{restaurant.name}: #{restaurant.reviews.positive.length} positive reviews." irb(main):004:1> end Review Load (0.6ms) SELECT `reviews`.* FROM `reviews` WHERE `reviews`.`restaurant_id` = 1 AND (rating > 3.0) Review Load (0.5ms) SELECT `reviews`.* FROM `reviews` WHERE `reviews`.`restaurant_id` = 2 AND (rating > 3.0) Review Load (0.7ms) SELECT `reviews`.* FROM `reviews` WHERE `reviews`.`restaurant_id` = 3 AND (rating > 3.0) Review Load (0.7ms) SELECT `reviews`.* FROM `reviews` WHERE `reviews`.`restaurant_id` = 4 AND (rating > 3.0) Review Load (0.7ms) SELECT `reviews`.* FROM `reviews` WHERE `reviews`.`restaurant_id` = 5 AND (rating > 3.0) => ["Judd's Pub: 5 positive reviews.", "Felix's Nightclub: 6 positive reviews.", "Mabel's Burrito Shack: 7 positive reviews.", "Kendall's Burrito Shack: 2 positive reviews.", "Elisabeth's Deli: 15 positive reviews."] Yep, that's an N+1 query. The biggest cause of slow Rails apps. You can fix this pretty easily, though, if you think about the relationship in a different way. Convert scopes to associations When you use the Rails association methods, like belongs_to and has_many, your model usually looks like this: app/models/re