Project

dase

0.01
No commit activity in last 3 years
No release in over 3 years
includes_count_of method on ActiveRecord::Relation to solve N+1 query problem when counting associated records
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 10.3
~> 1.3

Runtime

>= 5.1.4, ~> 5.1
>= 5.1.4, ~> 5.1
 Project Readme

Build Status

Overview

Dase gem provides includes_count_of method on a relation, which works similar to ActiveRecord's preload method and solves N+1 query problem when counting records in has_many ActiveRecord associations.

Usage

Given this data in the DB: Dase example

and this Rails model definition

class Author
  has_many :articles
end

you can now write this:

  authors = Author.includes_count_of(:articles)
  billy = authors.first    # => #<Author name: 'Billy'>                
  billy.articles_count     # => 2                

with conditions on associated records (only articles in year 2012)

  Author.includes_count_of(:articles, where: {year: 2012} )

using lambda syntax (in v4.1 and greater)

  Author.includes_count_of(:articles, -> { where(year: 2012) } )

with renamed counter method

  Author.includes_count_of(:articles, -> { where(year: 2012) }, as: :number_of_articles_in_2012)

with multiple associations counted at once

  Author.includes_count_of(:articles, :photos, :tweets)

Installation

Rails version Add this to Gemfile
3.2.x gem 'dase', '~> 3.2.0'
4.0.x ----- N/A -----
4.1.x gem 'dase', '~> 4.1.0'
4.2.x gem 'dase', '~> 4.2.0'
5.1.x gem 'dase', '~> 5.1.0'

Under the hood

When a relation is "materialized", we run a custom preloader which calculates the hash of counters in a single SQL query like this:

  counters_hash = Article.where(:year => 2012).count(:group => :author_id)

then we add counters to the parent records like this:

  define_method(:articles_count) { counters_hash[author.id] || 0 }

Alternative approaches

Dase calculates counters dynamically every time you make an SQL query. It makes an extra SQL query for each association processed. These alternatives may be more efficient:

Name origin

The gem is named by the german mathematician Johann Dase, who was a mental calculator and could add and multiply numbers very quickly.

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Bitdeli Badge