virtus_model 0.2.5
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 +7 -0
- data/lib/virtus_model/base.rb +165 -0
- data/lib/virtus_model/version.rb +3 -0
- data/lib/virtus_model.rb +2 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/virtus_model/base_spec.rb +355 -0
- metadata +149 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f21f80530d6cc87de3ae040817f78c8c83b4567f
|
4
|
+
data.tar.gz: 572466a814d7c485b6bd89aaed1614e29b837b4a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 75489e6017e171d19a196a82f228713682728331c2a58ca0e6d1da4a33cebeb590128053b90a21afe4482b7be6b256f05b5782667f1dfb22335eae7aff39618d
|
7
|
+
data.tar.gz: c39b394204e97a0f26b49693cea7addd5e34fedb7366a5626e9a25567a46333441e13d677d02018c235ddda0ef011914d619a193b7f50cb754ab131136d19f6c
|
@@ -0,0 +1,165 @@
|
|
1
|
+
require 'virtus'
|
2
|
+
require 'active_model'
|
3
|
+
|
4
|
+
module VirtusModel
|
5
|
+
class Base
|
6
|
+
include ActiveModel::Conversion
|
7
|
+
include ActiveModel::Validations
|
8
|
+
include Virtus.model
|
9
|
+
|
10
|
+
set_callback :validate, :validate_associations
|
11
|
+
|
12
|
+
# Get an array of attribute names.
|
13
|
+
def self.attributes
|
14
|
+
attribute_set.map(&:name)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Is there an attribute with the provided name?
|
18
|
+
def self.attribute?(name)
|
19
|
+
attributes.include?(name)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Is there an association with the provided name and type (optional)?
|
23
|
+
def self.association?(name, *types)
|
24
|
+
associations(*types).include?(name)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Get an array of association names by type (optional).
|
28
|
+
def self.associations(*types)
|
29
|
+
classes = {
|
30
|
+
one: Virtus::Attribute::EmbeddedValue,
|
31
|
+
many: Virtus::Attribute::Collection
|
32
|
+
}.select do |type, _|
|
33
|
+
types.empty? || types.include?(type)
|
34
|
+
end
|
35
|
+
|
36
|
+
attribute_set.select do |field|
|
37
|
+
classes.any? { |_, cls| field.class <= cls }
|
38
|
+
end.map(&:name)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Initialize attributes using the provided hash or object.
|
42
|
+
def initialize(model = nil)
|
43
|
+
super(compact_hash(extract_attributes(model)))
|
44
|
+
end
|
45
|
+
|
46
|
+
# Recursively update attributes and return a self-reference.
|
47
|
+
def assign_attributes(model)
|
48
|
+
self.attributes = extract_attributes(model)
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
52
|
+
# Update attributes and validate.
|
53
|
+
def update(model = nil, options = {})
|
54
|
+
assign_attributes(model)
|
55
|
+
validate(options)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Two models are equal if their attributes are equal.
|
59
|
+
def ==(other)
|
60
|
+
if other.is_a?(VirtusModel::Base)
|
61
|
+
self.attributes == other.attributes
|
62
|
+
else
|
63
|
+
self.attributes == other
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Recursively convert all attributes to hash pairs.
|
68
|
+
def export(options = nil)
|
69
|
+
self.class.attributes.reduce({}) do |result, name|
|
70
|
+
value = attributes[name]
|
71
|
+
if self.class.association?(name, :many)
|
72
|
+
result[name] = export_values(value, options)
|
73
|
+
elsif self.class.association?(name, :one)
|
74
|
+
result[name] = export_value(value, options)
|
75
|
+
else
|
76
|
+
result[name] = value
|
77
|
+
end
|
78
|
+
result
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Alias of #export.
|
83
|
+
def to_hash(options = nil)
|
84
|
+
export(options)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Alias of #to_hash.
|
88
|
+
def to_h(options = nil)
|
89
|
+
to_hash(options)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Alias of #export.
|
93
|
+
def as_json(options = nil)
|
94
|
+
export(options)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Convert the #as_json result to JSON.
|
98
|
+
def to_json(options = nil)
|
99
|
+
as_json(options).to_json
|
100
|
+
end
|
101
|
+
|
102
|
+
protected
|
103
|
+
|
104
|
+
# Extract model attributes into a hash.
|
105
|
+
def extract_attributes(model)
|
106
|
+
self.class.attributes.reduce({}) do |result, name|
|
107
|
+
if model.respond_to?(name)
|
108
|
+
result[name] = model.public_send(name)
|
109
|
+
elsif model.respond_to?(:[])
|
110
|
+
result[name] = model[name]
|
111
|
+
end
|
112
|
+
result
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Validate all associations by type and import resulting errors.
|
117
|
+
def validate_associations
|
118
|
+
validate_associations_one
|
119
|
+
validate_associations_many
|
120
|
+
end
|
121
|
+
|
122
|
+
# Validate "one" associations and import errors.
|
123
|
+
def validate_associations_one
|
124
|
+
self.class.associations(:one).each do |name|
|
125
|
+
import_errors(name, attributes[name])
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Validate "many" associations and import errors.
|
130
|
+
def validate_associations_many
|
131
|
+
self.class.associations(:many).each do |name|
|
132
|
+
values = attributes[name] || []
|
133
|
+
values.each.with_index do |value, index|
|
134
|
+
import_errors("#{name}[#{index}]", value)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# Merge associated errors using the current validation context.
|
140
|
+
def import_errors(name, model)
|
141
|
+
return unless model.respond_to?(:validate)
|
142
|
+
return if model.validate(validation_context)
|
143
|
+
model.errors.each do |field, error|
|
144
|
+
errors.add("#{name}[#{field}]", error)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# Export each value with the provided options.
|
149
|
+
def export_values(values, options = nil)
|
150
|
+
return if values.nil?
|
151
|
+
values.map { |v| export_value(v, options) }
|
152
|
+
end
|
153
|
+
|
154
|
+
# Export the value with the provided options.
|
155
|
+
def export_value(value, options = nil)
|
156
|
+
return if value.nil?
|
157
|
+
value.respond_to?(:export) ? value.export(options) : value
|
158
|
+
end
|
159
|
+
|
160
|
+
# Omit keys with nil values.
|
161
|
+
def compact_hash(hash)
|
162
|
+
hash.select { |_, value| !value.nil? }
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
data/lib/virtus_model.rb
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
Bundler.setup
|
6
|
+
|
7
|
+
require 'virtus_model'
|
8
|
+
require 'shoulda/matchers'
|
9
|
+
require 'active_support/core_ext/object/try'
|
10
|
+
|
11
|
+
Shoulda::Matchers.configure do |config|
|
12
|
+
config.integrate do |with|
|
13
|
+
with.test_framework :rspec
|
14
|
+
with.library :active_model
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,355 @@
|
|
1
|
+
describe VirtusModel::Base do
|
2
|
+
class SimpleModel < VirtusModel::Base
|
3
|
+
attribute :name, String
|
4
|
+
validates :name, presence: true
|
5
|
+
end
|
6
|
+
|
7
|
+
let(:simple_model) { SimpleModel.new(simple_model_attributes) }
|
8
|
+
let(:simple_model_attributes) { { name: 'test' } }
|
9
|
+
|
10
|
+
describe SimpleModel, type: :model do
|
11
|
+
it { is_expected.to validate_presence_of(:name) }
|
12
|
+
end
|
13
|
+
|
14
|
+
class ComplexModel < VirtusModel::Base
|
15
|
+
attribute :model, SimpleModel
|
16
|
+
attribute :models, Array[SimpleModel]
|
17
|
+
validates :model, presence: true
|
18
|
+
validates :models, presence: true
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:complex_model) { ComplexModel.new(complex_model_attributes) }
|
22
|
+
let(:complex_model_attributes) do
|
23
|
+
{
|
24
|
+
model: simple_model_attributes,
|
25
|
+
models: [simple_model_attributes]
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
describe ComplexModel, type: :model do
|
30
|
+
it { is_expected.to validate_presence_of(:model) }
|
31
|
+
it { is_expected.to validate_presence_of(:models) }
|
32
|
+
end
|
33
|
+
|
34
|
+
class InheritedModel < ComplexModel
|
35
|
+
attribute :name, String
|
36
|
+
end
|
37
|
+
|
38
|
+
describe InheritedModel, type: :model do
|
39
|
+
it { is_expected.to validate_presence_of(:model) }
|
40
|
+
it { is_expected.to validate_presence_of(:models) }
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '.attribute?' do
|
44
|
+
context SimpleModel do
|
45
|
+
subject { SimpleModel }
|
46
|
+
|
47
|
+
it { expect(subject.attribute?(:name)).to be(true) }
|
48
|
+
it { expect(subject.attribute?(:other)).to be(false) }
|
49
|
+
end
|
50
|
+
|
51
|
+
context ComplexModel do
|
52
|
+
subject { ComplexModel }
|
53
|
+
|
54
|
+
it { expect(subject.attribute?(:model)).to be(true) }
|
55
|
+
it { expect(subject.attribute?(:models)).to be(true) }
|
56
|
+
it { expect(subject.attribute?(:other)).to be(false) }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '.association?' do
|
61
|
+
context SimpleModel do
|
62
|
+
subject { SimpleModel }
|
63
|
+
|
64
|
+
it { expect(subject.association?(:name)).to be(false) }
|
65
|
+
it { expect(subject.association?(:other)).to be(false) }
|
66
|
+
end
|
67
|
+
|
68
|
+
context ComplexModel do
|
69
|
+
subject { ComplexModel }
|
70
|
+
|
71
|
+
it { expect(subject.association?(:model)).to be(true) }
|
72
|
+
it { expect(subject.association?(:models)).to be(true) }
|
73
|
+
it { expect(subject.association?(:other)).to be(false) }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe '.associations' do
|
78
|
+
context SimpleModel do
|
79
|
+
subject { SimpleModel }
|
80
|
+
|
81
|
+
it { expect(subject.associations).to eq([]) }
|
82
|
+
end
|
83
|
+
|
84
|
+
context ComplexModel do
|
85
|
+
subject { ComplexModel }
|
86
|
+
|
87
|
+
it { expect(subject.associations).to eq([:model, :models]) }
|
88
|
+
it { expect(subject.associations(:one)).to eq([:model]) }
|
89
|
+
it { expect(subject.associations(:many)).to eq([:models]) }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe '#initialize' do
|
94
|
+
context SimpleModel do
|
95
|
+
subject { SimpleModel.new(attributes) }
|
96
|
+
|
97
|
+
context 'attributes are blank' do
|
98
|
+
let(:attributes) { nil }
|
99
|
+
it { expect(subject.attributes).to eq(name: nil) }
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'attributes are present' do
|
103
|
+
let(:attributes) { { name: 'test', other: 'test' } }
|
104
|
+
it { expect(subject.attributes).to eq(name: 'test') }
|
105
|
+
it { expect(subject.attributes).not_to eq(other: 'test') }
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context ComplexModel do
|
110
|
+
subject { ComplexModel.new(attributes) }
|
111
|
+
|
112
|
+
context 'attributes are blank' do
|
113
|
+
let(:attributes) { nil }
|
114
|
+
it { expect(subject.attributes).to eq(model: nil, models: []) }
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'attributes are present' do
|
118
|
+
let(:attributes) { { model: model, models: [model], other: 'test' } }
|
119
|
+
let(:model) { { name: 'test' } }
|
120
|
+
it { expect(subject.export[:model]).to eq(model) }
|
121
|
+
it { expect(subject.export[:models]).to eq([model]) }
|
122
|
+
it { expect(subject.attributes).not_to eq(other: 'test') }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe '#assign_attributes' do
|
128
|
+
context SimpleModel do
|
129
|
+
subject { SimpleModel.new.assign_attributes(attributes) }
|
130
|
+
|
131
|
+
context 'hash' do
|
132
|
+
let(:attributes) { { name: 'test', other: 'test' } }
|
133
|
+
it { expect(subject.attributes).to include(name: 'test') }
|
134
|
+
it { expect(subject.attributes).not_to include(other: 'test') }
|
135
|
+
end
|
136
|
+
|
137
|
+
context 'object' do
|
138
|
+
let(:attributes) { simple_model }
|
139
|
+
it { expect(subject == simple_model).to be(true) }
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context ComplexModel do
|
144
|
+
subject { ComplexModel.new.assign_attributes(attributes) }
|
145
|
+
|
146
|
+
context 'hash' do
|
147
|
+
let(:attributes) { { model: model, models: [model], other: 'test' } }
|
148
|
+
let(:model) { { name: 'test', other: 'test' } }
|
149
|
+
it { expect(subject.attributes[:model]).to eq(SimpleModel.new(model)) }
|
150
|
+
it { expect(subject.attributes[:models]).to eq([SimpleModel.new(model)]) }
|
151
|
+
it { expect(subject.attributes).not_to include(other: 'test') }
|
152
|
+
end
|
153
|
+
|
154
|
+
context 'object' do
|
155
|
+
let(:attributes) { complex_model }
|
156
|
+
it { expect(subject == complex_model).to be(true) }
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe '#update' do
|
162
|
+
let!(:valid) { subject.update(attributes) }
|
163
|
+
|
164
|
+
context SimpleModel do
|
165
|
+
subject { SimpleModel.new }
|
166
|
+
|
167
|
+
context 'attributes are blank' do
|
168
|
+
let(:attributes) { nil }
|
169
|
+
it { expect(subject.export).to eq(name: nil) }
|
170
|
+
it { expect(valid).to be(false) }
|
171
|
+
end
|
172
|
+
|
173
|
+
context 'attributes are invalid' do
|
174
|
+
let(:attributes) { { name: '' } }
|
175
|
+
it { expect(subject.export).to eq(name: '') }
|
176
|
+
it { expect(valid).to be(false) }
|
177
|
+
end
|
178
|
+
|
179
|
+
context 'attributes are valid' do
|
180
|
+
let(:attributes) { simple_model_attributes }
|
181
|
+
it { expect(subject.export).to eq(name: 'test') }
|
182
|
+
it { expect(valid).to be(true) }
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
context ComplexModel do
|
187
|
+
subject { ComplexModel.new }
|
188
|
+
|
189
|
+
context 'attributes are blank' do
|
190
|
+
let(:attributes) { nil }
|
191
|
+
it { expect(subject.export).to eq(model: nil, models: []) }
|
192
|
+
it { expect(valid).to be(false) }
|
193
|
+
end
|
194
|
+
|
195
|
+
context 'attributes are invalid' do
|
196
|
+
let(:attributes) { { model: {} } }
|
197
|
+
it { expect(subject.export[:model]).to include(name: nil) }
|
198
|
+
it { expect(valid).to be(false) }
|
199
|
+
end
|
200
|
+
|
201
|
+
context 'attributes are valid' do
|
202
|
+
let(:attributes) { complex_model_attributes }
|
203
|
+
it { expect(subject.export[:model]).to include(name: 'test') }
|
204
|
+
it { expect(valid).to be(true) }
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
describe '#==' do
|
210
|
+
context SimpleModel do
|
211
|
+
subject { simple_model }
|
212
|
+
|
213
|
+
context 'equal hash' do
|
214
|
+
let(:other) { subject.dup.export }
|
215
|
+
it { expect(subject == other).to be(true) }
|
216
|
+
end
|
217
|
+
|
218
|
+
context 'equal object' do
|
219
|
+
let(:other) { subject.dup }
|
220
|
+
it { expect(subject == other).to be(true) }
|
221
|
+
end
|
222
|
+
|
223
|
+
context 'unequal hash' do
|
224
|
+
let(:other) { subject.dup.export.merge(name: 'test2') }
|
225
|
+
it { expect(subject == other).to be(false) }
|
226
|
+
end
|
227
|
+
|
228
|
+
context 'unequal object' do
|
229
|
+
let(:other) { subject.dup.assign_attributes(name: 'test2') }
|
230
|
+
it { expect(subject == other).to be(false) }
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
context ComplexModel do
|
235
|
+
subject { complex_model }
|
236
|
+
|
237
|
+
context 'equal hash' do
|
238
|
+
let(:other) { subject.dup.export }
|
239
|
+
it { expect(subject == other).to be(true) }
|
240
|
+
end
|
241
|
+
|
242
|
+
context 'equal object' do
|
243
|
+
let(:other) { subject.dup }
|
244
|
+
it { expect(subject == other).to be(true) }
|
245
|
+
end
|
246
|
+
|
247
|
+
context 'unequal hash' do
|
248
|
+
let(:other) { subject.dup.export.merge(models: { name: 'test2' }) }
|
249
|
+
it { expect(subject == other).to be(false) }
|
250
|
+
end
|
251
|
+
|
252
|
+
context 'unequal object' do
|
253
|
+
let(:other) { subject.dup.assign_attributes(models: [{ name: 'test2' }]) }
|
254
|
+
it { expect(subject == other).to be(false) }
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
describe '#export' do
|
260
|
+
context SimpleModel do
|
261
|
+
subject { simple_model }
|
262
|
+
|
263
|
+
it { expect(subject.export).to eq(simple_model_attributes) }
|
264
|
+
end
|
265
|
+
|
266
|
+
context ComplexModel do
|
267
|
+
subject { complex_model }
|
268
|
+
|
269
|
+
it { expect(subject.export).to eq(complex_model_attributes) }
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
describe '#to_hash' do
|
274
|
+
context SimpleModel do
|
275
|
+
subject { simple_model }
|
276
|
+
|
277
|
+
it { expect(subject.to_hash).to eq(subject.export) }
|
278
|
+
it { expect(subject.to_h).to eq(subject.to_hash) }
|
279
|
+
it { expect(subject.as_json).to eq(subject.to_hash) }
|
280
|
+
end
|
281
|
+
|
282
|
+
context ComplexModel do
|
283
|
+
subject { complex_model }
|
284
|
+
|
285
|
+
it { expect(subject.to_hash).to eq(subject.export) }
|
286
|
+
it { expect(subject.to_h).to eq(subject.to_hash) }
|
287
|
+
it { expect(subject.as_json).to eq(subject.to_hash) }
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
describe '#to_json' do
|
292
|
+
context SimpleModel do
|
293
|
+
subject { simple_model }
|
294
|
+
|
295
|
+
it { expect(subject.to_json).to eq(subject.export.to_json) }
|
296
|
+
end
|
297
|
+
|
298
|
+
context ComplexModel do
|
299
|
+
subject { complex_model }
|
300
|
+
|
301
|
+
it { expect(subject.to_json).to eq(subject.export.to_json) }
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
describe '#validate' do
|
306
|
+
before { subject.validate }
|
307
|
+
|
308
|
+
context SimpleModel do
|
309
|
+
context 'valid' do
|
310
|
+
subject { simple_model }
|
311
|
+
|
312
|
+
it { expect(subject.valid?).to be(true) }
|
313
|
+
it { expect(subject.errors).to be_blank }
|
314
|
+
end
|
315
|
+
|
316
|
+
context 'invalid' do
|
317
|
+
subject { simple_model.assign_attributes(name: '') }
|
318
|
+
|
319
|
+
it { expect(subject.valid?).to be(false) }
|
320
|
+
it { expect(subject.errors.messages).to include(name: ["can't be blank"]) }
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
context ComplexModel do
|
325
|
+
context 'valid' do
|
326
|
+
subject { complex_model }
|
327
|
+
|
328
|
+
it { expect(subject.valid?).to be(true) }
|
329
|
+
it { expect(subject.errors).to be_blank }
|
330
|
+
end
|
331
|
+
|
332
|
+
context 'invalid' do
|
333
|
+
subject { complex_model.assign_attributes(model: {}, models: [{}]) }
|
334
|
+
|
335
|
+
it { expect(subject.valid?).to be(false) }
|
336
|
+
it { expect(subject.errors.messages).to include(:"model[name]" => ["can't be blank"]) }
|
337
|
+
it { expect(subject.errors.messages).to include(:"models[0][name]" => ["can't be blank"]) }
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
describe '#to_json' do
|
343
|
+
context SimpleModel do
|
344
|
+
subject { simple_model }
|
345
|
+
|
346
|
+
it { expect(subject.to_json).to eq(subject.export.to_json) }
|
347
|
+
end
|
348
|
+
|
349
|
+
context ComplexModel do
|
350
|
+
subject { complex_model }
|
351
|
+
|
352
|
+
it { expect(subject.to_json).to eq(subject.export.to_json) }
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|
metadata
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: virtus_model
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Derek Schaefer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-04-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: virtus
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activemodel
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '11.1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '11.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rdoc
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '4.2'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '4.2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.4'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.4'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: shoulda-matchers
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.1'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.1'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.11'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.11'
|
111
|
+
description: VirtusModel
|
112
|
+
email:
|
113
|
+
- derek.schaefer@gmail.com
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- lib/virtus_model.rb
|
119
|
+
- lib/virtus_model/base.rb
|
120
|
+
- lib/virtus_model/version.rb
|
121
|
+
- spec/spec_helper.rb
|
122
|
+
- spec/virtus_model/base_spec.rb
|
123
|
+
homepage: https://github.com/derek-schaefer/virtus_model
|
124
|
+
licenses:
|
125
|
+
- MIT
|
126
|
+
metadata: {}
|
127
|
+
post_install_message:
|
128
|
+
rdoc_options: []
|
129
|
+
require_paths:
|
130
|
+
- lib
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: 2.0.0
|
136
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
requirements: []
|
142
|
+
rubyforge_project:
|
143
|
+
rubygems_version: 2.5.1
|
144
|
+
signing_key:
|
145
|
+
specification_version: 4
|
146
|
+
summary: VirtusModel
|
147
|
+
test_files:
|
148
|
+
- spec/spec_helper.rb
|
149
|
+
- spec/virtus_model/base_spec.rb
|