reform 2.3.0.rc1 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +5 -1
- data/.travis.yml +7 -11
- data/CHANGES.md +43 -3
- data/Gemfile +2 -5
- data/ISSUE_TEMPLATE.md +1 -1
- data/LICENSE.txt +1 -1
- data/README.md +7 -9
- data/Rakefile +6 -10
- data/lib/reform/contract.rb +7 -7
- data/lib/reform/contract/custom_error.rb +41 -0
- data/lib/reform/contract/validate.rb +10 -6
- data/lib/reform/errors.rb +27 -15
- data/lib/reform/form.rb +22 -11
- data/lib/reform/form/call.rb +1 -1
- data/lib/reform/form/composition.rb +2 -2
- data/lib/reform/form/dry.rb +22 -60
- data/lib/reform/form/dry/input_hash.rb +37 -0
- data/lib/reform/form/populator.rb +9 -11
- data/lib/reform/form/prepopulate.rb +3 -2
- data/lib/reform/form/validate.rb +19 -12
- data/lib/reform/result.rb +36 -9
- data/lib/reform/validation.rb +10 -8
- data/lib/reform/validation/groups.rb +2 -4
- data/lib/reform/version.rb +1 -1
- data/reform.gemspec +9 -9
- data/test/benchmarking.rb +10 -11
- data/test/call_test.rb +8 -8
- data/test/changed_test.rb +13 -13
- data/test/coercion_test.rb +56 -24
- data/test/composition_test.rb +49 -51
- data/test/contract/custom_error_test.rb +55 -0
- data/test/contract_test.rb +18 -18
- data/test/default_test.rb +3 -3
- data/test/deserialize_test.rb +14 -17
- data/test/docs/validation_test.rb +134 -0
- data/test/errors_test.rb +131 -86
- data/test/feature_test.rb +9 -11
- data/test/fixtures/dry_error_messages.yml +65 -52
- data/test/form_option_test.rb +3 -3
- data/test/form_test.rb +6 -6
- data/test/from_test.rb +17 -21
- data/test/inherit_test.rb +28 -35
- data/test/module_test.rb +23 -28
- data/test/parse_option_test.rb +12 -12
- data/test/parse_pipeline_test.rb +3 -3
- data/test/populate_test.rb +146 -93
- data/test/populator_skip_test.rb +3 -4
- data/test/prepopulator_test.rb +20 -21
- data/test/read_only_test.rb +12 -1
- data/test/readable_test.rb +7 -7
- data/test/reform_test.rb +38 -42
- data/test/save_test.rb +16 -19
- data/test/setup_test.rb +15 -15
- data/test/skip_if_test.rb +30 -19
- data/test/skip_setter_and_getter_test.rb +8 -9
- data/test/test_helper.rb +12 -5
- data/test/validate_test.rb +160 -140
- data/test/validation/dry_validation_test.rb +407 -236
- data/test/validation/result_test.rb +29 -31
- data/test/validation_library_provided_test.rb +3 -3
- data/test/virtual_test.rb +46 -6
- data/test/writeable_test.rb +13 -13
- metadata +32 -29
- data/test/readonly_test.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e0b6b3c1dbb48304ae8b36f5fbc12d9f7149edc61b40757017472b3eb01cf04f
|
4
|
+
data.tar.gz: 689811ffa73a062d4e598d8a36b6258571350d1ce4c5c87c85db9707313dde04
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a797c79e164c4c1791661a97163d4e89b1b2e49ae4992e1c0a59eb427d98ddfdbdae96292f455f843acacc869b5053916afa7131018843c66f4d886e6872c372
|
7
|
+
data.tar.gz: 82fe647e1ab34dcc24e85250d5876b88b84ea3a991cdfb163bf0dd616be701105ab1ca87065285bc0e32abe9f67ccdb3cda103c7f70143e49d0a8c3024baa75e
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -2,16 +2,12 @@ language: ruby
|
|
2
2
|
cache: bundler
|
3
3
|
bundler_args: --without benchmarks tools
|
4
4
|
rvm:
|
5
|
-
-
|
6
|
-
- 2.
|
7
|
-
- 2.
|
8
|
-
- 2.
|
5
|
+
- ruby-head
|
6
|
+
- 2.7
|
7
|
+
- 2.6
|
8
|
+
- 2.5
|
9
|
+
- 2.4
|
9
10
|
matrix:
|
10
11
|
fast_finish: true
|
11
|
-
|
12
|
-
|
13
|
-
urls:
|
14
|
-
- https://webhooks.gitter.im/e/680e86d98056f2ae2fd7
|
15
|
-
on_success: change # options: [always|never|change] default: always
|
16
|
-
on_failure: always # options: [always|never|change] default: always
|
17
|
-
on_start: never # options: [always|never|change] default: always
|
12
|
+
allow_failures:
|
13
|
+
- rvm: ruby-head
|
data/CHANGES.md
CHANGED
@@ -1,8 +1,25 @@
|
|
1
|
-
##
|
1
|
+
## 2.5.0
|
2
|
+
* fix memory leak with Dry validation (#525)
|
2
3
|
|
4
|
+
## 2.4.0
|
5
|
+
|
6
|
+
* [BREAKING] Dropping compatibility of dry-validation < 1.x
|
3
7
|
[* Removed `Reform::Contract` ?]
|
4
8
|
[* Move Form#deserializer to Form::deserializer]
|
5
9
|
|
10
|
+
## 2.3.3
|
11
|
+
|
12
|
+
* Rename validation option for dry-v 1+ to `contract` instead of `schema`
|
13
|
+
|
14
|
+
## 2.3.2
|
15
|
+
|
16
|
+
* Fix Validation block option :form incorrectly memoized between tests
|
17
|
+
|
18
|
+
## 2.3.1
|
19
|
+
* With dry-validation 1.5 the form is always injected. Just add option :form to access it in the schema.
|
20
|
+
* Removed global monkey patching of Dry::Schema::DSL
|
21
|
+
* Tests in ruby 2.7
|
22
|
+
|
6
23
|
## 2.3.0
|
7
24
|
|
8
25
|
You can upgrade from 2.2.0 without worries.
|
@@ -17,10 +34,33 @@ You can upgrade from 2.2.0 without worries.
|
|
17
34
|
* Reform now maintains a generic `Dry::Schema` class for global schema configuration. Can be overridden via `::validation`.
|
18
35
|
* When validating with dry-validation, we now pass a symbolized hash. We also replaced `Dry::Validation::Form` with `Schema` which won't coerce values where it shouldn't.
|
19
36
|
* [private] `Group#call` API now is: `call(form, errors)`.
|
20
|
-
*
|
21
|
-
|
37
|
+
* Modify `Form#valid?` - simply calls `validate({})`.
|
22
38
|
* In `:if` for validation groups, you now get a hash of result objects, not just true/false.
|
39
|
+
* Allow adding a custom error AFTER validate has been already called
|
40
|
+
|
41
|
+
Compatibility with `dry-validation` with 1.x:
|
42
|
+
* [CHANGE] seems like "custom" predicate are not supported by `dry-schema` anymore or better the same result is reached using the `rule` method:
|
43
|
+
Something like this:
|
44
|
+
```ruby
|
45
|
+
validation do
|
46
|
+
def a_song?(value)
|
47
|
+
value == :really_cool_song
|
48
|
+
end
|
23
49
|
|
50
|
+
required(:songs).filled(:a_song?)
|
51
|
+
end
|
52
|
+
```
|
53
|
+
will be something like:
|
54
|
+
```ruby
|
55
|
+
validation do
|
56
|
+
required(:songs).filled
|
57
|
+
|
58
|
+
rule(:songs) do
|
59
|
+
key.failure(:a_song?) unless value == :really_cool_song
|
60
|
+
end
|
61
|
+
end
|
62
|
+
```
|
63
|
+
* [BREAKING] inheriting/merging/overriding schema/rules is not supported by `dry-v` so the `inherit:` option is **NOT SUPPORTED** for now. Also extend a `schema:` option using a block is **NOT SUPPORTED** for now. Possible workaround is to use reform module to compose different validations but this won't override existing validations but just merge them
|
24
64
|
|
25
65
|
## 2.2.4
|
26
66
|
|
data/Gemfile
CHANGED
data/ISSUE_TEMPLATE.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Note: If you have a question about Reform, would like help using
|
2
2
|
Reform, want to request a feature, or do anything else other than
|
3
|
-
submit a bug report, please use the Trailblazer gitter channel.
|
3
|
+
submit a bug report, please use the [Trailblazer gitter channel](https://gitter.im/trailblazer/chat).
|
4
4
|
|
5
5
|
Note: Rails/ ActiveRecord/ ActiveModel support.
|
6
6
|
As of Reform 2.2.0 all Rails/ Active-* code was moved to the [reform-rails](https://github.com/trailblazer/reform-rails) gem.
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -10,11 +10,11 @@ _Form objects decoupled from your models._
|
|
10
10
|
|
11
11
|
Reform gives you a form object with validations and nested setup of models. It is completely framework-agnostic and doesn't care about your database.
|
12
12
|
|
13
|
-
Although reform can be used in any Ruby framework, it comes with [Rails support](#rails-integration), works with
|
13
|
+
Although reform can be used in any Ruby framework, it comes with [Rails support](#rails-integration), works with simple_form and other form gems, allows nesting forms to implement has_one and has_many relationships, can [compose a form](#compositions) from multiple objects and gives you coercion.
|
14
14
|
|
15
15
|
## Full Documentation
|
16
16
|
|
17
|
-
Reform is part of the [Trailblazer](http://trailblazer.to) framework. [Full documentation](http://trailblazer.to/
|
17
|
+
Reform is part of the [Trailblazer](http://trailblazer.to) framework. [Full documentation](http://trailblazer.to/2.1/docs/reform.html) is available on the project site.
|
18
18
|
|
19
19
|
## Reform 2.2
|
20
20
|
|
@@ -250,7 +250,7 @@ The manual saving with block is not encouraged. You should rather check the Disp
|
|
250
250
|
|
251
251
|
## Populating Forms
|
252
252
|
|
253
|
-
Very often, you need to give Reform some information how to create or find nested objects when `validate`ing. This directive is called _populator_ and [documented here](http://trailblazer.to/
|
253
|
+
Very often, you need to give Reform some information how to create or find nested objects when `validate`ing. This directive is called _populator_ and [documented here](http://trailblazer.to/2.1/docs/reform.html#reform-populators).
|
254
254
|
|
255
255
|
## Installation
|
256
256
|
|
@@ -313,18 +313,16 @@ AlbumForm.new(album: album, cd: CD.find(1))
|
|
313
313
|
|
314
314
|
## More
|
315
315
|
|
316
|
-
Reform comes many more optional features, like hash fields, coercion, virtual fields, and so on. Check the [full documentation here](http://trailblazer.to/
|
316
|
+
Reform comes many more optional features, like hash fields, coercion, virtual fields, and so on. Check the [full documentation here](http://trailblazer.to/2.1/docs/reform.html).
|
317
317
|
|
318
|
-
|
319
|
-
![](http://trailblazer.to/images/3dbuch-freigestellt.png)
|
320
|
-
</a>
|
318
|
+
[![](http://trailblazer.to/images/3dbuch-freigestellt.png)](https://leanpub.com/trailblazer)
|
321
319
|
|
322
320
|
Reform is part of the [Trailblazer project](http://trailblazer.to). Please [buy my book](https://leanpub.com/trailblazer) to support the development and learn everything about Reform - there's two chapters dedicated to Reform!
|
323
321
|
|
324
322
|
|
325
323
|
## Security And Strong_parameters
|
326
324
|
|
327
|
-
By
|
325
|
+
By explicitly defining the form layout using `::property` there is no more need for protecting from unwanted input. `strong_parameter` or `attr_accessible` become obsolete. Reform will simply ignore undefined incoming parameters.
|
328
326
|
|
329
327
|
## This is not Reform 1.x!
|
330
328
|
|
@@ -332,7 +330,7 @@ Temporary note: This is the README and API for Reform 2. On the public API, only
|
|
332
330
|
|
333
331
|
Anyway, please upgrade and _report problems_ and do not simply assume that we will magically find out what needs to get fixed. When in trouble, join us on [Gitter](https://gitter.im/trailblazer/chat).
|
334
332
|
|
335
|
-
[Full documentation for Reform](http://trailblazer.to/
|
333
|
+
[Full documentation for Reform](http://trailblazer.to/2.1/docs/reform.html) is available online, or support us and grab the [Trailblazer book](https://leanpub.com/trailblazer). There is an [Upgrading Guide](http://trailblazer.to/2.1/docs/reform.html#reform-upgrading-guide) to help you migrate through versions.
|
336
334
|
|
337
335
|
### Attributions!!!
|
338
336
|
|
data/Rakefile
CHANGED
@@ -1,15 +1,11 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
-
require
|
2
|
+
require "rake/testtask"
|
3
|
+
require "dry/types/version"
|
3
4
|
|
4
|
-
task :
|
5
|
-
Rake::TestTask.new(:test) do |test|
|
6
|
-
test.libs << 'test'
|
7
|
-
test.test_files = FileList['test/*_test.rb'] + FileList["test/validation/*_test.rb"]
|
8
|
-
test.verbose = true
|
9
|
-
end
|
5
|
+
task default: %i[test]
|
10
6
|
|
11
|
-
Rake::TestTask.new(:
|
12
|
-
test.libs <<
|
13
|
-
test.test_files = FileList[
|
7
|
+
Rake::TestTask.new(:test) do |test|
|
8
|
+
test.libs << "test"
|
9
|
+
test.test_files = FileList["test/**/*_test.rb"]
|
14
10
|
test.verbose = true
|
15
11
|
end
|
data/lib/reform/contract.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
-
require "uber/inheritable_attr"
|
2
|
-
|
3
1
|
module Reform
|
4
2
|
# Define your form structure and its validations. Instantiate it with a model,
|
5
3
|
# and then +validate+ this object graph.
|
6
4
|
class Contract < Disposable::Twin
|
5
|
+
require "reform/contract/custom_error"
|
7
6
|
require "disposable/twin/composition" # Expose.
|
8
7
|
include Expose
|
9
8
|
|
@@ -15,7 +14,7 @@ module Reform
|
|
15
14
|
Contract
|
16
15
|
end
|
17
16
|
|
18
|
-
def self.property(name, options={}, &block)
|
17
|
+
def self.property(name, options = {}, &block)
|
19
18
|
if twin = options.delete(:form)
|
20
19
|
options[:twin] = twin
|
21
20
|
end
|
@@ -33,7 +32,7 @@ module Reform
|
|
33
32
|
end
|
34
33
|
|
35
34
|
require "reform/result"
|
36
|
-
require
|
35
|
+
require "reform/contract/validate"
|
37
36
|
include Reform::Contract::Validate
|
38
37
|
|
39
38
|
require "reform/validation"
|
@@ -43,14 +42,16 @@ module Reform
|
|
43
42
|
require "disposable/twin/sync"
|
44
43
|
include Disposable::Twin::Sync
|
45
44
|
|
46
|
-
|
45
|
+
private
|
46
|
+
|
47
47
|
# DISCUSS: separate file?
|
48
48
|
module Readonly
|
49
49
|
def readonly?(name)
|
50
50
|
options_for(name)[:writeable] == false
|
51
51
|
end
|
52
|
+
|
52
53
|
def options_for(name)
|
53
|
-
|
54
|
+
self.class.options_for(name)
|
54
55
|
end
|
55
56
|
end
|
56
57
|
|
@@ -59,7 +60,6 @@ module Reform
|
|
59
60
|
end
|
60
61
|
include Readonly
|
61
62
|
|
62
|
-
|
63
63
|
def self.clone # TODO: test. THIS IS ONLY FOR Trailblazer when contract gets cloned in suboperation.
|
64
64
|
Class.new(self)
|
65
65
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Reform
|
2
|
+
class Contract < Disposable::Twin
|
3
|
+
# a "fake" Dry schema object to add into the @results array
|
4
|
+
# super ugly hack required for 2.3.x version since we are creating
|
5
|
+
# a new Reform::Errors instance every time we call form.errors
|
6
|
+
class CustomError
|
7
|
+
def initialize(key, error_text, results)
|
8
|
+
@key = key
|
9
|
+
@error_text = error_text
|
10
|
+
@errors = {key => Array(error_text)}
|
11
|
+
@messages = @errors
|
12
|
+
@hint = {}
|
13
|
+
@results = results
|
14
|
+
|
15
|
+
merge!
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader :messages, :hint
|
19
|
+
|
20
|
+
def success?
|
21
|
+
false
|
22
|
+
end
|
23
|
+
|
24
|
+
def failure?
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
28
|
+
# dry 1.x errors method has 1 kwargs argument
|
29
|
+
def errors(**_args)
|
30
|
+
@errors
|
31
|
+
end
|
32
|
+
|
33
|
+
def merge!
|
34
|
+
# to_h required for dry_v 1.x since the errors are Dry object instead of an hash
|
35
|
+
@results.map(&:errors)
|
36
|
+
.detect { |hash| hash.to_h.key?(@key) }
|
37
|
+
.tap { |hash| hash.nil? ? @results << self : hash.to_h[@key] |= Array(@error_text) }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -11,7 +11,7 @@ class Reform::Contract < Disposable::Twin
|
|
11
11
|
validate!(nil).success?
|
12
12
|
end
|
13
13
|
|
14
|
-
# The #errors method will be removed in Reform
|
14
|
+
# The #errors method will be removed in Reform 3.0 core.
|
15
15
|
def errors(*args)
|
16
16
|
Result::Errors.new(@result, self)
|
17
17
|
end
|
@@ -22,7 +22,11 @@ class Reform::Contract < Disposable::Twin
|
|
22
22
|
@result
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
25
|
+
def custom_errors
|
26
|
+
@result.to_results.select { |result| result.is_a? Reform::Contract::CustomError }
|
27
|
+
end
|
28
|
+
|
29
|
+
def validate!(name, pointers = [])
|
26
30
|
# run local validations. this could be nested schemas, too.
|
27
31
|
local_errors_by_group = Reform::Validation::Groups::Validate.(self.class.validation_groups, self).compact # TODO: discss compact
|
28
32
|
|
@@ -33,10 +37,10 @@ class Reform::Contract < Disposable::Twin
|
|
33
37
|
nested_errors = validate_nested!(pointers_for_nested)
|
34
38
|
|
35
39
|
# Result: unified interface #success?, #messages, etc.
|
36
|
-
@result = Result.new(local_errors_by_group + pointers, nested_errors)
|
40
|
+
@result = Result.new(custom_errors + local_errors_by_group + pointers, nested_errors)
|
37
41
|
end
|
38
42
|
|
39
|
-
|
43
|
+
private
|
40
44
|
|
41
45
|
# Recursively call validate! on nested forms.
|
42
46
|
# A pointer keeps an entire result object (e.g. Dry result) and
|
@@ -46,11 +50,11 @@ class Reform::Contract < Disposable::Twin
|
|
46
50
|
|
47
51
|
schema.each(twin: true) do |dfn|
|
48
52
|
# on collections, this calls validate! on each item form.
|
49
|
-
Disposable::Twin::PropertyProcessor.new(dfn, self).()
|
53
|
+
Disposable::Twin::PropertyProcessor.new(dfn, self).() do |form, i|
|
50
54
|
nested_pointers = pointers.collect { |pointer| pointer.advance(dfn[:name].to_sym, i) }.compact # pointer contains fragment for us, so go deeper
|
51
55
|
|
52
56
|
arr << form.validate!(dfn[:name], nested_pointers)
|
53
|
-
|
57
|
+
end
|
54
58
|
end
|
55
59
|
|
56
60
|
arr
|
data/lib/reform/errors.rb
CHANGED
@@ -12,15 +12,14 @@ class Reform::Contract::Result::Errors
|
|
12
12
|
# PROTOTYPING. THIS WILL GO TO A SEPARATE GEM IN REFORM 2.4/3.0.
|
13
13
|
DottedErrors = ->(form, prefix, hash) do
|
14
14
|
result = form.to_result
|
15
|
-
result.messages.collect { |k,v| hash[
|
15
|
+
result.messages.collect { |k, v| hash[[*prefix, k].join(".").to_sym] = v }
|
16
16
|
|
17
|
-
form.schema.each(twin: true)
|
17
|
+
form.schema.each(twin: true) do |dfn|
|
18
18
|
Disposable::Twin::PropertyProcessor.new(dfn, form).() do |frm, i|
|
19
|
-
|
20
|
-
DottedErrors.(
|
21
|
-
DottedErrors.(form.send(dfn[:name]), [*prefix, dfn[:name]], hash)
|
19
|
+
form_obj = i ? form.send(dfn[:name])[i] : form.send(dfn[:name])
|
20
|
+
DottedErrors.(form_obj, [*prefix, dfn[:name]], hash)
|
22
21
|
end
|
23
|
-
|
22
|
+
end
|
24
23
|
end
|
25
24
|
|
26
25
|
def messages(*args)
|
@@ -28,22 +27,35 @@ class Reform::Contract::Result::Errors
|
|
28
27
|
end
|
29
28
|
|
30
29
|
def full_messages
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
30
|
+
@dotted_errors.collect { |path, errors|
|
31
|
+
human_field = path.to_s.gsub(/([\.\_])+/, " ").gsub(/(\b\w)+/) { |s| s.capitalize }
|
32
|
+
errors.collect { |message| "#{human_field} #{message}" }
|
33
|
+
}.flatten
|
35
34
|
end
|
36
35
|
|
37
36
|
def [](name)
|
38
|
-
@dotted_errors[name]
|
37
|
+
@dotted_errors[name] || []
|
39
38
|
end
|
40
39
|
|
41
40
|
def size
|
42
41
|
messages.size
|
43
42
|
end
|
43
|
+
|
44
|
+
# needed for rails form helpers
|
45
|
+
def empty?
|
46
|
+
messages.empty?
|
47
|
+
end
|
48
|
+
|
49
|
+
# we need to delegate adding error to result because every time we call form.errors
|
50
|
+
# a new instance of this class is created so we need to update the @results array
|
51
|
+
# to be able to add custom errors here.
|
52
|
+
# This method will actually work only AFTER a validate call has been made
|
53
|
+
def add(key, error_test)
|
54
|
+
@result.add_error(key, error_test)
|
55
|
+
end
|
44
56
|
end
|
45
57
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
58
|
+
# Ensure that we can return Active Record compliant full messages when using dry
|
59
|
+
# we only want unique messages in our array
|
60
|
+
#
|
61
|
+
# @full_errors.add()
|
data/lib/reform/form.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module Reform
|
2
2
|
class Form < Contract
|
3
|
+
class InvalidOptionsCombinationError < StandardError; end
|
4
|
+
|
3
5
|
def self.default_nested_class
|
4
6
|
Form
|
5
7
|
end
|
@@ -15,23 +17,32 @@ module Reform
|
|
15
17
|
|
16
18
|
module Property
|
17
19
|
# Add macro logic, e.g. for :populator.
|
18
|
-
|
20
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
21
|
+
def property(name, options = {}, &block)
|
22
|
+
if (options.keys & %i[skip_if populator]).size == 2
|
23
|
+
raise InvalidOptionsCombinationError.new(
|
24
|
+
"[Reform] #{self}:property:#{name} Do not use skip_if and populator together, use populator with skip! instead"
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
19
28
|
# if composition and inherited we also need this setting
|
20
29
|
# to correctly inherit modules
|
21
|
-
if options.key?(:on) && options.key?(:inherit)
|
22
|
-
options[:_inherited] = options[:inherit]
|
23
|
-
end
|
30
|
+
options[:_inherited] = options[:inherit] if options.key?(:on) && options.key?(:inherit)
|
24
31
|
|
25
32
|
if options.key?(:parse)
|
26
33
|
options[:deserializer] ||= {}
|
27
34
|
options[:deserializer][:writeable] = options.delete(:parse)
|
28
35
|
end
|
29
36
|
|
30
|
-
if options.key?(:writable)
|
31
|
-
|
37
|
+
options[:writeable] ||= options.delete(:writable) if options.key?(:writable)
|
38
|
+
|
39
|
+
# for virtual collection we need at least to have the collection equal to [] to
|
40
|
+
# avoid issue when the populator
|
41
|
+
if (options.keys & %i[collection virtual]).size == 2
|
42
|
+
options = { default: [] }.merge(options)
|
32
43
|
end
|
33
44
|
|
34
|
-
definition = super #
|
45
|
+
definition = super # letdisposable and declarative gems sort out inheriting of properties, and so on.
|
35
46
|
definition.merge!(deserializer: {}) unless definition[:deserializer] # always keep :deserializer per property.
|
36
47
|
|
37
48
|
deserializer_options = definition[:deserializer]
|
@@ -48,7 +59,7 @@ module Reform
|
|
48
59
|
external_populator = Populator::External.new
|
49
60
|
|
50
61
|
# always compute a parse_pipeline for each property of the deserializer and inject it via :parse_pipeline.
|
51
|
-
# first,
|
62
|
+
# first, letrepresentable compute the pipeline functions by invoking #parse_functions.
|
52
63
|
if definition[:nested]
|
53
64
|
parse_pipeline = ->(input, opts) do
|
54
65
|
functions = opts[:binding].send(:parse_functions)
|
@@ -65,7 +76,7 @@ module Reform
|
|
65
76
|
pipeline = Representable::Pipeline[*functions] # Pipeline[StopOnExcluded, AssignName, ReadFragment, StopOnNotFound, OverwriteOnNil, Collect[#<Representable::Function::CreateObject:0xa6148ec>, #<Representable::Function::Decorate:0xa6148b0>, Deserialize], Set]
|
66
77
|
|
67
78
|
# FIXME: this won't work with property :name, inherit: true (where there is a populator set already).
|
68
|
-
pipeline = Representable::Pipeline::Insert.(pipeline, external_populator,
|
79
|
+
pipeline = Representable::Pipeline::Insert.(pipeline, external_populator, replace: Representable::SetValue) if definition[:populator] # FIXME: only diff to options without :populator
|
69
80
|
pipeline
|
70
81
|
end
|
71
82
|
end
|
@@ -77,12 +88,12 @@ module Reform
|
|
77
88
|
deserializer_options.merge!(skip_parse: proc) # TODO: same with skip_parse ==> External
|
78
89
|
end
|
79
90
|
|
80
|
-
|
81
91
|
# per default, everything should be writeable for the deserializer (we're only writing on the form). however, allow turning it off.
|
82
|
-
deserializer_options.merge!(writeable: true) unless deserializer_options.
|
92
|
+
deserializer_options.merge!(writeable: true) unless deserializer_options.key?(:writeable)
|
83
93
|
|
84
94
|
definition
|
85
95
|
end
|
96
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
86
97
|
end
|
87
98
|
extend Property
|
88
99
|
|