eager_group 0.9.0 → 0.10.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
  SHA256:
3
- metadata.gz: c8bad88cf4f0de57942e0477ee107ce8f40eeeded25b37def08ef560907ef143
4
- data.tar.gz: f14470d5456dbce04be8fac648623fbc0e1dbb25a3e89af5ebe7bde9dd6a61d5
3
+ metadata.gz: 3717871f8324a6ec0a0886745b12c17f7443398a8658bcb60ce008fa1e924df1
4
+ data.tar.gz: 0eccab385f9d6ec341ace42258672f663b03598ee164ef22b1b25fb7bf17779a
5
5
  SHA512:
6
- metadata.gz: 6e026cf0d9f8a9839b498b995ba7d48ab24afe2dc48f3e7d41cba16069ac4bc9b3c15d202e7b9730859aa81f24c8cb77a9e2bc8572e720a58457cc7f89f171a0
7
- data.tar.gz: 0033033e6b427479d0a49c2e2e1b1149f40a63a46f12aa42aa49f54fb91b27f84ee045aa96014c37b745fbad9b5ca84fab20b014ef521e478cbce058f681f803
6
+ metadata.gz: c1fb52a045e4f2005a78ef698ff915195e705a9729e1fb6a25275d2516c48e7f016d3249946d3a337b07b70a822f75c0ffe1f2acbb130c78a2d13df03107449b
7
+ data.tar.gz: 0a7393ea354afaaf1c1002c7641c3a4bd94e26b2407eea9b6cb701da243b67733c34d226711650964251aaa2f5d117db0d0e418e5702ebb4b75f59323c3b6c49
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Next Release
2
2
 
3
+ ## 0.10.0 (12/28/2022)
4
+
5
+ * Add STI support, use `class_attribute` to prevent subclasses affect each other
6
+
7
+ ## 0.9.1 (12/15/2022)
8
+
9
+ * Fix eager group fetch multi definitions
10
+
3
11
  ## 0.9.0 (12/04/2022)
4
12
 
5
13
  * Support `has_many` through `belongs_to`
@@ -9,7 +9,11 @@ module ActiveRecord
9
9
  end
10
10
 
11
11
  def eager_group(*args)
12
- check_if_method_has_arguments!(__callee__, args)
12
+ # we does not use the `check_if_method_has_arguments!` here because it would flatten all the arguments,
13
+ # which would cause `[:eager_group_definition, scope_arg1, scope_arg2]` not able to preload together with other `eager_group_definitions`.
14
+ # e.g. `Post.eager_group(:approved_comments_count, [:comments_average_rating_by_author, students[0], true])`
15
+ check_argument_not_blank!(args)
16
+ check_argument_valid!(args)
13
17
 
14
18
  spawn.eager_group!(*args)
15
19
  end
@@ -28,5 +32,38 @@ module ActiveRecord
28
32
 
29
33
  @values[:eager_group] = values
30
34
  end
35
+
36
+ private
37
+
38
+ def check_argument_not_blank!(args)
39
+ raise ArgumentError, "The method .eager_group() must contain arguments." if args.blank?
40
+ args.compact_blank!
41
+ end
42
+
43
+ def check_argument_valid!(args)
44
+ args.each do |eager_group_value|
45
+ check_eager_group_definitions_exists!(klass, eager_group_value)
46
+ end
47
+ end
48
+
49
+ def check_eager_group_definitions_exists!(klass, eager_group_value)
50
+ case eager_group_value
51
+ when Symbol, String
52
+ raise ArgumentError, "Unknown eager group definition :#{eager_group_value}" unless klass.eager_group_definitions.has_key?(eager_group_value)
53
+ when Array
54
+ definition_name = eager_group_value.first
55
+ raise ArgumentError, "Unknown eager group definition :#{definition_name}" unless klass.eager_group_definitions.has_key?(definition_name)
56
+ when Hash
57
+ eager_group_value.each do |association_name, association_eager_group_values|
58
+ association_klass = klass.reflect_on_association(association_name).klass
59
+
60
+ Array.wrap(association_eager_group_values).each do |association_eager_group_value|
61
+ check_eager_group_definitions_exists!(association_klass, association_eager_group_value)
62
+ end
63
+ end
64
+ else
65
+ raise ArgumentError, "Unknown eager_group argument :#{eager_group_value.inspect}"
66
+ end
67
+ end
31
68
  end
32
69
  end
@@ -25,6 +25,10 @@ module EagerGroup
25
25
  @klass.primary_key
26
26
  end
27
27
 
28
+ def aggregate_hash
29
+ raise NotImplementedError, 'Method "aggregate_hash" must be implemented in subclass'
30
+ end
31
+
28
32
  private
29
33
 
30
34
  def polymophic_as_condition
@@ -11,8 +11,7 @@ module EagerGroup
11
11
  def initialize(klass, records, eager_group_values)
12
12
  @klass = klass
13
13
  @records = Array.wrap(records).compact.uniq
14
- eager_group_definitions = @klass.eager_group_definitions
15
- @eager_group_values = eager_group_values.all? { |value| eager_group_definitions.key?(value) } ? eager_group_values : [eager_group_values]
14
+ @eager_group_values = eager_group_values
16
15
  end
17
16
 
18
17
  # Preload aggregate functions
@@ -23,15 +22,17 @@ module EagerGroup
23
22
 
24
23
  if definition_key.is_a?(Hash)
25
24
  association_name, definition_key = *definition_key.first
25
+ next if @records.empty?
26
+ @klass = @records.first.class.reflect_on_association(association_name).klass
27
+
26
28
  @records = @records.flat_map { |record| record.send(association_name) }
27
29
  next if @records.empty?
28
30
 
29
- @klass = @records.first.class
30
- end
31
31
 
32
- Array.wrap(definition_key).each do |key|
33
- find_aggregate_values_per_definition!(key, arguments)
32
+ self.class.new(@klass, @records, Array.wrap(definition_key)).run
34
33
  end
34
+
35
+ find_aggregate_values_per_definition!(definition_key, arguments)
35
36
  end
36
37
  end
37
38
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EagerGroup
4
- VERSION = '0.9.0'
4
+ VERSION = '0.10.0'
5
5
  end
data/lib/eager_group.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_support/core_ext/module/attribute_accessors'
4
+ require 'active_support/core_ext/class/attribute'
5
+ require 'active_support/core_ext/hash'
4
6
  require 'eager_group/version'
5
7
 
6
8
  module EagerGroup
@@ -9,30 +11,39 @@ module EagerGroup
9
11
 
10
12
  def self.included(base)
11
13
  base.extend ClassMethods
14
+ base.class_eval do
15
+ class_attribute :eager_group_definitions, instance_writer: false, default: {}.with_indifferent_access
16
+ end
12
17
  end
13
18
 
14
19
  module ClassMethods
15
- mattr_accessor :eager_group_definitions, default: {}
20
+ #mattr_accessor :eager_group_definitions, default: {}
21
+
22
+ def add_eager_group_definition(ar, definition_name, definition)
23
+ ar.eager_group_definitions = self.eager_group_definitions.except(definition_name).merge!(definition_name => definition)
24
+ end
16
25
 
17
26
  # class Post
18
27
  # define_eager_group :comments_avergage_rating, :comments, :average, :rating
19
28
  # define_eager_group :approved_comments_count, :comments, :count, :*, -> { approved }
20
29
  # end
21
30
  def define_eager_group(attr, association, aggregate_function, column_name, scope = nil)
22
- send :attr_accessor, attr
23
- eager_group_definitions[attr] = Definition.new(association, aggregate_function, column_name, scope)
31
+ add_eager_group_definition(self, attr, Definition.new(association, aggregate_function, column_name, scope))
32
+ define_definition_accessor(attr)
33
+ end
24
34
 
25
- define_method attr,
35
+ def define_definition_accessor(definition_name)
36
+ define_method definition_name,
26
37
  lambda { |*args|
27
- query_result_cache = instance_variable_get("@#{attr}")
38
+ query_result_cache = instance_variable_get("@#{definition_name}")
28
39
  return query_result_cache if args.blank? && query_result_cache.present?
29
40
 
30
- preload_eager_group(attr, *args)
31
- instance_variable_get("@#{attr}")
41
+ preload_eager_group(definition_name, *args)
42
+ instance_variable_get("@#{definition_name}")
32
43
  }
33
44
 
34
- define_method "#{attr}=" do |val|
35
- instance_variable_set("@#{attr}", val)
45
+ define_method "#{definition_name}=" do |val|
46
+ instance_variable_set("@#{definition_name}", val)
36
47
  end
37
48
  end
38
49
  end
@@ -40,7 +51,7 @@ module EagerGroup
40
51
  private
41
52
 
42
53
  def preload_eager_group(*eager_group_value)
43
- EagerGroup::Preloader.new(self.class, [self], eager_group_value).run
54
+ EagerGroup::Preloader.new(self.class, [self], [eager_group_value]).run
44
55
  end
45
56
  end
46
57
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eager_group
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Huang
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-12-04 00:00:00.000000000 Z
11
+ date: 2022-12-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -185,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
185
185
  - !ruby/object:Gem::Version
186
186
  version: '0'
187
187
  requirements: []
188
- rubygems_version: 3.3.26
188
+ rubygems_version: 3.4.1
189
189
  signing_key:
190
190
  specification_version: 4
191
191
  summary: Fix n+1 aggregate sql functions