activerecord-virtual_attributes 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9ceef88d5be93e1f696e382623d09b421031eae65de7608241b14a943ff5c76c
4
- data.tar.gz: bcf53221633defb009e5dbf739cf2466360c0a00e35bc312dec15d25def7406b
3
+ metadata.gz: f205435ff8ec8ecda2020356916188e8c145dedfd57e9e9a89c7c3c743afa57a
4
+ data.tar.gz: 3485ee96f78567ef4fd98eec35dc6350313c543c6e5606c1ad4191812a25d534
5
5
  SHA512:
6
- metadata.gz: 554b781f47a4fe637bad32ab5c194e4aa364c78dfb5d9a39f8877a3d22ed9c704b4f5ee8312a4220fe07b08eb5a9d4cb3aeb05af200cf0a54af10c4c2052bad4
7
- data.tar.gz: 3feaf1fa331f0e40813591d33f7543cda134acf88e6a70516e8f5aa27c4941c999cfb63ceb2bc86b44bce359daed0ce11f79276f7d832d553f82c754f7206d07
6
+ metadata.gz: 700653df253780ef026120bdaa639e14adc4ed2c5ee735575d6a42a8335833791ab8dff596de8195b3c07f9da68d55e535a70cd20edc7b3ed2d973cf23aab177
7
+ data.tar.gz: e4ae06737ca3973621e673b18388f0bc9a0012efbe2e569857de4b718a7a89ae3324f27ff3cbac91d0d7c8da6456bd36cee1161dec771b6af3f8bde0ced8f65b
@@ -5,6 +5,12 @@ a nice looking [Changelog](http://keepachangelog.com).
5
5
 
6
6
  ## Version [Unreleased] <small>tbd</small>
7
7
 
8
+ ## Version [3.0.0] <small>2020-09-28</small>
9
+
10
+ * fix virtual_aggregate to return a consistent 0 when calculating a sum of no records
11
+ * fix virtual delegate to include the type column when fetching associated models for polymorphism
12
+ * add virtual_average, virtual_minimum, and virtual_maximum
13
+
8
14
  ## Version [2.0.0] <small>2020-05-22</small>
9
15
 
10
16
  * This is a trivial release, but because it modifies a public interface, the jump makes it look significant.
@@ -66,7 +72,8 @@ a nice looking [Changelog](http://keepachangelog.com).
66
72
  * Initial Release
67
73
  * Extracted from ManageIQ/manageiq
68
74
 
69
- [Unreleased]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v2.0.0...HEAD
75
+ [Unreleased]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v3.0.0...HEAD
76
+ [3.0.0]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v2.0.0...v3.0.0
70
77
  [2.0.0]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v1.6.0...v2.0.0
71
78
  [1.6.0]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v1.5.0...v1.6.0
72
79
  [1.5.0]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v1.4.0...v1.5.0
@@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
29
29
 
30
30
  spec.add_development_dependency "appraisal"
31
31
  spec.add_development_dependency "byebug"
32
+ spec.add_development_dependency "db-query-matchers", "~>0.10"
32
33
  spec.add_development_dependency "rake", "~> 10.0"
33
34
  spec.add_development_dependency "rspec", "~> 3.0"
34
35
  spec.add_development_dependency "simplecov"
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module VirtualAttributes
3
- VERSION = "2.0.0".freeze
3
+ VERSION = "3.0.0".freeze
4
4
  end
5
5
  end
@@ -240,6 +240,7 @@ module ActiveRecord
240
240
  # (SELECT "vms_sub"."name" FROM "vms" AS "vms_ss" WHERE "vms_ss"."id" = "vms"."src_template_id")
241
241
  #
242
242
 
243
+ # Based upon ActiveRecord AssociationScope.scope
243
244
  def self.select_from_alias(to_ref, col, to_model_col_name, src_model_id)
244
245
  query = if to_ref.scope
245
246
  to_ref.klass.instance_exec(nil, &to_ref.scope)
@@ -247,6 +248,7 @@ module ActiveRecord
247
248
  to_ref.klass.all
248
249
  end
249
250
 
251
+ src_model = to_ref.active_record
250
252
  to_table = select_from_alias_table(to_ref.klass, src_model_id.relation)
251
253
  to_model_id = to_ref.klass.arel_attribute(to_model_col_name, to_table)
252
254
  to_column = to_ref.klass.arel_attribute(col, to_table)
@@ -254,6 +256,13 @@ module ActiveRecord
254
256
  .from(to_table)
255
257
  .where(to_model_id.eq(src_model_id))
256
258
 
259
+ # :type is in the reflection definition (meaning it is polymorphic)
260
+ if to_ref.type
261
+ # get the class name (e.g. "Host")
262
+ polymorphic_type = src_model.base_class.name
263
+ arel = arel.where(to_ref.klass.arel_attribute(to_ref.type).eq(polymorphic_type))
264
+ end
265
+
257
266
  yield arel if block_given?
258
267
 
259
268
  Arel.sql("(#{arel.to_sql})")
@@ -5,7 +5,7 @@ module VirtualAttributes
5
5
  module ClassMethods
6
6
  private
7
7
 
8
- # define an attribute to calculating the total of a has many relationship
8
+ # define an attribute to calculate the total of a has many relationship
9
9
  #
10
10
  # example:
11
11
  #
@@ -25,24 +25,45 @@ module VirtualAttributes
25
25
  # # arel == (SELECT COUNT(*) FROM vms where ems.id = vms.ems_id)
26
26
  #
27
27
  def virtual_total(name, relation, options = {})
28
- define_virtual_size_method(name, relation)
29
28
  define_virtual_aggregate_attribute(name, relation, :count, Arel.star, options)
29
+ define_method(name) { (has_attribute?(name) ? self[name] : send(relation).try(:size)) || 0 }
30
30
  end
31
31
 
32
- # define an attribute to calculate the sum of a has may relationship
32
+ def virtual_sum(name, relation, column, options = {})
33
+ define_virtual_aggregate_attribute(name, relation, :sum, column, options)
34
+ define_virtual_aggregate_method(name, relation, column, :sum)
35
+ end
36
+
37
+ def virtual_minimum(name, relation, column, options = {})
38
+ define_virtual_aggregate_attribute(name, relation, :minimum, column, options)
39
+ define_virtual_aggregate_method(name, relation, column, :min, :minimum)
40
+ end
41
+
42
+ def virtual_maximum(name, relation, column, options = {})
43
+ define_virtual_aggregate_attribute(name, relation, :maximum, column, options)
44
+ define_virtual_aggregate_method(name, relation, column, :max, :maximum)
45
+ end
46
+
47
+ def virtual_average(name, relation, column, options = {})
48
+ define_virtual_aggregate_attribute(name, relation, :average, column, options)
49
+ define_virtual_aggregate_method(name, relation, column, :average) { |values| values.count == 0 ? 0 : values.sum / values.count }
50
+ end
51
+
52
+ # @param method_name
53
+ # :count :average :minimum :maximum :sum
33
54
  #
34
55
  # example:
35
56
  #
36
57
  # class Hardware
37
58
  # has_many :disks
38
- # virtual_aggregate :allocated_disk_storage, :disks, :sum, :size
59
+ # virtual_sum :allocated_disk_storage, :disks, :size
39
60
  # end
40
61
  #
41
62
  # generates:
42
63
  #
43
64
  # def allocated_disk_storage
44
65
  # if disks.loaded?
45
- # disks.blank? ? nil : disks.map(&:size).compact.sum
66
+ # disks.map(&:size).compact.sum
46
67
  # else
47
68
  # disks.sum(:size) || 0
48
69
  # end
@@ -53,10 +74,8 @@ module VirtualAttributes
53
74
  # # arel => (SELECT sum("disks"."size") where "hardware"."id" = "disks"."hardware_id")
54
75
 
55
76
  def virtual_aggregate(name, relation, method_name = :sum, column = nil, options = {})
56
- return define_virtual_total(name, relation, options) if method_name == :size
57
-
58
- define_virtual_aggregate_method(name, relation, method_name, column)
59
- define_virtual_aggregate_attribute(name, relation, method_name, column, options)
77
+ return virtual_total(name, relation, options) if method_name == :size
78
+ return virtual_sum(name, relation, column, options) if method_name == :sum
60
79
  end
61
80
 
62
81
  def define_virtual_aggregate_attribute(name, relation, method_name, column, options)
@@ -77,20 +96,19 @@ module VirtualAttributes
77
96
  end
78
97
  end
79
98
 
80
- def define_virtual_size_method(name, relation)
81
- define_method(name) do
82
- (has_attribute?(name) ? self[name] : send(relation).try(:size)) || 0
83
- end
84
- end
85
-
86
- def define_virtual_aggregate_method(name, relation, method_name, column)
99
+ def define_virtual_aggregate_method(name, relation, column, ruby_method_name, arel_method_name = ruby_method_name)
87
100
  define_method(name) do
88
- if attribute_present?(name)
89
- self[name]
101
+ if has_attribute?(name)
102
+ self[name] || 0
90
103
  elsif (rel = send(relation)).loaded?
91
- rel.blank? ? nil : rel.map { |t| t.send(column) }.compact.send(method_name)
104
+ values = rel.map { |t| t.send(column) }.compact
105
+ if block_given?
106
+ yield values
107
+ else
108
+ values.blank? ? nil : values.send(ruby_method_name)
109
+ end
92
110
  else
93
- rel.try(method_name, column) || 0
111
+ rel.try(arel_method_name, column) || 0
94
112
  end
95
113
  end
96
114
  end
@@ -128,7 +146,9 @@ module VirtualAttributes
128
146
  end
129
147
 
130
148
  # add () around query
131
- t.grouping(Arel::Nodes::SqlLiteral.new(sql))
149
+ query = t.grouping(Arel::Nodes::SqlLiteral.new(sql))
150
+ # add coalesce to ensure correct value comes out
151
+ t.grouping(Arel::Nodes::NamedFunction.new('COALESCE', [query, Arel::Nodes::SqlLiteral.new("0")]))
132
152
  end
133
153
  end
134
154
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-virtual_attributes
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keenan Brock
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-22 00:00:00.000000000 Z
11
+ date: 2020-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: db-query-matchers
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.10'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.10'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -143,7 +157,7 @@ metadata:
143
157
  homepage_uri: https://github.com/ManageIQ/activerecord-virtual_attributes
144
158
  source_code_uri: https://github.com/ManageIQ/activerecord-virtual_attributes
145
159
  changelog_uri: https://github.com/ManageIQ/activerecord-virtual_attributes/blob/master/CHANGELOG.md
146
- post_install_message:
160
+ post_install_message:
147
161
  rdoc_options: []
148
162
  require_paths:
149
163
  - lib
@@ -158,9 +172,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
158
172
  - !ruby/object:Gem::Version
159
173
  version: '0'
160
174
  requirements: []
161
- rubyforge_project:
175
+ rubyforge_project:
162
176
  rubygems_version: 2.7.6.2
163
- signing_key:
177
+ signing_key:
164
178
  specification_version: 4
165
179
  summary: Access non-sql attributes from sql
166
180
  test_files: []