dase 4.1.1 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b1a4d6f990d789d3a9a7a7d79995e3bd9177c98a
4
- data.tar.gz: 5c4be473b6ddc9a2c8933207044ae224d8ebe1bc
3
+ metadata.gz: 75b57d1d16a33aaf6039f6aff02fb26342ef15c3
4
+ data.tar.gz: bb177eeae7391ba894d15395d05917bb71b1de82
5
5
  SHA512:
6
- metadata.gz: 1b41222641e271a29db1a2c7d9283d00d005f9ebdca0317d13d2bb8a11daa1d16e3c490afd3ca86ddbceb5bb0b58bbc3d870ed057d09c40c6f2d5596b3b07fa3
7
- data.tar.gz: 4790d98c1bcfd56ba5e8334b0841814f5f4936163449a3c09b8d90682caa390f006fff51c3a59f28af127443f72f044f95212d2ceba9f3b13e38c1dc1565d846
6
+ metadata.gz: f128f08ff9148ec3e97b3c781ca502cbe6863ee5440d577f815723f6d1d6c6cdc6feb6760c840db9818986f5b87cbed10e235a7bb8ad233579c1b9e8d80ee9b5
7
+ data.tar.gz: 9914f5bc4f059db6c6395bf754136d8d910b95233333236c2f4a2d928b35f8d8181e910777eb54fd0c747ca70b6176f9730034971516cfd649cdda7a3cc2b774
data/.travis.yml CHANGED
@@ -1,7 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - "1.9.3"
4
- - rbx-19mode
4
+ - "2.1.4"
5
+ #- rbx-19mode
5
6
  #- jruby-19mode # JRuby in 1.9 mode
6
7
 
7
8
  # uncomment this line if your project needs to run something other than `rake`:
data/README.md CHANGED
@@ -2,99 +2,75 @@
2
2
 
3
3
  ## Overview
4
4
 
5
- Dase gem provides 'includes_count_of' method on a relation, which works similar to ActiveRecord's 'includes' method.
6
-
7
- ![Dase example](https://vovayartsev-home.s3.amazonaws.com/dase-mockup.png)
8
-
9
- Calling 'includes_count_of(:articles)' on a relation object adds 'articles_count' method to each of the authors:
10
- ```
11
- authors = Author.includes(:publisher).includes_count_of(:articles, :conditions => {:year => 2012})
12
- authors.first.name # => 'Billy'
13
- authors.first.articles_count # => 2
14
- ```
15
-
16
-
17
- ## Installation
18
-
19
- Add this line to your Rails 3.2.x application's Gemfile:
20
-
21
- gem 'dase', "~> 3.2.4"
5
+ Dase gem provides `includes_count_of` method on a relation, which works similar to ActiveRecord's `preload` method and solves [N+1 query problem](http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations) when counting records in `has_many` ActiveRecord associations.
22
6
 
23
7
  ## Usage
24
8
 
25
- ### Basic usage:
9
+ Given this data in the DB:
10
+ ![Dase example](https://dl.dropboxusercontent.com/u/8560625/dase.png)
26
11
 
12
+ and this Rails model definition
13
+ ```ruby
14
+ class Author
15
+ has_many :articles
16
+ end
27
17
  ```
28
- class Author
29
- has_many :articles
30
- end
31
-
32
- Author.includes_count_of(:articles).find_each do |author|
33
- puts "#{author.name} has #{author.articles_count} articles published"
34
- end
18
+ you can now write this:
19
+ ```
20
+ authors = Author.includes_count_of(:articles)
21
+ billy = authors.first # => #<Author name: 'Billy'>
22
+ billy.articles_count # => 2
35
23
  ```
36
24
 
37
- ### Using :conditions hash
38
- Specify a hash of options which will be passed to the underlying finder
39
- which retrieves the association. Valid keys are: :conditions, :group, :having, :joins, :include
25
+ with conditions on associated records (only articles in year 2012)
40
26
  ```
41
- Author.includes_count_of(:articles, :conditions => {:year => 2012}) # counts only articles in year 2012
27
+ Author.includes_count_of(:articles, where: {year: 2012} )
42
28
  ```
43
29
 
44
- ### Using scope merging
30
+ using lambda syntax (in v4.1 and greater)
45
31
  ```
46
- class Article
47
- belongs_to :author
48
- scope this_year, lambda { where(:year => 2012) }
49
- end
50
-
51
- results = Author.includes_count_of(:articles, :only => Article.this_year)
52
- results.first.articles_count # => # number of articles of given Author for year 2012 only
32
+ Author.includes_count_of(:articles, -> { where(year: 2012) } )
53
33
  ```
54
- This is achieved by merging the association scope with the scope provided as ":only => ..." option.
55
- No additional checks are performed, and providing the association of proper type is solely your responsibility.
56
34
 
57
-
58
- ### Renaming counter column
35
+ with renamed counter method
59
36
  ```
60
- sites = WebSite.includes_count_of(:users, :conditions => {:role => 'admin'}, :as => :admins_count)
61
- sites.each { |site| puts "Site #{site.url} has #{site.admins_count} admin users" }
37
+ Author.includes_count_of(:articles, -> { where(year: 2012) }, as: :number_of_articles_in_2012)
62
38
  ```
63
39
 
64
- ## Compatibility
65
-
66
- ### Rails versions
67
-
68
- This gem is for Rails 3.2.x . Earlier versions are not supported.
69
-
70
- Note: the Dase gem version number correlates with the Active Record's versions number,
71
- which it has been tested with.
72
- E.g. the latest 3.2.* version of Dase will play nicely with the latest 3.2.* version of Active Record.
73
- Since dase gem is a sort of a "hack", make sure you specified the version number for "dase" gem in your Gemfile.
74
-
75
- ### Polymorphic associations and HasManyThrough associations
76
-
77
- Polymorphic associations and HasManyThrough associations support should work, but it is not tested quite well.
78
- Bug reports and pull requests are very welcome.
40
+ with multiple associations counted at once
41
+ ```
42
+ Author.includes_count_of(:articles, :photos, :tweets)
43
+ ```
79
44
 
80
- ### jRuby support
45
+ ## Installation
81
46
 
82
- Not yet
47
+ | Rails version | Add this to Gemfile |
48
+ |---------------|------------------------|
49
+ | 3.2.x | gem 'dase', '~> 3.2.0' |
50
+ | 4.0.x | ----- N/A ----- |
51
+ | 4.1.x | gem 'dase', '~> 4.1.0' |
52
+ | 4.2.0.beta2 | gem 'dase', :github => 'vovayartsev/dase', :branch => 'rails-4-2' |
83
53
 
84
- ## How it works
54
+ ## Under the hood
85
55
 
86
- Here's a pseudo-code that gives an idea on how it works internally
56
+ When a relation is "materialized", we run a custom preloader which calculates the hash of counters in a single SQL query like this:
87
57
  ```
88
58
  counters_hash = Article.where(:year => 2012).count(:group => :author_id)
89
- Author.find_each do |author|
90
- puts "#{author.name} has #{counters_hash[author.id] || 0} articles published"
91
- end
92
59
  ```
60
+ then we add counters to the parent records like this:
61
+ ```
62
+ define_method(:articles_count) { counters_hash[author.id] || 0 }
63
+ ```
64
+
65
+ ## Alternative approaches
66
+ 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:
67
+ * Cache column in the DB - see [counter_culture](https://github.com/magnusvk/counter_culture) gem, or [counter_cache](http://guides.rubyonrails.org/association_basics.html#counter_cache) in Rails Guides.
68
+ * Using subquery in SELECT clause, or JOIN+SELECT+GROUP approach, as explained in [that video](http://www.youtube.com/watch?v=rJg3I-leoo4)
93
69
 
94
70
  ## Name origin
95
71
 
96
72
  The gem is named by the german mathematician [Johann Dase](http://en.wikipedia.org/wiki/Zacharias_Dase),
97
- who was a mental calculator - he could count and multiply numbers very quickly.
73
+ who was a [mental calculator](http://en.wikipedia.org/wiki/Mental_calculator) and could add and multiply numbers very quickly.
98
74
 
99
75
  ## Contributing
100
76
 
@@ -105,5 +81,10 @@ who was a mental calculator - he could count and multiply numbers very quickly.
105
81
  5. Create new Pull Request
106
82
 
107
83
 
108
- [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/vovayartsev/dase/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
84
+
85
+ [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/vovayartsev/dase/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
86
+
87
+
88
+
89
+
109
90
 
data/dase.gemspec CHANGED
@@ -9,18 +9,16 @@ Gem::Specification.new do |gem|
9
9
  gem.authors = ["Vladimir Yartsev"]
10
10
  gem.licenses = ["MIT"]
11
11
  gem.email = ["vovayartsev@gmail.com"]
12
- gem.description = %q{Dase gem creates includes_count_of method in ActiveRecord::Relation
13
- to count associated records efficiently. See examples at https://github.com/vovayartsev/dase
14
- }
12
+ gem.description = %q{includes_count_of method on ActiveRecord::Relation to solve N+1 query problem when counting associated records }
15
13
  gem.summary = %q{Provides includes_count_of method on ActiveRecord::Relation to count associated records efficiently}
16
14
  gem.homepage = "https://github.com/vovayartsev/dase"
17
15
 
18
- gem.add_runtime_dependency "activesupport", ">= 4.0", "<= 4.2"
16
+ gem.add_runtime_dependency "activesupport", "~> 4.2.0"
19
17
 
20
18
  if defined? JRUBY_VERSION
21
19
  gem.add_development_dependency 'activerecord-jdbcsqlite3-adapter'
22
20
  else
23
- gem.add_runtime_dependency "activerecord", ">= 4.0", "<= 4.2"
21
+ gem.add_runtime_dependency "activerecord", "~> 4.2.0"
24
22
  gem.add_development_dependency 'sqlite3', '~> 1.3'
25
23
  end
26
24
 
@@ -27,7 +27,7 @@ module Dase
27
27
 
28
28
  def merge(other)
29
29
  super(other).tap do |result|
30
- result.dase_values.merge!(other.dase_values || {}) if other # other == nil is fine too
30
+ result.dase_values.merge!(other.dase_values) if other # other == nil is fine too
31
31
  end
32
32
  end
33
33
 
data/lib/dase/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Dase
2
- VERSION = '4.1.1'
2
+ VERSION = '4.2.0'
3
3
  end
metadata CHANGED
@@ -1,55 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dase
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.1
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Yartsev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-31 00:00:00.000000000 Z
11
+ date: 2014-12-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '4.0'
20
- - - "<="
17
+ - - "~>"
21
18
  - !ruby/object:Gem::Version
22
- version: '4.2'
19
+ version: 4.2.0
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: '4.0'
30
- - - "<="
24
+ - - "~>"
31
25
  - !ruby/object:Gem::Version
32
- version: '4.2'
26
+ version: 4.2.0
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: activerecord
35
29
  requirement: !ruby/object:Gem::Requirement
36
30
  requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- version: '4.0'
40
- - - "<="
31
+ - - "~>"
41
32
  - !ruby/object:Gem::Version
42
- version: '4.2'
33
+ version: 4.2.0
43
34
  type: :runtime
44
35
  prerelease: false
45
36
  version_requirements: !ruby/object:Gem::Requirement
46
37
  requirements:
47
- - - ">="
48
- - !ruby/object:Gem::Version
49
- version: '4.0'
50
- - - "<="
38
+ - - "~>"
51
39
  - !ruby/object:Gem::Version
52
- version: '4.2'
40
+ version: 4.2.0
53
41
  - !ruby/object:Gem::Dependency
54
42
  name: sqlite3
55
43
  requirement: !ruby/object:Gem::Requirement
@@ -92,9 +80,8 @@ dependencies:
92
80
  - - "~>"
93
81
  - !ruby/object:Gem::Version
94
82
  version: '3.1'
95
- description: "Dase gem creates includes_count_of method in ActiveRecord::Relation\n
96
- \ to count associated records efficiently. See examples at
97
- https://github.com/vovayartsev/dase\n "
83
+ description: 'includes_count_of method on ActiveRecord::Relation to solve N+1 query
84
+ problem when counting associated records '
98
85
  email:
99
86
  - vovayartsev@gmail.com
100
87
  executables: []
@@ -161,4 +148,3 @@ test_files:
161
148
  - test/fixtures/schema.rb
162
149
  - test/helper.rb
163
150
  - test/test_dase.rb
164
- has_rdoc: