# Avoid N+1 Queries # Example Application: # User has many followers # BAD user.followers.collect{ |f| f.user.name } # Queries generated # select followers where user_id = 1 # select user where id=2 # select user where id=3 # .................. # Good user.followers.includes(:user){ |f| f.user.name } # Queries generated # select followers where user_id = 1 # select user where id in(2,3,..) # Counter Caching # we want to get the number of retweets of a tweet # BAD tweet.retweets.length # Load the tweets into array and then call .length on that array # Better tweet.retweets.size OR tweet.retweets.count # make a count query to the db # What if the above query is made in a loop? many queries right? # Best using counter caching # Add column retweets_count to the tweet model # app/models/tweet.rb belongs_to :original_tweet, class_name: 'Tweet', foreign_key: 'tweet_id', counter_cache: :retweets_count has_many :retweets, class_name: 'Tweet', foreign_key: 'tweet_id' tweet.retweets.size # No query , only look at the cache as the 'tweet' object is already fetched