activerecord-virtual_attributes 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +3 -1
- data/.yamllint +8 -0
- data/CHANGELOG.md +16 -8
- data/Gemfile +1 -1
- data/lib/active_record/virtual_attributes.rb +17 -12
- data/lib/active_record/virtual_attributes/rspec/have_virtual_attribute.rb +2 -24
- data/lib/active_record/virtual_attributes/version.rb +1 -1
- data/lib/active_record/virtual_attributes/virtual_arel.rb +1 -0
- data/lib/active_record/virtual_attributes/virtual_delegates.rb +17 -14
- data/lib/active_record/virtual_attributes/virtual_fields.rb +1 -1
- data/lib/active_record/virtual_attributes/virtual_total.rb +1 -9
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a6c500c61ceb22d7703070013800f894b62a5efd8bf14e3e5aec0e24afdb5e1
|
4
|
+
data.tar.gz: 1e8c99b6823e09e10e39958c3f50651e5f1b558a76ef15377f23cd13571fd2cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d1b3dc8b531417c714f180c74946f7f42fe6470b7a4912567be43f79529cdaad399c4316af05e0ca63b51e37d022f2887e316752d69371afed7c7ca92f0c6d0
|
7
|
+
data.tar.gz: fb251d9ca04da11c0042f0ec93c908e1ded759faf3c0935a94a7809219cd3ba73d7d4ef7451d6d7293efded29da176af921bcc92607170b5d2219c546559d317
|
data/.codeclimate.yml
CHANGED
data/.yamllint
ADDED
data/CHANGELOG.md
CHANGED
@@ -5,24 +5,32 @@ a nice looking [Changelog](http://keepachangelog.com).
|
|
5
5
|
|
6
6
|
## Version [Unreleased]
|
7
7
|
|
8
|
+
## Version [1.2.0] <small>2019-04-23</small>
|
9
|
+
|
10
|
+
* Virtual_delegate :type now specified to avoid rare race conditions with attribute discovery
|
11
|
+
* Delays interpreting delegate until column is used
|
12
|
+
* Postgres now supports order by virtual_aggregate
|
13
|
+
* More flexible includes. e.g.: Arrays of symbols now work
|
14
|
+
* Raises errors for invalid `includes()` and `:uses`
|
15
|
+
|
8
16
|
## Version [1.1.0] <small>2019-04-23</small>
|
9
17
|
|
10
|
-
*
|
11
|
-
*
|
12
|
-
*
|
13
|
-
* climate code fixes
|
18
|
+
* Add legacy types for `VirtualAttribute::Types`
|
19
|
+
* Fix rails 5.1 bug with `includes()`
|
20
|
+
* Remove reference to `MiqPreloader`
|
14
21
|
|
15
22
|
## Version [1.0.0] <small>2019-03-05</small>
|
16
23
|
|
17
|
-
*
|
18
|
-
*
|
19
|
-
*
|
24
|
+
* Renamed to activerecord-virtual_attributes
|
25
|
+
* Moved from ManageIQ to own repo
|
26
|
+
* Added support for Rails 5.1
|
20
27
|
|
21
28
|
## Version 0.1.0 <small>2019-01-17</small>
|
22
29
|
|
23
30
|
* Initial Release
|
24
31
|
* Extracted from ManageIQ/manageiq
|
25
32
|
|
26
|
-
[Unreleased]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v1.
|
33
|
+
[Unreleased]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v1.2.0...HEAD
|
34
|
+
[1.2.0]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v1.1.0...v1.2.0
|
27
35
|
[1.1.0]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v1.0.0...v1.1.0
|
28
36
|
[1.0.0]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v0.1.0...v1.0.0
|
data/Gemfile
CHANGED
@@ -15,15 +15,21 @@ module ActiveRecord
|
|
15
15
|
module Type
|
16
16
|
# TODO: do we actually need symbol types?
|
17
17
|
class Symbol < ActiveRecord::Type::String
|
18
|
-
def type
|
18
|
+
def type
|
19
|
+
:symbol
|
20
|
+
end
|
19
21
|
end
|
20
22
|
|
21
23
|
class StringSet < ActiveRecord::Type::Value
|
22
|
-
def type
|
24
|
+
def type
|
25
|
+
:string_set
|
26
|
+
end
|
23
27
|
end
|
24
28
|
|
25
29
|
class NumericSet < ActiveRecord::Type::Value
|
26
|
-
def type
|
30
|
+
def type
|
31
|
+
:numeric_set
|
32
|
+
end
|
27
33
|
end
|
28
34
|
end
|
29
35
|
|
@@ -37,7 +43,6 @@ module ActiveRecord
|
|
37
43
|
end
|
38
44
|
|
39
45
|
module ClassMethods
|
40
|
-
|
41
46
|
#
|
42
47
|
# Definition
|
43
48
|
#
|
@@ -127,17 +132,17 @@ require "active_record/virtual_attributes/virtual_fields"
|
|
127
132
|
|
128
133
|
# this patch is no longer necessary for 5.2
|
129
134
|
if ActiveRecord.version.to_s < "5.2"
|
130
|
-
require "active_record/attribute"
|
131
|
-
module ActiveRecord
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
135
|
+
require "active_record/attribute"
|
136
|
+
module ActiveRecord
|
137
|
+
# This is a bug in rails 5.0 and 5.1, but it is made much worse by virtual attributes
|
138
|
+
class Attribute
|
139
|
+
def with_value_from_database(value)
|
140
|
+
# self.class.from_database(name, value, type)
|
141
|
+
initialized? ? self.class.from_database(name, value, type) : self
|
142
|
+
end
|
137
143
|
end
|
138
144
|
end
|
139
145
|
end
|
140
|
-
end
|
141
146
|
|
142
147
|
require "active_record/virtual_attributes/virtual_total"
|
143
148
|
require "active_record/virtual_attributes/arel_groups"
|
@@ -1,27 +1,3 @@
|
|
1
|
-
# TODO: expose this to classes that include this gem
|
2
|
-
|
3
|
-
# legacy matcher
|
4
|
-
RSpec::Matchers.define :have_virtual_column do |name, type|
|
5
|
-
match do |klass|
|
6
|
-
expect(klass.has_attribute?(name)).to be_truthy
|
7
|
-
expect(klass.virtual_attribute?(name)).to be_truthy
|
8
|
-
expect(klass.type_for_attribute(name).type).to eq(type)
|
9
|
-
klass.instance_methods.include?(name.to_sym)
|
10
|
-
end
|
11
|
-
|
12
|
-
failure_message do |klass|
|
13
|
-
"expected #{klass.name} to have virtual column #{name.inspect} with type #{type.inspect}"
|
14
|
-
end
|
15
|
-
|
16
|
-
failure_message_when_negated do |klass|
|
17
|
-
"expected #{klass.name} to not have virtual column #{name.inspect} with type #{type.inspect}"
|
18
|
-
end
|
19
|
-
|
20
|
-
description do
|
21
|
-
"expect the object to have the virtual column"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
1
|
RSpec::Matchers.define :have_virtual_attribute do |name, type|
|
26
2
|
match do |klass|
|
27
3
|
expect(klass.has_attribute?(name)).to be_truthy
|
@@ -42,3 +18,5 @@ RSpec::Matchers.define :have_virtual_attribute do |name, type|
|
|
42
18
|
"expect the object to have the virtual column"
|
43
19
|
end
|
44
20
|
end
|
21
|
+
|
22
|
+
RSpec::Matchers.alias_matcher(:have_virtual_column, :have_virtual_attribute)
|
@@ -15,7 +15,6 @@ module ActiveRecord
|
|
15
15
|
end
|
16
16
|
|
17
17
|
module ClassMethods
|
18
|
-
|
19
18
|
#
|
20
19
|
# Definition
|
21
20
|
#
|
@@ -72,7 +71,8 @@ module ActiveRecord
|
|
72
71
|
end
|
73
72
|
|
74
73
|
col = col.to_s
|
75
|
-
type = to_ref.klass.type_for_attribute(col)
|
74
|
+
type = options[:type] || to_ref.klass.type_for_attribute(col)
|
75
|
+
type = ActiveRecord::Type.lookup(type) if type.kind_of?(Symbol)
|
76
76
|
raise "unknown attribute #{to}##{col} referenced in #{name}" unless type
|
77
77
|
arel = virtual_delegate_arel(col, to_ref)
|
78
78
|
define_virtual_attribute(method_name, type, :uses => (options[:uses] || to), :arel => arel)
|
@@ -142,20 +142,23 @@ module ActiveRecord
|
|
142
142
|
# See select_from_alias for examples
|
143
143
|
|
144
144
|
def virtual_delegate_arel(col, to_ref)
|
145
|
-
#
|
145
|
+
# Ensure the association is reachable via sql
|
146
|
+
#
|
147
|
+
# But NOT ensuring the target column has sql
|
148
|
+
# to_ref.klass.arel_attribute(col) loads the target classes' schema.
|
149
|
+
# This cascades and causing a race condition
|
150
|
+
#
|
146
151
|
# There is currently no way to propagate sql over a virtual association
|
147
|
-
if to_ref.
|
148
|
-
|
152
|
+
if reflect_on_association(to_ref.name) && (to_ref.macro == :has_one || to_ref.macro == :belongs_to)
|
153
|
+
lambda do |t|
|
154
|
+
join_keys = if ActiveRecord.version.to_s >= "5.1"
|
155
|
+
to_ref.join_keys
|
156
|
+
else
|
157
|
+
to_ref.join_keys(to_ref.klass)
|
158
|
+
end
|
159
|
+
src_model_id = arel_attribute(join_keys.foreign_key, t)
|
149
160
|
blk = ->(arel) { arel.limit = 1 } if to_ref.macro == :has_one
|
150
|
-
|
151
|
-
if ActiveRecord.version.to_s >= "5.1"
|
152
|
-
join_keys = to_ref.join_keys
|
153
|
-
else
|
154
|
-
join_keys = to_ref.join_keys(to_ref.klass)
|
155
|
-
end
|
156
|
-
src_model_id = arel_attribute(join_keys.foreign_key, t)
|
157
|
-
VirtualDelegates.select_from_alias(to_ref, col, join_keys.key, src_model_id, &blk)
|
158
|
-
end
|
161
|
+
VirtualDelegates.select_from_alias(to_ref, col, join_keys.key, src_model_id, &blk)
|
159
162
|
end
|
160
163
|
end
|
161
164
|
end
|
@@ -40,7 +40,7 @@ module ActiveRecord
|
|
40
40
|
associations.each_with_object({}) do |(parent, child), h|
|
41
41
|
next if virtual_field?(parent)
|
42
42
|
reflection = reflect_on_association(parent.to_sym)
|
43
|
-
h[parent] = reflection.options[:polymorphic] ?
|
43
|
+
h[parent] = reflection.nil? || reflection.options[:polymorphic] ? {} : reflection.klass.remove_virtual_fields(child) || {}
|
44
44
|
end
|
45
45
|
else
|
46
46
|
associations
|
@@ -100,14 +100,6 @@ module VirtualAttributes
|
|
100
100
|
reflection.klass.all
|
101
101
|
end
|
102
102
|
|
103
|
-
# ordering will probably screw up aggregations, so clear this out from
|
104
|
-
# any calls
|
105
|
-
#
|
106
|
-
# only clear this out if this isn't a `:size` call as well, since doing
|
107
|
-
# a COUNT(*) will allow any ORDER BY to still work properly. This is
|
108
|
-
# to avoid any possible edge cases by clearing out the order clause.
|
109
|
-
query.order_values = [] if method_name != :size
|
110
|
-
|
111
103
|
foreign_table = reflection.klass.arel_table
|
112
104
|
# need db access for the keys, so delaying all this lookup until call time
|
113
105
|
if ActiveRecord.version.to_s >= "5.1"
|
@@ -115,7 +107,7 @@ module VirtualAttributes
|
|
115
107
|
else
|
116
108
|
join_keys = reflection.join_keys(reflection.klass)
|
117
109
|
end
|
118
|
-
query = query.where(t[join_keys.foreign_key].eq(foreign_table[join_keys.key]))
|
110
|
+
query = query.except(:order).where(t[join_keys.foreign_key].eq(foreign_table[join_keys.key]))
|
119
111
|
|
120
112
|
arel_column = if method_name == :size
|
121
113
|
Arel.star.count
|
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: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Keenan Brock
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -94,6 +94,7 @@ files:
|
|
94
94
|
- ".rubocop_cc.yml"
|
95
95
|
- ".rubocop_local.yml"
|
96
96
|
- ".travis.yml"
|
97
|
+
- ".yamllint"
|
97
98
|
- Appraisals
|
98
99
|
- CHANGELOG.md
|
99
100
|
- Gemfile
|
@@ -143,7 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
143
144
|
version: '0'
|
144
145
|
requirements: []
|
145
146
|
rubyforge_project:
|
146
|
-
rubygems_version: 2.7.6
|
147
|
+
rubygems_version: 2.7.6.2
|
147
148
|
signing_key:
|
148
149
|
specification_version: 4
|
149
150
|
summary: Access non-sql attributes from sql
|