active_type 0.5.0 → 0.6.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 +4 -4
- data/.rspec +1 -0
- data/.travis.yml +36 -11
- data/CHANGELOG.md +31 -2
- data/README.md +19 -2
- data/active_type.gemspec +1 -0
- data/gemfiles/Gemfile.3.2.mysql2.lock +2 -2
- data/gemfiles/Gemfile.3.2.sqlite3.lock +2 -2
- data/gemfiles/Gemfile.4.0.sqlite3.lock +2 -2
- data/gemfiles/Gemfile.4.1.sqlite3.lock +2 -2
- data/gemfiles/Gemfile.4.2.1.mysql2.lock +2 -2
- data/gemfiles/Gemfile.4.2.1.pg.lock +2 -2
- data/gemfiles/Gemfile.4.2.1.sqlite3.lock +2 -2
- data/gemfiles/Gemfile.5.0.0.mysql2 +7 -0
- data/gemfiles/Gemfile.5.0.0.mysql2.lock +54 -0
- data/gemfiles/Gemfile.5.0.0.pg +7 -0
- data/gemfiles/Gemfile.5.0.0.pg.lock +54 -0
- data/gemfiles/Gemfile.5.0.0.sqlite3 +7 -0
- data/gemfiles/Gemfile.5.0.0.sqlite3.lock +54 -0
- data/lib/active_type/extended_record/inheritance.rb +41 -6
- data/lib/active_type/nested_attributes/builder.rb +3 -3
- data/lib/active_type/no_table.rb +129 -42
- data/lib/active_type/type_caster.rb +30 -2
- data/lib/active_type/util.rb +11 -2
- data/lib/active_type/version.rb +1 -1
- data/spec/active_type/nested_attributes_spec.rb +5 -1
- data/spec/active_type/object_spec.rb +31 -3
- data/spec/active_type/record_spec.rb +27 -8
- data/spec/active_type/util_spec.rb +15 -1
- data/spec/shared_examples/accessors.rb +0 -17
- data/spec/shared_examples/coercible_columns.rb +21 -1
- metadata +11 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b973cce18664ad143d834c1ab76a67560a7d7625
|
|
4
|
+
data.tar.gz: 8de998fb74cc5a6bc9217b072461ac293cf83951
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 28e1d976f66a72868ce6321a589235bb1536accd6b01fb5312f337d76ad191e3542b324e98e1b640e2718a45b8e423bdae5b1512e75fe50bc3896381bcae4f55
|
|
7
|
+
data.tar.gz: 1582cff084f91960662efda6b38ce5fa8d5ff4379e11a5b3181b64f70f1021b5b3074ea33c867a362942ae912ca4bcbba942daf53db1874f6548b3daf6b439e3
|
data/.rspec
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--color
|
data/.travis.yml
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
language: ruby
|
|
2
2
|
rvm:
|
|
3
|
-
- "1.8.7"
|
|
4
3
|
- "1.9.3"
|
|
5
4
|
- "2.0.0"
|
|
6
5
|
- "2.1.7"
|
|
7
6
|
- "2.2.4"
|
|
7
|
+
- "2.3.1"
|
|
8
8
|
gemfile:
|
|
9
9
|
- gemfiles/Gemfile.3.2.mysql2
|
|
10
10
|
- gemfiles/Gemfile.3.2.sqlite3
|
|
@@ -13,6 +13,9 @@ gemfile:
|
|
|
13
13
|
- gemfiles/Gemfile.4.2.1.mysql2
|
|
14
14
|
- gemfiles/Gemfile.4.2.1.pg
|
|
15
15
|
- gemfiles/Gemfile.4.2.1.sqlite3
|
|
16
|
+
- gemfiles/Gemfile.5.0.0.mysql2
|
|
17
|
+
- gemfiles/Gemfile.5.0.0.pg
|
|
18
|
+
- gemfiles/Gemfile.5.0.0.sqlite3
|
|
16
19
|
before_script:
|
|
17
20
|
- psql -c 'create database active_type_test;' -U postgres
|
|
18
21
|
- mysql -e 'create database IF NOT EXISTS active_type_test;'
|
|
@@ -27,16 +30,6 @@ branches:
|
|
|
27
30
|
- master
|
|
28
31
|
matrix:
|
|
29
32
|
exclude:
|
|
30
|
-
- rvm: "1.8.7"
|
|
31
|
-
gemfile: gemfiles/Gemfile.4.0.sqlite3
|
|
32
|
-
- rvm: "1.8.7"
|
|
33
|
-
gemfile: gemfiles/Gemfile.4.1.sqlite3
|
|
34
|
-
- rvm: "1.8.7"
|
|
35
|
-
gemfile: gemfiles/Gemfile.4.2.1.sqlite3
|
|
36
|
-
- rvm: "1.8.7"
|
|
37
|
-
gemfile: gemfiles/Gemfile.4.2.1.mysql2
|
|
38
|
-
- rvm: "1.8.7"
|
|
39
|
-
gemfile: gemfiles/Gemfile.4.2.1.pg
|
|
40
33
|
- rvm: "1.9.3"
|
|
41
34
|
gemfile: gemfiles/Gemfile.4.0.sqlite3
|
|
42
35
|
- rvm: "1.9.3"
|
|
@@ -45,6 +38,12 @@ matrix:
|
|
|
45
38
|
gemfile: gemfiles/Gemfile.4.2.1.pg
|
|
46
39
|
- rvm: "1.9.3"
|
|
47
40
|
gemfile: gemfiles/Gemfile.3.2.mysql2
|
|
41
|
+
- rvm: "1.9.3"
|
|
42
|
+
gemfile: gemfiles/Gemfile.5.0.0.sqlite3
|
|
43
|
+
- rvm: "1.9.3"
|
|
44
|
+
gemfile: gemfiles/Gemfile.5.0.0.mysql2
|
|
45
|
+
- rvm: "1.9.3"
|
|
46
|
+
gemfile: gemfiles/Gemfile.5.0.0.pg
|
|
48
47
|
- rvm: "2.0.0"
|
|
49
48
|
gemfile: gemfiles/Gemfile.4.0.sqlite3
|
|
50
49
|
- rvm: "2.0.0"
|
|
@@ -53,6 +52,14 @@ matrix:
|
|
|
53
52
|
gemfile: gemfiles/Gemfile.4.2.1.pg
|
|
54
53
|
- rvm: "2.0.0"
|
|
55
54
|
gemfile: gemfiles/Gemfile.3.2.mysql2
|
|
55
|
+
- rvm: "2.0.0"
|
|
56
|
+
gemfile: gemfiles/Gemfile.4.1.sqlite3
|
|
57
|
+
- rvm: "2.0.0"
|
|
58
|
+
gemfile: gemfiles/Gemfile.5.0.0.sqlite3
|
|
59
|
+
- rvm: "2.0.0"
|
|
60
|
+
gemfile: gemfiles/Gemfile.5.0.0.mysql2
|
|
61
|
+
- rvm: "2.0.0"
|
|
62
|
+
gemfile: gemfiles/Gemfile.5.0.0.pg
|
|
56
63
|
- rvm: "2.1.7"
|
|
57
64
|
gemfile: gemfiles/Gemfile.4.0.sqlite3
|
|
58
65
|
- rvm: "2.1.7"
|
|
@@ -61,3 +68,21 @@ matrix:
|
|
|
61
68
|
gemfile: gemfiles/Gemfile.4.2.1.pg
|
|
62
69
|
- rvm: "2.1.7"
|
|
63
70
|
gemfile: gemfiles/Gemfile.3.2.mysql2
|
|
71
|
+
- rvm: "2.1.7"
|
|
72
|
+
gemfile: gemfiles/Gemfile.4.1.sqlite3
|
|
73
|
+
- rvm: "2.1.7"
|
|
74
|
+
gemfile: gemfiles/Gemfile.5.0.0.sqlite3
|
|
75
|
+
- rvm: "2.1.7"
|
|
76
|
+
gemfile: gemfiles/Gemfile.5.0.0.mysql2
|
|
77
|
+
- rvm: "2.1.7"
|
|
78
|
+
gemfile: gemfiles/Gemfile.5.0.0.pg
|
|
79
|
+
- rvm: "2.2.4"
|
|
80
|
+
gemfile: gemfiles/Gemfile.4.0.sqlite3
|
|
81
|
+
- rvm: "2.2.4"
|
|
82
|
+
gemfile: gemfiles/Gemfile.4.2.1.mysql2
|
|
83
|
+
- rvm: "2.2.4"
|
|
84
|
+
gemfile: gemfiles/Gemfile.4.2.1.pg
|
|
85
|
+
- rvm: "2.2.4"
|
|
86
|
+
gemfile: gemfiles/Gemfile.3.2.mysql2
|
|
87
|
+
- rvm: "2.2.4"
|
|
88
|
+
gemfile: gemfiles/Gemfile.4.1.sqlite3
|
data/CHANGELOG.md
CHANGED
|
@@ -4,9 +4,38 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
ActiveType is in a pre-1.0 state. This means that its APIs and behavior are subject to breaking changes without deprecation notices. Until 1.0, version numbers will follow a [Semver][]-ish `0.y.z` format, where `y` is incremented when new features or breaking changes are introduced, and `z` is incremented for lesser changes or bug fixes.
|
|
6
6
|
|
|
7
|
-
## [
|
|
7
|
+
## [0.6.0][] (2016-07-05)
|
|
8
8
|
|
|
9
|
-
*
|
|
9
|
+
* Drop support for 1.8.7.
|
|
10
|
+
* Rails 5 compatibility.
|
|
11
|
+
|
|
12
|
+
## [0.5.1][] (2016-05-09)
|
|
13
|
+
|
|
14
|
+
* Fix an issue with incorrectly copied errors on Util.cast.
|
|
15
|
+
|
|
16
|
+
## [0.5.0][] (2016-04-08)
|
|
17
|
+
|
|
18
|
+
* Nicer `#inspect` method.
|
|
19
|
+
|
|
20
|
+
## [0.4.5][] (2016-02-01)
|
|
21
|
+
|
|
22
|
+
* Fixed issue `#dup`ing `ActiveType::Object`
|
|
23
|
+
|
|
24
|
+
## [0.4.4][] (2016-01-18)
|
|
25
|
+
|
|
26
|
+
* Call `#after_commit` for `ActiveType::Object`
|
|
27
|
+
|
|
28
|
+
## [0.4.3][] (2015-11-11)
|
|
29
|
+
|
|
30
|
+
* Fix issue with Booleans on mysql.
|
|
31
|
+
|
|
32
|
+
## [0.4.2][] (2015-09-24)
|
|
33
|
+
|
|
34
|
+
* Add `attribute_will_change!` for virtual attributes.
|
|
35
|
+
|
|
36
|
+
## [0.4.1][] (2015-09-24)
|
|
37
|
+
|
|
38
|
+
* Add `attribute_was` for virtual attributes.
|
|
10
39
|
|
|
11
40
|
## [0.4.0][] (2015-06-12)
|
|
12
41
|
|
data/README.md
CHANGED
|
@@ -50,6 +50,23 @@ class SignUp < ActiveType::Record[User]
|
|
|
50
50
|
end
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
+
|
|
54
|
+
### A note on Rails 5
|
|
55
|
+
|
|
56
|
+
Rails 5 comes with its own implementation of `.attribute`. This implementation is functionally very
|
|
57
|
+
similar, but not identical to ActiveType's.
|
|
58
|
+
|
|
59
|
+
We have decided to continue to use our own implementation. This means that if you use ActiveType, `ActiveRecord::Base.attribute` will be overriden.
|
|
60
|
+
|
|
61
|
+
The following behaviours are different than in vanilla Rails 5:
|
|
62
|
+
|
|
63
|
+
- Defaults `proc`s are evaluated in instance context, not class context.
|
|
64
|
+
- Defaults are evaluated lazily.
|
|
65
|
+
- You can override attributes with custom methods and use `super`.
|
|
66
|
+
- Attributes will work on records retrieved via `.find`.
|
|
67
|
+
- Attributes will be duped if you dup the record.
|
|
68
|
+
|
|
69
|
+
|
|
53
70
|
### ActiveType::Object
|
|
54
71
|
|
|
55
72
|
|
|
@@ -307,14 +324,14 @@ sign_up.is_a?(SignUp) # => true
|
|
|
307
324
|
Supported Rails versions
|
|
308
325
|
------------------------
|
|
309
326
|
|
|
310
|
-
ActiveType is tested against ActiveRecord 3.2, 4.0, 4.1
|
|
327
|
+
ActiveType is tested against ActiveRecord 3.2, 4.0, 4.1, 4.2 and 5.0.
|
|
311
328
|
|
|
312
329
|
Later versions might work, earlier will not.
|
|
313
330
|
|
|
314
331
|
Supported Ruby versions
|
|
315
332
|
------------------------
|
|
316
333
|
|
|
317
|
-
ActiveType is tested against
|
|
334
|
+
ActiveType is tested against 1.9.3, 2.0.0, 2.1.2 (for 4.x only), 2.2.4 and 2.3.1.
|
|
318
335
|
|
|
319
336
|
|
|
320
337
|
Installation
|
data/active_type.gemspec
CHANGED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: ..
|
|
3
|
+
specs:
|
|
4
|
+
active_type (0.6.0)
|
|
5
|
+
activerecord (>= 3.2)
|
|
6
|
+
|
|
7
|
+
GEM
|
|
8
|
+
remote: https://rubygems.org/
|
|
9
|
+
specs:
|
|
10
|
+
activemodel (5.0.0)
|
|
11
|
+
activesupport (= 5.0.0)
|
|
12
|
+
activerecord (5.0.0)
|
|
13
|
+
activemodel (= 5.0.0)
|
|
14
|
+
activesupport (= 5.0.0)
|
|
15
|
+
arel (~> 7.0)
|
|
16
|
+
activesupport (5.0.0)
|
|
17
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
18
|
+
i18n (~> 0.7)
|
|
19
|
+
minitest (~> 5.1)
|
|
20
|
+
tzinfo (~> 1.1)
|
|
21
|
+
arel (7.0.0)
|
|
22
|
+
concurrent-ruby (1.0.2)
|
|
23
|
+
diff-lcs (1.2.5)
|
|
24
|
+
i18n (0.7.0)
|
|
25
|
+
minitest (5.9.0)
|
|
26
|
+
mysql2 (0.3.21)
|
|
27
|
+
rspec (3.5.0)
|
|
28
|
+
rspec-core (~> 3.5.0)
|
|
29
|
+
rspec-expectations (~> 3.5.0)
|
|
30
|
+
rspec-mocks (~> 3.5.0)
|
|
31
|
+
rspec-core (3.5.0)
|
|
32
|
+
rspec-support (~> 3.5.0)
|
|
33
|
+
rspec-expectations (3.5.0)
|
|
34
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
35
|
+
rspec-support (~> 3.5.0)
|
|
36
|
+
rspec-mocks (3.5.0)
|
|
37
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
38
|
+
rspec-support (~> 3.5.0)
|
|
39
|
+
rspec-support (3.5.0)
|
|
40
|
+
thread_safe (0.3.5)
|
|
41
|
+
tzinfo (1.2.2)
|
|
42
|
+
thread_safe (~> 0.1)
|
|
43
|
+
|
|
44
|
+
PLATFORMS
|
|
45
|
+
ruby
|
|
46
|
+
|
|
47
|
+
DEPENDENCIES
|
|
48
|
+
active_type!
|
|
49
|
+
activerecord (~> 5.0.0)
|
|
50
|
+
mysql2 (~> 0.3.17)
|
|
51
|
+
rspec (~> 3.4)
|
|
52
|
+
|
|
53
|
+
BUNDLED WITH
|
|
54
|
+
1.12.1
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: ..
|
|
3
|
+
specs:
|
|
4
|
+
active_type (0.6.0)
|
|
5
|
+
activerecord (>= 3.2)
|
|
6
|
+
|
|
7
|
+
GEM
|
|
8
|
+
remote: https://rubygems.org/
|
|
9
|
+
specs:
|
|
10
|
+
activemodel (5.0.0)
|
|
11
|
+
activesupport (= 5.0.0)
|
|
12
|
+
activerecord (5.0.0)
|
|
13
|
+
activemodel (= 5.0.0)
|
|
14
|
+
activesupport (= 5.0.0)
|
|
15
|
+
arel (~> 7.0)
|
|
16
|
+
activesupport (5.0.0)
|
|
17
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
18
|
+
i18n (~> 0.7)
|
|
19
|
+
minitest (~> 5.1)
|
|
20
|
+
tzinfo (~> 1.1)
|
|
21
|
+
arel (7.0.0)
|
|
22
|
+
concurrent-ruby (1.0.2)
|
|
23
|
+
diff-lcs (1.2.5)
|
|
24
|
+
i18n (0.7.0)
|
|
25
|
+
minitest (5.9.0)
|
|
26
|
+
pg (0.18.4)
|
|
27
|
+
rspec (3.5.0)
|
|
28
|
+
rspec-core (~> 3.5.0)
|
|
29
|
+
rspec-expectations (~> 3.5.0)
|
|
30
|
+
rspec-mocks (~> 3.5.0)
|
|
31
|
+
rspec-core (3.5.0)
|
|
32
|
+
rspec-support (~> 3.5.0)
|
|
33
|
+
rspec-expectations (3.5.0)
|
|
34
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
35
|
+
rspec-support (~> 3.5.0)
|
|
36
|
+
rspec-mocks (3.5.0)
|
|
37
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
38
|
+
rspec-support (~> 3.5.0)
|
|
39
|
+
rspec-support (3.5.0)
|
|
40
|
+
thread_safe (0.3.5)
|
|
41
|
+
tzinfo (1.2.2)
|
|
42
|
+
thread_safe (~> 0.1)
|
|
43
|
+
|
|
44
|
+
PLATFORMS
|
|
45
|
+
ruby
|
|
46
|
+
|
|
47
|
+
DEPENDENCIES
|
|
48
|
+
active_type!
|
|
49
|
+
activerecord (~> 5.0.0)
|
|
50
|
+
pg
|
|
51
|
+
rspec (~> 3.4)
|
|
52
|
+
|
|
53
|
+
BUNDLED WITH
|
|
54
|
+
1.12.1
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: ..
|
|
3
|
+
specs:
|
|
4
|
+
active_type (0.6.0)
|
|
5
|
+
activerecord (>= 3.2)
|
|
6
|
+
|
|
7
|
+
GEM
|
|
8
|
+
remote: https://rubygems.org/
|
|
9
|
+
specs:
|
|
10
|
+
activemodel (5.0.0)
|
|
11
|
+
activesupport (= 5.0.0)
|
|
12
|
+
activerecord (5.0.0)
|
|
13
|
+
activemodel (= 5.0.0)
|
|
14
|
+
activesupport (= 5.0.0)
|
|
15
|
+
arel (~> 7.0)
|
|
16
|
+
activesupport (5.0.0)
|
|
17
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
18
|
+
i18n (~> 0.7)
|
|
19
|
+
minitest (~> 5.1)
|
|
20
|
+
tzinfo (~> 1.1)
|
|
21
|
+
arel (7.0.0)
|
|
22
|
+
concurrent-ruby (1.0.2)
|
|
23
|
+
diff-lcs (1.2.5)
|
|
24
|
+
i18n (0.7.0)
|
|
25
|
+
minitest (5.9.0)
|
|
26
|
+
rspec (3.5.0)
|
|
27
|
+
rspec-core (~> 3.5.0)
|
|
28
|
+
rspec-expectations (~> 3.5.0)
|
|
29
|
+
rspec-mocks (~> 3.5.0)
|
|
30
|
+
rspec-core (3.5.0)
|
|
31
|
+
rspec-support (~> 3.5.0)
|
|
32
|
+
rspec-expectations (3.5.0)
|
|
33
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
34
|
+
rspec-support (~> 3.5.0)
|
|
35
|
+
rspec-mocks (3.5.0)
|
|
36
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
37
|
+
rspec-support (~> 3.5.0)
|
|
38
|
+
rspec-support (3.5.0)
|
|
39
|
+
sqlite3 (1.3.11)
|
|
40
|
+
thread_safe (0.3.5)
|
|
41
|
+
tzinfo (1.2.2)
|
|
42
|
+
thread_safe (~> 0.1)
|
|
43
|
+
|
|
44
|
+
PLATFORMS
|
|
45
|
+
ruby
|
|
46
|
+
|
|
47
|
+
DEPENDENCIES
|
|
48
|
+
active_type!
|
|
49
|
+
activerecord (~> 5.0.0)
|
|
50
|
+
rspec (~> 3.4)
|
|
51
|
+
sqlite3
|
|
52
|
+
|
|
53
|
+
BUNDLED WITH
|
|
54
|
+
1.12.1
|
|
@@ -23,13 +23,48 @@ module ActiveType
|
|
|
23
23
|
|
|
24
24
|
private
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
if ActiveRecord::VERSION::MAJOR < 5
|
|
27
|
+
|
|
28
|
+
def find_sti_class(type_name)
|
|
29
|
+
sti_class = super
|
|
30
|
+
if self <= sti_class
|
|
31
|
+
self
|
|
32
|
+
else
|
|
33
|
+
sti_class
|
|
34
|
+
end
|
|
32
35
|
end
|
|
36
|
+
|
|
37
|
+
else
|
|
38
|
+
|
|
39
|
+
# Rails 5 find_sti_class does a sanity check for proper inheritance that fails for
|
|
40
|
+
# our usecase
|
|
41
|
+
# copied from activerecord/lib/active_record/inheritance.rb
|
|
42
|
+
def find_sti_class(type_name)
|
|
43
|
+
type_name = base_class.type_for_attribute(inheritance_column).cast(type_name)
|
|
44
|
+
subclass = begin
|
|
45
|
+
if store_full_sti_class
|
|
46
|
+
ActiveSupport::Dependencies.constantize(type_name)
|
|
47
|
+
else
|
|
48
|
+
compute_type(type_name)
|
|
49
|
+
end
|
|
50
|
+
rescue NameError
|
|
51
|
+
raise ActiveRecord::SubclassNotFound,
|
|
52
|
+
"The single-table inheritance mechanism failed to locate the subclass: '#{type_name}'. " \
|
|
53
|
+
"This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " \
|
|
54
|
+
"Please rename this column if you didn't intend it to be used for storing the inheritance class " \
|
|
55
|
+
"or overwrite #{name}.inheritance_column to use another column for that information."
|
|
56
|
+
end
|
|
57
|
+
#### our code starts here
|
|
58
|
+
if self <= subclass
|
|
59
|
+
subclass = self
|
|
60
|
+
end
|
|
61
|
+
#### our code ends here
|
|
62
|
+
unless subclass == self || descendants.include?(subclass)
|
|
63
|
+
raise ActiveRecord::SubclassNotFound, "Invalid single-table inheritance type: #{subclass.name} is not a subclass of #{name}"
|
|
64
|
+
end
|
|
65
|
+
subclass
|
|
66
|
+
end
|
|
67
|
+
|
|
33
68
|
end
|
|
34
69
|
|
|
35
70
|
end
|
|
@@ -28,7 +28,7 @@ module ActiveType
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def add_attribute(name, options)
|
|
31
|
-
@owner.attribute(name, options)
|
|
31
|
+
@owner.attribute(name, :object, options)
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def add_writer_method(name, association)
|
|
@@ -41,7 +41,7 @@ module ActiveType
|
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def add_autosave(name, association)
|
|
44
|
-
save_method = "save_associated_records_for_#{name}"
|
|
44
|
+
save_method = :"save_associated_records_for_#{name}"
|
|
45
45
|
@module.module_eval do
|
|
46
46
|
define_method save_method do
|
|
47
47
|
association.save(self)
|
|
@@ -51,7 +51,7 @@ module ActiveType
|
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
def add_validation(name, association)
|
|
54
|
-
validate_method = "validate_associated_records_for_#{name}"
|
|
54
|
+
validate_method = :"validate_associated_records_for_#{name}"
|
|
55
55
|
@module.module_eval do
|
|
56
56
|
define_method validate_method do
|
|
57
57
|
association.validate(self)
|
data/lib/active_type/no_table.rb
CHANGED
|
@@ -1,81 +1,167 @@
|
|
|
1
1
|
module ActiveType
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
if ActiveRecord::VERSION::MAJOR < 5
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
module NoTable
|
|
6
6
|
|
|
7
|
+
extend ActiveSupport::Concern
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
module ClassMethods
|
|
10
|
+
|
|
11
|
+
def column_types
|
|
12
|
+
{}
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def columns
|
|
16
|
+
[]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def primary_key
|
|
20
|
+
nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def destroy(*)
|
|
24
|
+
new
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def destroy_all(*)
|
|
28
|
+
[]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def find_by_sql(*)
|
|
32
|
+
[]
|
|
33
|
+
end
|
|
9
34
|
|
|
10
|
-
def primary_key
|
|
11
|
-
nil
|
|
12
35
|
end
|
|
13
36
|
|
|
14
|
-
def
|
|
15
|
-
|
|
37
|
+
def id
|
|
38
|
+
nil
|
|
16
39
|
end
|
|
17
40
|
|
|
18
|
-
def
|
|
41
|
+
def attribute_names
|
|
19
42
|
[]
|
|
20
43
|
end
|
|
21
44
|
|
|
22
|
-
def
|
|
23
|
-
|
|
45
|
+
def transaction(&block)
|
|
46
|
+
@_current_transaction_records ||= []
|
|
47
|
+
yield
|
|
24
48
|
end
|
|
25
49
|
|
|
26
|
-
def
|
|
27
|
-
|
|
50
|
+
def destroy
|
|
51
|
+
@destroyed = true
|
|
52
|
+
freeze
|
|
28
53
|
end
|
|
29
54
|
|
|
55
|
+
def reload
|
|
56
|
+
self
|
|
57
|
+
end
|
|
30
58
|
|
|
31
|
-
|
|
32
|
-
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
def create(*)
|
|
63
|
+
true
|
|
33
64
|
end
|
|
34
65
|
|
|
35
|
-
|
|
66
|
+
def update(*)
|
|
67
|
+
true
|
|
68
|
+
end
|
|
36
69
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
70
|
+
if ActiveRecord::Base.private_method_defined?(:create_record)
|
|
71
|
+
def create_record(*)
|
|
72
|
+
true
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def update_record(*)
|
|
76
|
+
true
|
|
77
|
+
end
|
|
78
|
+
else
|
|
79
|
+
def _create_record(*)
|
|
80
|
+
@new_record = false
|
|
81
|
+
true
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def _update_record(*)
|
|
85
|
+
true
|
|
86
|
+
end
|
|
87
|
+
end
|
|
40
88
|
|
|
41
|
-
def attribute_names
|
|
42
|
-
[]
|
|
43
89
|
end
|
|
44
90
|
|
|
45
|
-
|
|
46
|
-
@_current_transaction_records ||= []
|
|
47
|
-
yield
|
|
48
|
-
end
|
|
91
|
+
else
|
|
49
92
|
|
|
50
|
-
|
|
51
|
-
@destroyed = true
|
|
52
|
-
freeze
|
|
53
|
-
end
|
|
93
|
+
# Rails 5+
|
|
54
94
|
|
|
55
|
-
|
|
56
|
-
self
|
|
57
|
-
end
|
|
95
|
+
module NoTable
|
|
58
96
|
|
|
97
|
+
extend ActiveSupport::Concern
|
|
59
98
|
|
|
60
|
-
|
|
99
|
+
class DummySchemaCache
|
|
61
100
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
101
|
+
def columns_hash(table_name)
|
|
102
|
+
{}
|
|
103
|
+
end
|
|
65
104
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
105
|
+
def data_source_exists?(table_name)
|
|
106
|
+
false
|
|
107
|
+
end
|
|
69
108
|
|
|
70
|
-
|
|
71
|
-
|
|
109
|
+
def clear_data_source_cache!(table_name)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
class DummyConnection < ActiveRecord::ConnectionAdapters::AbstractAdapter
|
|
115
|
+
|
|
116
|
+
attr_reader :schema_cache
|
|
117
|
+
|
|
118
|
+
def initialize(*)
|
|
119
|
+
super
|
|
120
|
+
@schema_cache = DummySchemaCache.new
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
module ClassMethods
|
|
126
|
+
|
|
127
|
+
def connection
|
|
128
|
+
@connection ||= DummyConnection.new(nil)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def destroy(*)
|
|
132
|
+
new
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def destroy_all(*)
|
|
136
|
+
[]
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def find_by_sql(*)
|
|
140
|
+
[]
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def destroy
|
|
146
|
+
@destroyed = true
|
|
147
|
+
freeze
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def reload
|
|
151
|
+
self
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
private
|
|
156
|
+
|
|
157
|
+
def create(*)
|
|
72
158
|
true
|
|
73
159
|
end
|
|
74
160
|
|
|
75
|
-
def
|
|
161
|
+
def update(*)
|
|
76
162
|
true
|
|
77
163
|
end
|
|
78
|
-
|
|
164
|
+
|
|
79
165
|
def _create_record(*)
|
|
80
166
|
@new_record = false
|
|
81
167
|
true
|
|
@@ -84,6 +170,7 @@ module ActiveType
|
|
|
84
170
|
def _update_record(*)
|
|
85
171
|
true
|
|
86
172
|
end
|
|
173
|
+
|
|
87
174
|
end
|
|
88
175
|
|
|
89
176
|
end
|
|
@@ -4,8 +4,10 @@ module ActiveType
|
|
|
4
4
|
def self.get(type, connection)
|
|
5
5
|
native_caster = if ActiveRecord::VERSION::STRING < '4.2'
|
|
6
6
|
NativeCasters::DelegateToColumn.new(type)
|
|
7
|
+
elsif ActiveRecord::VERSION::STRING < '5'
|
|
8
|
+
NativeCasters::DelegateToRails4Type.new(type, connection)
|
|
7
9
|
else
|
|
8
|
-
NativeCasters::
|
|
10
|
+
NativeCasters::DelegateToRails5Type.new(type)
|
|
9
11
|
end
|
|
10
12
|
new(type, native_caster)
|
|
11
13
|
end
|
|
@@ -62,7 +64,7 @@ module ActiveType
|
|
|
62
64
|
|
|
63
65
|
# Adapter for Rails 4.2+.
|
|
64
66
|
# In these versions, casting logic lives in subclasses of ActiveRecord::Type::Value
|
|
65
|
-
class
|
|
67
|
+
class DelegateToRails4Type
|
|
66
68
|
|
|
67
69
|
def initialize(type, connection)
|
|
68
70
|
# The specified type (e.g. "string") may not necessary match the
|
|
@@ -87,6 +89,32 @@ module ActiveType
|
|
|
87
89
|
|
|
88
90
|
end
|
|
89
91
|
|
|
92
|
+
# Adapter for Rails 5+.
|
|
93
|
+
# In these versions, casting logic lives in subclasses of ActiveRecord::Type::Value
|
|
94
|
+
class DelegateToRails5Type
|
|
95
|
+
|
|
96
|
+
def initialize(type)
|
|
97
|
+
@active_record_type = lookup(type)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def type_cast_from_user(value)
|
|
101
|
+
@active_record_type.cast(value)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
private
|
|
105
|
+
|
|
106
|
+
def lookup(type)
|
|
107
|
+
if type.respond_to?(:cast)
|
|
108
|
+
type
|
|
109
|
+
else
|
|
110
|
+
ActiveRecord::Type.lookup(type)
|
|
111
|
+
end
|
|
112
|
+
rescue ::ArgumentError => e
|
|
113
|
+
ActiveRecord::Type::Value.new
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
|
117
|
+
|
|
90
118
|
end
|
|
91
119
|
|
|
92
120
|
end
|
data/lib/active_type/util.rb
CHANGED
|
@@ -23,15 +23,24 @@ module ActiveType
|
|
|
23
23
|
# Rails 3.2, 4.2
|
|
24
24
|
casted.instance_variable_set(:@attributes, record.instance_variable_get(:@attributes))
|
|
25
25
|
# Rails 3.2
|
|
26
|
-
|
|
26
|
+
casted.instance_variable_set(:@attributes_cache, record.instance_variable_get(:@attributes_cache))
|
|
27
27
|
# Rails 4.2
|
|
28
28
|
casted.instance_variable_set(:@changed_attributes, record.instance_variable_get(:@changed_attributes))
|
|
29
|
+
# Rails 5.0
|
|
30
|
+
casted.instance_variable_set(:@mutation_tracker, record.instance_variable_get(:@mutation_tracker))
|
|
29
31
|
# Rails 3.2, 4.2
|
|
30
32
|
casted.instance_variable_set(:@new_record, record.new_record?)
|
|
31
33
|
# Rails 3.2, 4.2
|
|
32
34
|
casted.instance_variable_set(:@destroyed, record.destroyed?)
|
|
33
35
|
# Rails 3.2, 4.2
|
|
34
|
-
|
|
36
|
+
errors = record.errors
|
|
37
|
+
if errors.kind_of? ActiveModel::Errors
|
|
38
|
+
errors = errors.dup
|
|
39
|
+
# otherwise attributes defined in ActiveType::Record
|
|
40
|
+
# won't be visible to `errors.add`
|
|
41
|
+
errors.instance_variable_set(:@base, casted)
|
|
42
|
+
end
|
|
43
|
+
casted.instance_variable_set(:@errors, errors)
|
|
35
44
|
end
|
|
36
45
|
end
|
|
37
46
|
|
data/lib/active_type/version.rb
CHANGED
|
@@ -3,6 +3,12 @@ require 'ostruct'
|
|
|
3
3
|
|
|
4
4
|
module ObjectSpec
|
|
5
5
|
|
|
6
|
+
def self.type
|
|
7
|
+
if ActiveRecord::VERSION::MAJOR >= 5
|
|
8
|
+
@type ||= ActiveModel::Type::Value.new
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
6
12
|
class Object < ActiveType::Object
|
|
7
13
|
|
|
8
14
|
attribute :virtual_string, :string
|
|
@@ -11,6 +17,7 @@ module ObjectSpec
|
|
|
11
17
|
attribute :virtual_date, :date
|
|
12
18
|
attribute :virtual_boolean, :boolean
|
|
13
19
|
attribute :virtual_attribute
|
|
20
|
+
attribute :virtual_type_attribute, ObjectSpec.type
|
|
14
21
|
|
|
15
22
|
end
|
|
16
23
|
|
|
@@ -171,6 +178,10 @@ describe ActiveType::Object do
|
|
|
171
178
|
describe 'untyped columns' do
|
|
172
179
|
it_should_behave_like 'an untyped column', :virtual_attribute
|
|
173
180
|
end
|
|
181
|
+
|
|
182
|
+
describe 'type columns' do
|
|
183
|
+
it_should_behave_like 'a coercible type column', :virtual_type_attribute, ObjectSpec.type
|
|
184
|
+
end
|
|
174
185
|
end
|
|
175
186
|
|
|
176
187
|
describe 'query methods' do
|
|
@@ -218,7 +229,7 @@ describe ActiveType::Object do
|
|
|
218
229
|
subject.virtual_boolean = true
|
|
219
230
|
subject.virtual_attribute = OpenStruct.new({:test => "openstruct"})
|
|
220
231
|
|
|
221
|
-
expect(subject.inspect).to eq("#<ObjectSpec::Object virtual_attribute: #<OpenStruct test=\"openstruct\">, virtual_boolean: true, virtual_date: \"#{Date.today}\", virtual_integer: 17, virtual_string: \"string\", virtual_time: \"#{t.to_s(:db)}\">")
|
|
232
|
+
expect(subject.inspect).to eq("#<ObjectSpec::Object virtual_attribute: #<OpenStruct test=\"openstruct\">, virtual_boolean: true, virtual_date: \"#{Date.today}\", virtual_integer: 17, virtual_string: \"string\", virtual_time: \"#{t.to_s(:db)}\", virtual_type_attribute: nil>")
|
|
222
233
|
end
|
|
223
234
|
|
|
224
235
|
end
|
|
@@ -236,6 +247,7 @@ describe ActiveType::Object do
|
|
|
236
247
|
"virtual_date" => nil,
|
|
237
248
|
"virtual_boolean" => nil,
|
|
238
249
|
"virtual_attribute" => nil,
|
|
250
|
+
"virtual_type_attribute" => nil,
|
|
239
251
|
})
|
|
240
252
|
end
|
|
241
253
|
|
|
@@ -252,6 +264,7 @@ describe ActiveType::Object do
|
|
|
252
264
|
"virtual_boolean" => nil,
|
|
253
265
|
"virtual_attribute" => nil,
|
|
254
266
|
"another_virtual_string" => nil,
|
|
267
|
+
"virtual_type_attribute" => nil,
|
|
255
268
|
})
|
|
256
269
|
end
|
|
257
270
|
|
|
@@ -268,6 +281,7 @@ describe ActiveType::Object do
|
|
|
268
281
|
"virtual_boolean" => nil,
|
|
269
282
|
"virtual_attribute" => nil,
|
|
270
283
|
"another_virtual_string" => nil,
|
|
284
|
+
"virtual_type_attribute" => nil,
|
|
271
285
|
})
|
|
272
286
|
end
|
|
273
287
|
|
|
@@ -381,7 +395,13 @@ describe ActiveType::Object do
|
|
|
381
395
|
%w[before_validation before_save].each do |callback|
|
|
382
396
|
|
|
383
397
|
it "aborts the chain when #{callback} returns false" do
|
|
384
|
-
|
|
398
|
+
if ActiveRecord::VERSION::MAJOR >= 5
|
|
399
|
+
allow(subject).to receive("#{callback}_callback") do
|
|
400
|
+
throw(:abort)
|
|
401
|
+
end
|
|
402
|
+
else
|
|
403
|
+
allow(subject).to receive_messages("#{callback}_callback" => false)
|
|
404
|
+
end
|
|
385
405
|
|
|
386
406
|
expect(subject.save).to be_falsey
|
|
387
407
|
end
|
|
@@ -404,9 +424,17 @@ describe ActiveType::Object do
|
|
|
404
424
|
|
|
405
425
|
end
|
|
406
426
|
|
|
427
|
+
describe '#id' do
|
|
428
|
+
|
|
429
|
+
it 'is nil' do
|
|
430
|
+
expect(subject.id).to eq nil
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
end
|
|
434
|
+
|
|
407
435
|
describe '.find' do
|
|
408
436
|
it 'raises an error' do
|
|
409
|
-
error = if ActiveRecord::VERSION::MAJOR
|
|
437
|
+
error = if ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR >= 1
|
|
410
438
|
ActiveRecord::UnknownPrimaryKey
|
|
411
439
|
else
|
|
412
440
|
ActiveRecord::RecordNotFound
|
|
@@ -3,6 +3,12 @@ require 'ostruct'
|
|
|
3
3
|
|
|
4
4
|
module RecordSpec
|
|
5
5
|
|
|
6
|
+
def self.type
|
|
7
|
+
if ActiveRecord::VERSION::MAJOR >= 5
|
|
8
|
+
@type ||= ActiveModel::Type::Value.new
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
6
12
|
class Record < ActiveType::Record
|
|
7
13
|
|
|
8
14
|
attribute :virtual_string, :string
|
|
@@ -11,6 +17,7 @@ module RecordSpec
|
|
|
11
17
|
attribute :virtual_date, :date
|
|
12
18
|
attribute :virtual_boolean, :boolean
|
|
13
19
|
attribute :virtual_attribute
|
|
20
|
+
attribute :virtual_type_attribute, RecordSpec.type
|
|
14
21
|
|
|
15
22
|
end
|
|
16
23
|
|
|
@@ -58,6 +65,7 @@ end
|
|
|
58
65
|
describe ActiveType::Record do
|
|
59
66
|
|
|
60
67
|
subject { RecordSpec::Record.new }
|
|
68
|
+
t = Time.new(2016, 2, 1, 12)
|
|
61
69
|
|
|
62
70
|
it 'is a ActiveRecord::Base' do
|
|
63
71
|
expect(subject).to be_a(ActiveRecord::Base)
|
|
@@ -70,22 +78,22 @@ describe ActiveType::Record do
|
|
|
70
78
|
describe 'constructors' do
|
|
71
79
|
subject { RecordSpec::Record }
|
|
72
80
|
|
|
73
|
-
it_should_behave_like 'ActiveRecord-like constructors', { :persisted_string => "string", :persisted_integer => 100, :persisted_time =>
|
|
81
|
+
it_should_behave_like 'ActiveRecord-like constructors', { :persisted_string => "string", :persisted_integer => 100, :persisted_time => t, :persisted_date => Date.today, :persisted_boolean => true }
|
|
74
82
|
|
|
75
|
-
it_should_behave_like 'ActiveRecord-like constructors', { :virtual_string => "string", :virtual_integer => 100, :virtual_time =>
|
|
83
|
+
it_should_behave_like 'ActiveRecord-like constructors', { :virtual_string => "string", :virtual_integer => 100, :virtual_time => t, :virtual_date => Date.today, :virtual_boolean => true }
|
|
76
84
|
|
|
77
85
|
end
|
|
78
86
|
|
|
79
87
|
describe 'mass assignment' do
|
|
80
|
-
it_should_behave_like 'ActiveRecord-like mass assignment', { :persisted_string => "string", :persisted_integer => 100, :persisted_time =>
|
|
88
|
+
it_should_behave_like 'ActiveRecord-like mass assignment', { :persisted_string => "string", :persisted_integer => 100, :persisted_time => t, :persisted_date => Date.today, :persisted_boolean => true }
|
|
81
89
|
|
|
82
|
-
it_should_behave_like 'ActiveRecord-like mass assignment', { :virtual_string => "string", :virtual_integer => 100, :virtual_time =>
|
|
90
|
+
it_should_behave_like 'ActiveRecord-like mass assignment', { :virtual_string => "string", :virtual_integer => 100, :virtual_time => t, :virtual_date => Date.today, :virtual_boolean => true }
|
|
83
91
|
end
|
|
84
92
|
|
|
85
93
|
describe 'accessors' do
|
|
86
|
-
it_should_behave_like 'ActiveRecord-like accessors', { :persisted_string => "string", :persisted_integer => 100, :persisted_time =>
|
|
94
|
+
it_should_behave_like 'ActiveRecord-like accessors', { :persisted_string => "string", :persisted_integer => 100, :persisted_time => t, :persisted_date => Date.today, :persisted_boolean => true }
|
|
87
95
|
|
|
88
|
-
it_should_behave_like 'ActiveRecord-like accessors', { :virtual_string => "string", :virtual_integer => 100, :virtual_time =>
|
|
96
|
+
it_should_behave_like 'ActiveRecord-like accessors', { :virtual_string => "string", :virtual_integer => 100, :virtual_time => t, :virtual_date => Date.today, :virtual_boolean => true }
|
|
89
97
|
end
|
|
90
98
|
|
|
91
99
|
describe 'overridable attributes' do
|
|
@@ -150,6 +158,10 @@ describe ActiveType::Record do
|
|
|
150
158
|
describe 'untyped columns' do
|
|
151
159
|
it_should_behave_like 'an untyped column', :virtual_attribute
|
|
152
160
|
end
|
|
161
|
+
|
|
162
|
+
describe 'type columns' do
|
|
163
|
+
it_should_behave_like 'a coercible type column', :virtual_type_attribute, RecordSpec.type
|
|
164
|
+
end
|
|
153
165
|
end
|
|
154
166
|
|
|
155
167
|
describe '#inspect' do
|
|
@@ -165,7 +177,7 @@ describe ActiveType::Record do
|
|
|
165
177
|
subject.virtual_boolean = true
|
|
166
178
|
subject.virtual_attribute = OpenStruct.new({:test => "openstruct"})
|
|
167
179
|
|
|
168
|
-
expect(subject.inspect).to eq("#<RecordSpec::Record id: nil, persisted_boolean: nil, persisted_date: nil, persisted_integer: 20, persisted_string: \"persisted string\", persisted_time: nil, virtual_attribute: #<OpenStruct test=\"openstruct\">, virtual_boolean: true, virtual_date: \"#{Date.today}\", virtual_integer: 17, virtual_string: \"string\", virtual_time: \"#{t.to_s(:db)}\">")
|
|
180
|
+
expect(subject.inspect).to eq("#<RecordSpec::Record id: nil, persisted_boolean: nil, persisted_date: nil, persisted_integer: 20, persisted_string: \"persisted string\", persisted_time: nil, virtual_attribute: #<OpenStruct test=\"openstruct\">, virtual_boolean: true, virtual_date: \"#{Date.today}\", virtual_integer: 17, virtual_string: \"string\", virtual_time: \"#{t.to_s(:db)}\", virtual_type_attribute: nil>")
|
|
169
181
|
end
|
|
170
182
|
|
|
171
183
|
end
|
|
@@ -184,12 +196,13 @@ describe ActiveType::Record do
|
|
|
184
196
|
"virtual_date" => nil,
|
|
185
197
|
"virtual_boolean" => nil,
|
|
186
198
|
"virtual_attribute" => nil,
|
|
199
|
+
"virtual_type_attribute" => nil,
|
|
187
200
|
"id" => nil,
|
|
188
201
|
"persisted_string" => "string",
|
|
189
202
|
"persisted_integer" => nil,
|
|
190
203
|
"persisted_time" => nil,
|
|
191
204
|
"persisted_date" => nil,
|
|
192
|
-
"persisted_boolean" => nil
|
|
205
|
+
"persisted_boolean" => nil,
|
|
193
206
|
})
|
|
194
207
|
end
|
|
195
208
|
|
|
@@ -252,4 +265,10 @@ describe ActiveType::Record do
|
|
|
252
265
|
it_should_behave_like 'a belongs_to association', :child, RecordSpec::Child
|
|
253
266
|
end
|
|
254
267
|
|
|
268
|
+
it 'can access virtual attributes after .find' do
|
|
269
|
+
subject.save!
|
|
270
|
+
expect(subject.class.find(subject.id).virtual_string).to eq(nil)
|
|
271
|
+
expect(subject.class.find(subject.id).virtual_string).to eq(nil)
|
|
272
|
+
end
|
|
273
|
+
|
|
255
274
|
end
|
|
@@ -9,9 +9,12 @@ module UtilSpec
|
|
|
9
9
|
class ExtendedRecord < ActiveType::Record[BaseRecord]
|
|
10
10
|
|
|
11
11
|
attribute :virtual_string
|
|
12
|
+
attribute :virtual_string_for_validation
|
|
12
13
|
after_initialize :set_virtual_string
|
|
14
|
+
attr_reader :after_initialize_called
|
|
13
15
|
|
|
14
16
|
def set_virtual_string
|
|
17
|
+
@after_initialize_called = true
|
|
15
18
|
self.virtual_string = "persisted_string is #{persisted_string}"
|
|
16
19
|
end
|
|
17
20
|
|
|
@@ -84,7 +87,7 @@ describe ActiveType::Util do
|
|
|
84
87
|
it 'calls after_initialize callbacks of the cast target' do
|
|
85
88
|
base_record = UtilSpec::BaseRecord.create!(:persisted_string => 'foo')
|
|
86
89
|
extended_record = ActiveType::Util.cast(base_record, UtilSpec::ExtendedRecord)
|
|
87
|
-
expect(extended_record.
|
|
90
|
+
expect(extended_record.after_initialize_called).to eq true
|
|
88
91
|
end
|
|
89
92
|
|
|
90
93
|
it 'lets after_initialize callbacks access attributes (bug in ActiveRecord#becomes)' do
|
|
@@ -117,6 +120,17 @@ describe ActiveType::Util do
|
|
|
117
120
|
expect(extended_record.changes).to eq({ 'persisted_string' => ['foo', 'bar'] })
|
|
118
121
|
end
|
|
119
122
|
|
|
123
|
+
it 'associates the error object correctly with the new type (BUGFIX)' do
|
|
124
|
+
base_record = UtilSpec::BaseRecord.create!(:persisted_string => 'foo')
|
|
125
|
+
extended_record = ActiveType::Util.cast(base_record, UtilSpec::ExtendedRecord)
|
|
126
|
+
expect {
|
|
127
|
+
value = extended_record.virtual_string_for_validation
|
|
128
|
+
extended_record.errors.add(:virtual_string_for_validation, :empty) if value.nil? || value.empty?
|
|
129
|
+
}.not_to raise_error
|
|
130
|
+
expect(extended_record.errors.size).to eq 1
|
|
131
|
+
expect(base_record.errors.size).to eq 0
|
|
132
|
+
end
|
|
133
|
+
|
|
120
134
|
end
|
|
121
135
|
|
|
122
136
|
end
|
|
@@ -1,21 +1,4 @@
|
|
|
1
|
-
class User < ::ActiveRecord::Base
|
|
2
|
-
end
|
|
3
|
-
|
|
4
|
-
class Foo < ::ActiveType::Record[User]
|
|
5
|
-
def new
|
|
6
|
-
allocate
|
|
7
|
-
end
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
|
|
11
1
|
shared_examples_for "ActiveRecord-like accessors" do |attributes|
|
|
12
|
-
it 'setup the virtual_attributes instance variable lazy' do
|
|
13
|
-
expect(Foo.new.virtual_attributes).to eq({})
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it 'setup the virtual_attributes_cache instance variable lazy' do
|
|
17
|
-
expect(Foo.new.virtual_attributes_cache).to eq({})
|
|
18
|
-
end
|
|
19
2
|
|
|
20
3
|
it 'allows to read and write' do
|
|
21
4
|
attributes.each do |key, value|
|
|
@@ -115,7 +115,7 @@ shared_examples_for 'a coercible time column' do |column|
|
|
|
115
115
|
end
|
|
116
116
|
|
|
117
117
|
it 'leaves times alone' do
|
|
118
|
-
time = Time.now
|
|
118
|
+
time = Time.at(Time.now.to_i)
|
|
119
119
|
subject.send(:"#{column}=", time)
|
|
120
120
|
|
|
121
121
|
expect(subject.send(column)).to eq(time)
|
|
@@ -226,3 +226,23 @@ shared_examples_for 'an untyped column' do |column|
|
|
|
226
226
|
expect(subject.send(column)).to eq(object)
|
|
227
227
|
end
|
|
228
228
|
end
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
shared_examples_for 'a coercible type column' do |column, type|
|
|
232
|
+
|
|
233
|
+
if type
|
|
234
|
+
|
|
235
|
+
it 'is nil by default' do
|
|
236
|
+
expect(subject.send(column)).to be_nil
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
it 'leaves strings alone' do
|
|
240
|
+
expect(type).to receive(:cast).with('input').and_return('output')
|
|
241
|
+
subject.send(:"#{column}=", 'input')
|
|
242
|
+
|
|
243
|
+
expect(subject.send(column)).to eq('output')
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: active_type
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tobias Kraze
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2016-
|
|
12
|
+
date: 2016-07-05 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: bundler
|
|
@@ -60,6 +60,7 @@ extensions: []
|
|
|
60
60
|
extra_rdoc_files: []
|
|
61
61
|
files:
|
|
62
62
|
- ".gitignore"
|
|
63
|
+
- ".rspec"
|
|
63
64
|
- ".ruby-version"
|
|
64
65
|
- ".travis.yml"
|
|
65
66
|
- CHANGELOG.md
|
|
@@ -81,6 +82,12 @@ files:
|
|
|
81
82
|
- gemfiles/Gemfile.4.2.1.pg.lock
|
|
82
83
|
- gemfiles/Gemfile.4.2.1.sqlite3
|
|
83
84
|
- gemfiles/Gemfile.4.2.1.sqlite3.lock
|
|
85
|
+
- gemfiles/Gemfile.5.0.0.mysql2
|
|
86
|
+
- gemfiles/Gemfile.5.0.0.mysql2.lock
|
|
87
|
+
- gemfiles/Gemfile.5.0.0.pg
|
|
88
|
+
- gemfiles/Gemfile.5.0.0.pg.lock
|
|
89
|
+
- gemfiles/Gemfile.5.0.0.sqlite3
|
|
90
|
+
- gemfiles/Gemfile.5.0.0.sqlite3.lock
|
|
84
91
|
- lib/active_type.rb
|
|
85
92
|
- lib/active_type/extended_record.rb
|
|
86
93
|
- lib/active_type/extended_record/inheritance.rb
|
|
@@ -133,7 +140,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
133
140
|
requirements:
|
|
134
141
|
- - ">="
|
|
135
142
|
- !ruby/object:Gem::Version
|
|
136
|
-
version:
|
|
143
|
+
version: 1.9.3
|
|
137
144
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
138
145
|
requirements:
|
|
139
146
|
- - ">="
|
|
@@ -141,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
141
148
|
version: '0'
|
|
142
149
|
requirements: []
|
|
143
150
|
rubyforge_project:
|
|
144
|
-
rubygems_version: 2.4.
|
|
151
|
+
rubygems_version: 2.4.5.1
|
|
145
152
|
signing_key:
|
|
146
153
|
specification_version: 4
|
|
147
154
|
summary: Make any Ruby object quack like ActiveRecord
|