reform 2.3.0.rc1 → 2.3.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +30 -0
- data/.rubocop_todo.yml +460 -0
- data/.travis.yml +26 -11
- data/CHANGES.md +25 -2
- data/Gemfile +6 -3
- data/ISSUE_TEMPLATE.md +1 -1
- data/README.md +2 -4
- data/Rakefile +18 -9
- data/lib/reform/contract.rb +7 -7
- data/lib/reform/contract/custom_error.rb +41 -0
- data/lib/reform/contract/validate.rb +9 -5
- 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 +10 -86
- data/lib/reform/form/dry/input_hash.rb +37 -0
- data/lib/reform/form/dry/new_api.rb +58 -0
- data/lib/reform/form/dry/old_api.rb +61 -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 -3
- data/lib/reform/version.rb +1 -1
- data/reform.gemspec +10 -9
- data/test/benchmarking.rb +10 -11
- data/test/call_new_api.rb +23 -0
- data/test/{call_test.rb → call_old_api.rb} +3 -3
- data/test/changed_test.rb +7 -7
- data/test/coercion_test.rb +50 -18
- data/test/composition_new_api.rb +186 -0
- data/test/{composition_test.rb → composition_old_api.rb} +23 -26
- data/test/contract/custom_error_test.rb +55 -0
- data/test/contract_new_api.rb +77 -0
- data/test/{contract_test.rb → contract_old_api.rb} +8 -8
- data/test/default_test.rb +1 -1
- data/test/deserialize_test.rb +8 -11
- data/test/errors_new_api.rb +225 -0
- data/test/errors_old_api.rb +230 -0
- data/test/feature_test.rb +7 -9
- data/test/fixtures/dry_error_messages.yml +5 -2
- data/test/fixtures/dry_new_api_error_messages.yml +104 -0
- data/test/form_new_api.rb +57 -0
- data/test/{form_test.rb → form_old_api.rb} +2 -2
- data/test/form_option_new_api.rb +24 -0
- data/test/{form_option_test.rb → form_option_old_api.rb} +1 -1
- data/test/from_test.rb +8 -12
- data/test/inherit_new_api.rb +105 -0
- data/test/{inherit_test.rb → inherit_old_api.rb} +10 -17
- data/test/module_new_api.rb +137 -0
- data/test/{module_test.rb → module_old_api.rb} +19 -15
- data/test/parse_option_test.rb +5 -5
- data/test/parse_pipeline_test.rb +2 -2
- data/test/populate_new_api.rb +304 -0
- data/test/{populate_test.rb → populate_old_api.rb} +28 -34
- data/test/populator_skip_test.rb +1 -2
- data/test/prepopulator_test.rb +5 -6
- data/test/read_only_test.rb +12 -1
- data/test/readable_test.rb +5 -5
- data/test/reform_new_api.rb +204 -0
- data/test/{reform_test.rb → reform_old_api.rb} +17 -23
- data/test/save_new_api.rb +101 -0
- data/test/{save_test.rb → save_old_api.rb} +10 -13
- data/test/setup_test.rb +6 -6
- data/test/{skip_if_test.rb → skip_if_new_api.rb} +20 -9
- data/test/skip_if_old_api.rb +92 -0
- data/test/skip_setter_and_getter_test.rb +2 -3
- data/test/test_helper.rb +13 -5
- data/test/validate_new_api.rb +408 -0
- data/test/{validate_test.rb → validate_old_api.rb} +43 -53
- data/test/validation/dry_validation_new_api.rb +826 -0
- data/test/validation/{dry_validation_test.rb → dry_validation_old_api.rb} +223 -116
- data/test/validation/result_test.rb +20 -22
- data/test/validation_library_provided_test.rb +3 -3
- data/test/virtual_test.rb +46 -6
- data/test/writeable_test.rb +7 -7
- metadata +101 -51
- data/test/errors_test.rb +0 -180
- data/test/readonly_test.rb +0 -14
data/.travis.yml
CHANGED
@@ -2,16 +2,31 @@ language: ruby
|
|
2
2
|
cache: bundler
|
3
3
|
bundler_args: --without benchmarks tools
|
4
4
|
rvm:
|
5
|
-
-
|
6
|
-
- 2.
|
7
|
-
- 2.
|
8
|
-
|
5
|
+
- ruby-head
|
6
|
+
- 2.5
|
7
|
+
- 2.4
|
8
|
+
env:
|
9
|
+
- "DRY_VALIDATION='~> 1.3.0'"
|
10
|
+
- "DRY_VALIDATION='~> 1.2.0'"
|
11
|
+
- "DRY_VALIDATION='~> 1.1.0'"
|
12
|
+
- "DRY_VALIDATION='~> 1.0.0'"
|
13
|
+
- "DRY_VALIDATION='~> 0.13.0'"
|
14
|
+
- "DRY_VALIDATION='~> 0.12.0'"
|
9
15
|
matrix:
|
10
16
|
fast_finish: true
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
17
|
+
allow_failures:
|
18
|
+
- rvm: ruby-head
|
19
|
+
include:
|
20
|
+
- { rvm: 2.2, env: "DRY_VALIDATION='~> 0.11.0'" }
|
21
|
+
- { rvm: 2.3, env: "DRY_VALIDATION='~> 0.12.0'" }
|
22
|
+
- { rvm: 2.3, env: "DRY_VALIDATION='~> 0.13.0'" }
|
23
|
+
|
24
|
+
|
25
|
+
# maybe move this to slack in a private channel
|
26
|
+
# notifications:
|
27
|
+
# webhooks:
|
28
|
+
# urls:
|
29
|
+
# - https://webhooks.gitter.im/e/680e86d98056f2ae2fd7
|
30
|
+
# on_success: change # options: [always|never|change] default: always
|
31
|
+
# on_failure: always # options: [always|never|change] default: always
|
32
|
+
# on_start: never # options: [always|never|change] default: always
|
data/CHANGES.md
CHANGED
@@ -17,10 +17,33 @@ You can upgrade from 2.2.0 without worries.
|
|
17
17
|
* Reform now maintains a generic `Dry::Schema` class for global schema configuration. Can be overridden via `::validation`.
|
18
18
|
* 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
19
|
* [private] `Group#call` API now is: `call(form, errors)`.
|
20
|
-
*
|
21
|
-
|
20
|
+
* Modify `Form#valid?` - simply calls `validate({})`.
|
22
21
|
* In `:if` for validation groups, you now get a hash of result objects, not just true/false.
|
22
|
+
* Allow adding a custom error AFTER validate has been already called
|
23
|
+
|
24
|
+
Compatibility with `dry-validation` with 1.x:
|
25
|
+
* [CHANGE] seems like "custom" predicate are not supported by `dry-schema` anymore or better the same result is reached using the `rule` method:
|
26
|
+
Something like this:
|
27
|
+
```ruby
|
28
|
+
validation do
|
29
|
+
def a_song?(value)
|
30
|
+
value == :really_cool_song
|
31
|
+
end
|
23
32
|
|
33
|
+
required(:songs).filled(:a_song?)
|
34
|
+
end
|
35
|
+
```
|
36
|
+
will be something like:
|
37
|
+
```ruby
|
38
|
+
validation do
|
39
|
+
required(:songs).filled
|
40
|
+
|
41
|
+
rule(:songs) do
|
42
|
+
key.failure(:a_song?) unless value == :really_cool_song
|
43
|
+
end
|
44
|
+
end
|
45
|
+
```
|
46
|
+
* [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
47
|
|
25
48
|
## 2.2.4
|
26
49
|
|
data/Gemfile
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
-
source
|
1
|
+
source "https://rubygems.org"
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
gem "minitest-line"
|
6
|
-
gem 'byebug'
|
7
5
|
# gem "disposable", path: "../disposable"
|
8
6
|
|
7
|
+
# just trying to add `dry-monads` correct version in base on dry-validation
|
8
|
+
dry_v_version = ENV.fetch('DRY_VALIDATION', '~> 0.13.0')
|
9
|
+
dry_m_version = "~> #{dry_v_version.gsub("~>", "").to_f}.0"
|
10
|
+
gem 'dry-monads', dry_m_version if dry_v_version.gsub("~>", "").to_f >= 1
|
11
|
+
gem 'dry-validation', ENV.fetch('DRY_VALIDATION', '~> 0.13.0')
|
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/README.md
CHANGED
@@ -315,16 +315,14 @@ AlbumForm.new(album: album, cd: CD.find(1))
|
|
315
315
|
|
316
316
|
Reform comes many more optional features, like hash fields, coercion, virtual fields, and so on. Check the [full documentation here](http://trailblazer.to/gems/reform).
|
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
|
|
data/Rakefile
CHANGED
@@ -1,15 +1,24 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
-
require
|
2
|
+
require "rake/testtask"
|
3
|
+
require "rubocop/rake_task"
|
3
4
|
|
4
|
-
task :
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
task default: %i[test]
|
6
|
+
|
7
|
+
TEST_WITH_OLD_AND_NEW_API = %w[
|
8
|
+
validation/dry_validation call composition contract errors inherit module reform
|
9
|
+
save skip_if populate validate form
|
10
|
+
].freeze
|
11
|
+
|
12
|
+
def dry_v_test_files
|
13
|
+
dry_v_version = ENV.fetch("DRY_VALIDATION", "~> 0.13.0")
|
14
|
+
api = dry_v_version.gsub("~>", "").to_f >= 1.0 ? "new" : "old"
|
15
|
+
TEST_WITH_OLD_AND_NEW_API.map { |file| "test/#{file}_#{api}_api.rb" }
|
9
16
|
end
|
10
17
|
|
11
|
-
Rake::TestTask.new(:
|
12
|
-
test.libs <<
|
13
|
-
test.test_files = FileList[
|
18
|
+
Rake::TestTask.new(:test) do |test|
|
19
|
+
test.libs << "test"
|
20
|
+
test.test_files = FileList["test/*_test.rb"] + FileList["test/validation/*_test.rb"] + dry_v_test_files
|
14
21
|
test.verbose = true
|
15
22
|
end
|
23
|
+
|
24
|
+
RuboCop::RakeTask.new(:rubocop)
|
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
|
@@ -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
|
|