light_form 0.0.6 → 0.0.7
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 +57 -2
- data/lib/light_form/property_methods.rb +21 -6
- data/lib/light_form/version.rb +1 -1
- data/spec/lib/form_spec.rb +59 -36
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a9dd6b626e08abeb2968d7a51d35823eb0d312b3
|
4
|
+
data.tar.gz: af5d354b4a33a0d2452aca26796a22c1f1ba83af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a01b0469a57d809f83415cadcb5e03b259a9d99ebbe077c613f61cd63c921df8f9de33704bcb405f1787ff933684fb9e5601eb14eabc68a22b09a8cf3d52ba4
|
7
|
+
data.tar.gz: e5fe1ce5c99618f33a98dc721b8adca47d8f5c50be5c0873cec7fade9588036863e30fffafa821e661759aa56d5e84df083fb207d27ac877eeecee318886df44
|
data/README.md
CHANGED
@@ -18,9 +18,64 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
$ gem install light_form
|
20
20
|
|
21
|
-
##
|
21
|
+
## How it works
|
22
|
+
Build form from specific params and custom validation:
|
22
23
|
|
23
|
-
|
24
|
+
```ruby
|
25
|
+
class Address
|
26
|
+
include ActiveModel::Model
|
27
|
+
attr_accessor :street, :post_code
|
28
|
+
end
|
29
|
+
|
30
|
+
class Child
|
31
|
+
include ActiveModel::Model
|
32
|
+
attr_accessor :name, :age
|
33
|
+
end
|
34
|
+
|
35
|
+
class PersonForm < LightForm::Form
|
36
|
+
properties :title, :first_name, :last_name
|
37
|
+
property :email, validates: { presence: true }
|
38
|
+
property :age, with: -> (v) { v.to_i }
|
39
|
+
|
40
|
+
property :address, model: Address do
|
41
|
+
properties :street, :post_code
|
42
|
+
end
|
43
|
+
|
44
|
+
property :children, collection: Child, uniq: true do
|
45
|
+
property :name, validates: { presence: true }
|
46
|
+
property :age, with: -> (v) { v.to_i }
|
47
|
+
end
|
48
|
+
|
49
|
+
property :interests, collection: true, uniq: true
|
50
|
+
end
|
51
|
+
|
52
|
+
person = PersonForm.new(
|
53
|
+
{
|
54
|
+
title: 'Mr', first_name: 'Pawel', last_name: 'Awesome', email: nil,
|
55
|
+
age: '31', address: { street: 'Best', post_code: '33333' },
|
56
|
+
children: [ {name: 'Emi', age: '2'}, {name: 'Emi', age: '2'}, {age: '2'} ],
|
57
|
+
interests: [ 'football', 'football', 'basketball', 'football' ]
|
58
|
+
}
|
59
|
+
)
|
60
|
+
|
61
|
+
person.valid? == false
|
62
|
+
|
63
|
+
person.errors.as_json == {
|
64
|
+
children: [{1=>{name: ["can't be blank"]}}],
|
65
|
+
email: ["can't be blank"]
|
66
|
+
}
|
67
|
+
|
68
|
+
person.to_h == {
|
69
|
+
title: 'Mr',
|
70
|
+
first_name: 'Pawel',
|
71
|
+
last_name: 'Awesome',
|
72
|
+
email: nil,
|
73
|
+
age: 31,
|
74
|
+
address: <AddressModel:0x007faf0ba22238 @street='Best', @post_code='33333'>,
|
75
|
+
children: [<ChildModel:0x007faf0ba21ec8 @name='Emi', @age=2>, <ChildModel:0x007faf0ba21c70 @name='', @age=2>],
|
76
|
+
interests: ['football', 'basketball']
|
77
|
+
}
|
78
|
+
```
|
24
79
|
|
25
80
|
## Contributing
|
26
81
|
|
@@ -75,18 +75,22 @@ module LightForm
|
|
75
75
|
|
76
76
|
def valid?(context = nil)
|
77
77
|
@errors = ActiveModel::Errors.new(self)
|
78
|
-
return
|
78
|
+
return _form_valid?(context) unless errors_overriden?
|
79
79
|
@_errors = @errors
|
80
80
|
stored_method = method(:errors)
|
81
81
|
errors_method = -> { @errors }
|
82
82
|
define_singleton_method(:errors) { errors_method.call }
|
83
|
-
result,
|
83
|
+
result, _store, @_errors, @errors = _form_valid?(context), @_errors, @errors, _store
|
84
84
|
define_singleton_method(:errors) { stored_method.call }
|
85
85
|
result
|
86
86
|
end
|
87
87
|
|
88
88
|
private
|
89
89
|
|
90
|
+
def _form_valid?(context)
|
91
|
+
[_check_validation, _valid_without_clear?(context)].all?
|
92
|
+
end
|
93
|
+
|
90
94
|
def _valid_without_clear?(context = nil)
|
91
95
|
current_context, self.validation_context = validation_context, context
|
92
96
|
run_validations!
|
@@ -98,20 +102,31 @@ module LightForm
|
|
98
102
|
obj.errors if obj.respond_to?(:valid?) && !obj.valid?
|
99
103
|
end
|
100
104
|
|
105
|
+
def _array_validation_errors(obj)
|
106
|
+
{}.tap do |errors_list|
|
107
|
+
obj.each_with_index do |item, idx|
|
108
|
+
next if !item.respond_to?(:valid?) || item.valid?
|
109
|
+
errors_list[idx] = item.errors.as_json
|
110
|
+
end
|
111
|
+
return if errors_list.empty?
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
101
115
|
def _check_validation
|
116
|
+
# copy errors from lash to model for forms on view
|
102
117
|
@errors = ActiveModel::Errors.new(self)
|
103
118
|
properties = _properties.delete(_properties_sources.keys)
|
104
119
|
properties.each do |prop|
|
105
120
|
public_send(prop).tap do |subject|
|
106
|
-
items = subject.is_a?(Array) ? subject
|
107
|
-
@errors.add(prop, items) if items && !items.empty?
|
121
|
+
items = subject.is_a?(Array) ? _array_validation_errors(subject) : _validation_errors(subject)
|
122
|
+
@errors.add(prop, items) if items && !items.empty?
|
108
123
|
end
|
109
124
|
end
|
125
|
+
|
110
126
|
_properties_sources.each do |prop, v|
|
111
127
|
next unless v[:params]
|
112
128
|
subject = v[:params].clone
|
113
|
-
|
114
|
-
items = subject.is_a?(Array) ? subject.map(&method(:_validation_errors)) : _validation_errors(v[:params])
|
129
|
+
items = subject.is_a?(Array) ? _array_validation_errors(subject) : _validation_errors(v[:params])
|
115
130
|
@errors.add(prop, items) if items && !items.empty?
|
116
131
|
end
|
117
132
|
@errors.empty?
|
data/lib/light_form/version.rb
CHANGED
data/spec/lib/form_spec.rb
CHANGED
@@ -6,12 +6,30 @@ describe LightForm::Form do
|
|
6
6
|
[:name, :age].map { |attr| public_send("#{attr}") }
|
7
7
|
end
|
8
8
|
|
9
|
-
def ==(
|
10
|
-
eql?(
|
9
|
+
def ==(other)
|
10
|
+
eql?(other)
|
11
11
|
end
|
12
12
|
|
13
|
-
def eql?(
|
14
|
-
|
13
|
+
def eql?(other)
|
14
|
+
other.class == self.class && other.equality_state == equality_state
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
class AddressModel
|
20
|
+
include ActiveModel::Model
|
21
|
+
attr_accessor :street, :post_code
|
22
|
+
|
23
|
+
def equality_state
|
24
|
+
[:street, :post_code].map { |attr| public_send("#{attr}") }
|
25
|
+
end
|
26
|
+
|
27
|
+
def ==(other)
|
28
|
+
eql?(other)
|
29
|
+
end
|
30
|
+
|
31
|
+
def eql?(other)
|
32
|
+
other.class == self.class && other.equality_state == equality_state
|
15
33
|
end
|
16
34
|
end
|
17
35
|
|
@@ -320,49 +338,54 @@ describe LightForm::Form do
|
|
320
338
|
end
|
321
339
|
|
322
340
|
expect(test_obj.valid?).to eq(false)
|
323
|
-
ap test_obj.errors
|
324
341
|
end
|
325
342
|
|
326
343
|
it 'to_h' do
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
344
|
+
attrs = {
|
345
|
+
title: 'Mr',
|
346
|
+
first_name: 'Pawel',
|
347
|
+
last_name: 'Awesome',
|
348
|
+
email: nil,
|
349
|
+
age: '31',
|
350
|
+
address: { street: 'Best', post_code: '33333' },
|
351
|
+
children: [{ name: 'Emi', age: '2' }, { name: 'Emi', age: '2' }, { name: '', age: '2' }],
|
352
|
+
interests: %w(football football basketball football)
|
353
|
+
}
|
334
354
|
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
355
|
+
test_obj = object_factory(real_class_name: 'PersonForm', attributes: attrs) do
|
356
|
+
properties :title, :first_name, :last_name
|
357
|
+
property :email, validates: { presence: true }
|
358
|
+
property :age, with: -> (v) { v.to_i }
|
339
359
|
|
340
|
-
|
341
|
-
|
342
|
-
|
360
|
+
property :address, model: AddressModel do
|
361
|
+
properties :street, :post_code
|
362
|
+
end
|
343
363
|
|
344
|
-
|
364
|
+
property :children, collection: ChildModel, uniq: true do
|
365
|
+
property :name, validates: { presence: true }
|
366
|
+
property :age, with: -> (v) { v.to_i }
|
345
367
|
end
|
368
|
+
|
369
|
+
property :interests, collection: true, uniq: true
|
346
370
|
end
|
347
371
|
|
348
372
|
expect(test_obj.to_h).to eq(
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
],
|
358
|
-
gh: [
|
359
|
-
ChildModel.new(age: '31', name: 'Pawel'),
|
360
|
-
ChildModel.new(age: '32', name: 'Sylwia')
|
361
|
-
],
|
362
|
-
ij: []
|
363
|
-
}
|
364
|
-
}
|
373
|
+
address: AddressModel.new(attrs[:address]),
|
374
|
+
age: 31,
|
375
|
+
children: [ChildModel.new(name: 'Emi', age: 2), ChildModel.new(name: '', age: 2)],
|
376
|
+
email: nil,
|
377
|
+
first_name: attrs[:first_name],
|
378
|
+
interests: %w(football basketball),
|
379
|
+
last_name: attrs[:last_name],
|
380
|
+
title: attrs[:title]
|
365
381
|
)
|
382
|
+
|
383
|
+
expect(test_obj.valid?).to eq(false)
|
384
|
+
expect(test_obj.errors.as_json).to eq(
|
385
|
+
children: [{1=>{name: ["can't be blank"]}}],
|
386
|
+
email: ["can't be blank"]
|
387
|
+
)
|
388
|
+
|
366
389
|
end
|
367
390
|
end
|
368
391
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: light_form
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pawel Niemczyk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-04-
|
11
|
+
date: 2015-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|