activerecord-virtual_attributes 2.0.0 → 3.0.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: 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: []