virtus_model 0.2.6 → 0.3.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/README.md +87 -0
- data/lib/virtus_model/base.rb +4 -3
- data/lib/virtus_model/version.rb +1 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/virtus_model/base_spec.rb +26 -0
- metadata +49 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4889888392103490330641562a43bbc90466a8c4
|
4
|
+
data.tar.gz: 13c865c370ea09c3e0a4857bd6b82ab511191f1c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 295d96a01e5a71b31db621c6a5de0a1b4a9ac47848d20eced14d6fdf197f5aabcbeaa4b19314b150410b6f04e519505601eb3ad24f62cc1dc83e31fdc65d504a
|
7
|
+
data.tar.gz: e1fb74537b824ebb7cb722694970a357aa707ca0ed011275c0bb9b7eba49cf1d48070e0a2160da5969f403a66f26719e5e68840bf7697de6ce2c7373100db90e
|
data/README.md
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# VirtusModel
|
2
|
+
|
3
|
+
A practical and pleasant union of [Virtus](https://rubygems.org/gems/virtus) and [ActiveModel](https://rubygems.org/gems/activemodel).
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Ruby version 2.2.2 or greater is required.
|
8
|
+
|
9
|
+
```shell
|
10
|
+
$ gem install virtus_model
|
11
|
+
```
|
12
|
+
|
13
|
+
## Examples
|
14
|
+
|
15
|
+
First, familiarize yourself with the Virtus and ActiveModel libraries.
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
#
|
19
|
+
# Class definitions
|
20
|
+
#
|
21
|
+
|
22
|
+
class ModelOne < VirtusModel::Base
|
23
|
+
attribute :name, String
|
24
|
+
|
25
|
+
validates :name, presence: true
|
26
|
+
end
|
27
|
+
|
28
|
+
class ModelTwo < VirtusModel::Base
|
29
|
+
attribute :models, Array[ModelOne]
|
30
|
+
|
31
|
+
validates :models, presence: true
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Class methods
|
36
|
+
#
|
37
|
+
|
38
|
+
raise unless ModelOne.attributes == [:name]
|
39
|
+
|
40
|
+
raise unless ModelOne.attribute?(:name)
|
41
|
+
|
42
|
+
raise if ModelOne.attribute?(:other)
|
43
|
+
|
44
|
+
raise unless ModelTwo.associations == [:models]
|
45
|
+
|
46
|
+
raise unless ModelTwo.association?(:models)
|
47
|
+
|
48
|
+
raise if ModelTwo.association?(:other)
|
49
|
+
|
50
|
+
#
|
51
|
+
# Instance methods
|
52
|
+
#
|
53
|
+
|
54
|
+
model1 = ModelOne.new(name: 'hello')
|
55
|
+
|
56
|
+
raise unless model1.attributes == { name: 'hello' }
|
57
|
+
|
58
|
+
raise unless model1.valid?
|
59
|
+
|
60
|
+
model1.assign_attributes(name: nil)
|
61
|
+
|
62
|
+
raise if model1.valid?
|
63
|
+
|
64
|
+
raise unless model1.errors[:name] == ["can't be blank"]
|
65
|
+
|
66
|
+
raise unless model1.update(name: 'hello')
|
67
|
+
|
68
|
+
model2 = ModelTwo.new(models: [model1.attributes])
|
69
|
+
|
70
|
+
raise unless model2.valid?
|
71
|
+
|
72
|
+
model2.assign_attributes(models: [])
|
73
|
+
|
74
|
+
raise if model2.valid?
|
75
|
+
|
76
|
+
raise unless model2.errors[:models] == ["can't be blank"]
|
77
|
+
|
78
|
+
raise if model2.update(models: [{ name: nil }])
|
79
|
+
|
80
|
+
raise unless model2.errors[:'models[0][name]'] == ["can't be blank"]
|
81
|
+
|
82
|
+
raise unless model2.update(models: [model1])
|
83
|
+
|
84
|
+
raise unless model2.export == { models: [{ name: 'hello' }] }
|
85
|
+
|
86
|
+
raise unless ModelTwo.new(model2.export) == model2
|
87
|
+
```
|
data/lib/virtus_model/base.rb
CHANGED
@@ -6,9 +6,10 @@ module VirtusModel
|
|
6
6
|
class Base
|
7
7
|
include ActiveModel::Conversion
|
8
8
|
include ActiveModel::Validations
|
9
|
-
include
|
9
|
+
include ActiveModel::Validations::Callbacks
|
10
|
+
include Virtus.model(nullify_blank: true)
|
10
11
|
|
11
|
-
|
12
|
+
before_validation :validate_associations
|
12
13
|
|
13
14
|
# Get an array of attribute names.
|
14
15
|
def self.attributes
|
@@ -107,7 +108,7 @@ module VirtusModel
|
|
107
108
|
self.class.attributes.reduce({}) do |result, name|
|
108
109
|
if model.respond_to?(name)
|
109
110
|
result[name] = model.public_send(name)
|
110
|
-
elsif model.respond_to?(:[])
|
111
|
+
elsif model.respond_to?(:[]) && model.respond_to?(:key?) && model.key?(name)
|
111
112
|
result[name] = model[name]
|
112
113
|
end
|
113
114
|
result
|
data/lib/virtus_model/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -8,6 +8,7 @@ describe VirtusModel::Base do
|
|
8
8
|
let(:simple_model_attributes) { { name: 'test' } }
|
9
9
|
|
10
10
|
describe SimpleModel, type: :model do
|
11
|
+
it { is_expected.to callback(:validate_associations).before(:validation) }
|
11
12
|
it { is_expected.to validate_presence_of(:name) }
|
12
13
|
end
|
13
14
|
|
@@ -27,6 +28,7 @@ describe VirtusModel::Base do
|
|
27
28
|
end
|
28
29
|
|
29
30
|
describe ComplexModel, type: :model do
|
31
|
+
it { is_expected.to callback(:validate_associations).before(:validation) }
|
30
32
|
it { is_expected.to validate_presence_of(:model) }
|
31
33
|
it { is_expected.to validate_presence_of(:models) }
|
32
34
|
end
|
@@ -36,10 +38,21 @@ describe VirtusModel::Base do
|
|
36
38
|
end
|
37
39
|
|
38
40
|
describe InheritedModel, type: :model do
|
41
|
+
it { is_expected.to callback(:validate_associations).before(:validation) }
|
39
42
|
it { is_expected.to validate_presence_of(:model) }
|
40
43
|
it { is_expected.to validate_presence_of(:models) }
|
41
44
|
end
|
42
45
|
|
46
|
+
class CallbackModel < ComplexModel
|
47
|
+
after_validation :child_callback
|
48
|
+
end
|
49
|
+
|
50
|
+
describe CallbackModel, type: :model do
|
51
|
+
before(:example) { allow(subject).to receive(:child_callback) }
|
52
|
+
it { is_expected.to callback(:validate_associations).before(:validation) }
|
53
|
+
it { is_expected.to callback(:child_callback).after(:validation) }
|
54
|
+
end
|
55
|
+
|
43
56
|
describe '.attribute?' do
|
44
57
|
context SimpleModel do
|
45
58
|
subject { SimpleModel }
|
@@ -130,8 +143,14 @@ describe VirtusModel::Base do
|
|
130
143
|
|
131
144
|
context 'hash' do
|
132
145
|
let(:attributes) { { name: 'test', other: 'test' } }
|
146
|
+
|
133
147
|
it { expect(subject.attributes).to include(name: 'test') }
|
134
148
|
it { expect(subject.attributes).not_to include(other: 'test') }
|
149
|
+
|
150
|
+
it 'does not overwrite omitted fields' do
|
151
|
+
expect(subject.assign_attributes({})).to be_a(SimpleModel)
|
152
|
+
expect(subject.attributes[:name]).to eq('test')
|
153
|
+
end
|
135
154
|
end
|
136
155
|
|
137
156
|
context 'object' do
|
@@ -146,9 +165,16 @@ describe VirtusModel::Base do
|
|
146
165
|
context 'hash' do
|
147
166
|
let(:attributes) { { model: model, models: [model], other: 'test' } }
|
148
167
|
let(:model) { { name: 'test', other: 'test' } }
|
168
|
+
|
149
169
|
it { expect(subject.attributes[:model]).to eq(SimpleModel.new(model)) }
|
150
170
|
it { expect(subject.attributes[:models]).to eq([SimpleModel.new(model)]) }
|
151
171
|
it { expect(subject.attributes).not_to include(other: 'test') }
|
172
|
+
|
173
|
+
it 'does not overwrite omitted fields' do
|
174
|
+
expect(subject.assign_attributes(model: nil)).to be_a(ComplexModel)
|
175
|
+
expect(subject.attributes[:model]).to be(nil)
|
176
|
+
expect(subject.attributes[:models]).to eq([SimpleModel.new(model)])
|
177
|
+
end
|
152
178
|
end
|
153
179
|
|
154
180
|
context 'object' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: virtus_model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Derek Schaefer
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: virtus
|
@@ -28,44 +28,56 @@ dependencies:
|
|
28
28
|
name: activemodel
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '4.2'
|
34
|
+
- - "<"
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '6'
|
34
37
|
type: :runtime
|
35
38
|
prerelease: false
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
37
40
|
requirements:
|
38
|
-
- - "
|
41
|
+
- - ">="
|
39
42
|
- !ruby/object:Gem::Version
|
40
43
|
version: '4.2'
|
44
|
+
- - "<"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '6'
|
41
47
|
- !ruby/object:Gem::Dependency
|
42
48
|
name: activesupport
|
43
49
|
requirement: !ruby/object:Gem::Requirement
|
44
50
|
requirements:
|
45
|
-
- - "
|
51
|
+
- - ">="
|
46
52
|
- !ruby/object:Gem::Version
|
47
53
|
version: '4.2'
|
54
|
+
- - "<"
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '6'
|
48
57
|
type: :runtime
|
49
58
|
prerelease: false
|
50
59
|
version_requirements: !ruby/object:Gem::Requirement
|
51
60
|
requirements:
|
52
|
-
- - "
|
61
|
+
- - ">="
|
53
62
|
- !ruby/object:Gem::Version
|
54
63
|
version: '4.2'
|
64
|
+
- - "<"
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '6'
|
55
67
|
- !ruby/object:Gem::Dependency
|
56
68
|
name: rake
|
57
69
|
requirement: !ruby/object:Gem::Requirement
|
58
70
|
requirements:
|
59
71
|
- - "~>"
|
60
72
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
73
|
+
version: '13.0'
|
62
74
|
type: :development
|
63
75
|
prerelease: false
|
64
76
|
version_requirements: !ruby/object:Gem::Requirement
|
65
77
|
requirements:
|
66
78
|
- - "~>"
|
67
79
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
80
|
+
version: '13.0'
|
69
81
|
- !ruby/object:Gem::Dependency
|
70
82
|
name: rdoc
|
71
83
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,49 +98,64 @@ dependencies:
|
|
86
98
|
requirements:
|
87
99
|
- - "~>"
|
88
100
|
- !ruby/object:Gem::Version
|
89
|
-
version: '3.
|
101
|
+
version: '3.10'
|
90
102
|
type: :development
|
91
103
|
prerelease: false
|
92
104
|
version_requirements: !ruby/object:Gem::Requirement
|
93
105
|
requirements:
|
94
106
|
- - "~>"
|
95
107
|
- !ruby/object:Gem::Version
|
96
|
-
version: '3.
|
108
|
+
version: '3.10'
|
97
109
|
- !ruby/object:Gem::Dependency
|
98
110
|
name: shoulda-matchers
|
99
111
|
requirement: !ruby/object:Gem::Requirement
|
100
112
|
requirements:
|
101
113
|
- - "~>"
|
102
114
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
115
|
+
version: '4.0'
|
116
|
+
type: :development
|
117
|
+
prerelease: false
|
118
|
+
version_requirements: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - "~>"
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '4.0'
|
123
|
+
- !ruby/object:Gem::Dependency
|
124
|
+
name: shoulda-callback-matchers
|
125
|
+
requirement: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - "~>"
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '1.1'
|
104
130
|
type: :development
|
105
131
|
prerelease: false
|
106
132
|
version_requirements: !ruby/object:Gem::Requirement
|
107
133
|
requirements:
|
108
134
|
- - "~>"
|
109
135
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
136
|
+
version: '1.1'
|
111
137
|
- !ruby/object:Gem::Dependency
|
112
138
|
name: simplecov
|
113
139
|
requirement: !ruby/object:Gem::Requirement
|
114
140
|
requirements:
|
115
141
|
- - "~>"
|
116
142
|
- !ruby/object:Gem::Version
|
117
|
-
version: '0.
|
143
|
+
version: '0.17'
|
118
144
|
type: :development
|
119
145
|
prerelease: false
|
120
146
|
version_requirements: !ruby/object:Gem::Requirement
|
121
147
|
requirements:
|
122
148
|
- - "~>"
|
123
149
|
- !ruby/object:Gem::Version
|
124
|
-
version: '0.
|
125
|
-
description:
|
150
|
+
version: '0.17'
|
151
|
+
description: A practical and pleasant union of Virtus and ActiveModel.
|
126
152
|
email:
|
127
153
|
- derek.schaefer@gmail.com
|
128
154
|
executables: []
|
129
155
|
extensions: []
|
130
156
|
extra_rdoc_files: []
|
131
157
|
files:
|
158
|
+
- README.md
|
132
159
|
- lib/virtus_model.rb
|
133
160
|
- lib/virtus_model/base.rb
|
134
161
|
- lib/virtus_model/version.rb
|
@@ -138,7 +165,7 @@ homepage: https://github.com/derek-schaefer/virtus_model
|
|
138
165
|
licenses:
|
139
166
|
- MIT
|
140
167
|
metadata: {}
|
141
|
-
post_install_message:
|
168
|
+
post_install_message:
|
142
169
|
rdoc_options: []
|
143
170
|
require_paths:
|
144
171
|
- lib
|
@@ -146,18 +173,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
146
173
|
requirements:
|
147
174
|
- - ">="
|
148
175
|
- !ruby/object:Gem::Version
|
149
|
-
version: 2.
|
176
|
+
version: 2.2.2
|
150
177
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
178
|
requirements:
|
152
179
|
- - ">="
|
153
180
|
- !ruby/object:Gem::Version
|
154
181
|
version: '0'
|
155
182
|
requirements: []
|
156
|
-
rubyforge_project:
|
157
|
-
rubygems_version: 2.5.
|
158
|
-
signing_key:
|
183
|
+
rubyforge_project:
|
184
|
+
rubygems_version: 2.5.2.3
|
185
|
+
signing_key:
|
159
186
|
specification_version: 4
|
160
|
-
summary: VirtusModel
|
187
|
+
summary: VirtusModel = Virtus + ActiveModel
|
161
188
|
test_files:
|
162
189
|
- spec/spec_helper.rb
|
163
190
|
- spec/virtus_model/base_spec.rb
|