reform 2.2.4 → 2.3.3
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 +5 -5
- data/.gitignore +5 -1
- data/.travis.yml +11 -6
- data/Appraisals +8 -0
- data/CHANGES.md +57 -4
- data/CONTRIBUTING.md +31 -0
- data/Gemfile +2 -16
- data/ISSUE_TEMPLATE.md +25 -0
- data/LICENSE.txt +1 -1
- data/README.md +5 -7
- data/Rakefile +16 -9
- data/gemfiles/0.13.0.gemfile +8 -0
- data/gemfiles/1.5.0.gemfile +9 -0
- data/lib/reform.rb +1 -0
- data/lib/reform/contract.rb +7 -17
- data/lib/reform/contract/custom_error.rb +41 -0
- data/lib/reform/contract/validate.rb +53 -23
- data/lib/reform/errors.rb +61 -0
- data/lib/reform/form.rb +36 -10
- data/lib/reform/form/call.rb +1 -1
- data/lib/reform/form/composition.rb +2 -2
- data/lib/reform/form/dry.rb +10 -58
- data/lib/reform/form/dry/input_hash.rb +37 -0
- data/lib/reform/form/dry/new_api.rb +45 -0
- data/lib/reform/form/dry/old_api.rb +61 -0
- data/lib/reform/form/populator.rb +11 -27
- data/lib/reform/form/prepopulate.rb +4 -3
- data/lib/reform/form/validate.rb +28 -13
- data/lib/reform/result.rb +90 -0
- data/lib/reform/validation.rb +19 -11
- data/lib/reform/validation/groups.rb +12 -27
- data/lib/reform/version.rb +1 -1
- data/reform.gemspec +14 -13
- data/test/benchmarking.rb +39 -6
- data/test/call_new_api.rb +23 -0
- data/test/call_old_api.rb +23 -0
- data/test/changed_test.rb +14 -14
- data/test/coercion_test.rb +57 -25
- data/test/composition_new_api.rb +186 -0
- data/test/composition_old_api.rb +184 -0
- data/test/contract/custom_error_test.rb +55 -0
- data/test/contract_new_api.rb +77 -0
- data/test/contract_old_api.rb +77 -0
- data/test/default_test.rb +4 -4
- data/test/deserialize_test.rb +17 -20
- data/test/errors_new_api.rb +225 -0
- data/test/errors_old_api.rb +230 -0
- data/test/feature_test.rb +10 -12
- data/test/fixtures/dry_error_messages.yml +73 -23
- 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} +8 -8
- data/test/form_option_new_api.rb +24 -0
- data/test/{form_option_test.rb → form_option_old_api.rb} +5 -5
- data/test/from_test.rb +18 -22
- data/test/inherit_new_api.rb +105 -0
- data/test/inherit_old_api.rb +105 -0
- data/test/{module_test.rb → module_new_api.rb} +26 -31
- data/test/module_old_api.rb +146 -0
- data/test/parse_option_test.rb +40 -0
- data/test/parse_pipeline_test.rb +4 -4
- data/test/populate_new_api.rb +304 -0
- data/test/populate_old_api.rb +304 -0
- data/test/populator_skip_test.rb +11 -11
- data/test/prepopulator_test.rb +23 -24
- data/test/read_only_test.rb +12 -1
- data/test/readable_test.rb +9 -9
- data/test/reform_new_api.rb +204 -0
- data/test/{reform_test.rb → reform_old_api.rb} +44 -65
- data/test/save_new_api.rb +101 -0
- data/test/save_old_api.rb +101 -0
- data/test/setup_test.rb +17 -17
- data/test/skip_if_new_api.rb +85 -0
- data/test/skip_if_old_api.rb +92 -0
- data/test/skip_setter_and_getter_test.rb +9 -10
- data/test/test_helper.rb +25 -14
- data/test/validate_new_api.rb +453 -0
- data/test/{validate_test.rb → validate_old_api.rb} +121 -131
- data/test/validation/dry_validation_new_api.rb +835 -0
- data/test/validation/dry_validation_old_api.rb +772 -0
- data/test/validation/result_test.rb +77 -0
- data/test/validation_library_provided_test.rb +16 -0
- data/test/virtual_test.rb +47 -7
- data/test/writeable_test.rb +38 -9
- metadata +111 -56
- data/gemfiles/Gemfile.disposable-0.3 +0 -6
- data/lib/reform/contract/errors.rb +0 -43
- data/lib/reform/form/mongoid.rb +0 -37
- data/lib/reform/form/orm.rb +0 -26
- data/lib/reform/mongoid.rb +0 -4
- data/test/call_test.rb +0 -23
- data/test/composition_test.rb +0 -149
- data/test/contract_test.rb +0 -77
- data/test/deprecation_test.rb +0 -27
- data/test/errors_test.rb +0 -165
- data/test/inherit_test.rb +0 -119
- data/test/populate_test.rb +0 -270
- data/test/readonly_test.rb +0 -14
- data/test/save_test.rb +0 -89
- data/test/skip_if_test.rb +0 -74
- data/test/validation/dry_test.rb +0 -60
- data/test/validation/dry_validation_test.rb +0 -352
- data/test/validation/errors.yml +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0f5d5dea8c04f5d993a91776afffea2a0b48603d850c11204d04e79248be6cf8
|
4
|
+
data.tar.gz: e4132e9db35384198bf31797b8620219c6418df4781a8f5300bbcf38c1a1c630
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0845ada0bbafc7c3a45485d51f93c66c8616bee7b23c851712d297be20c73e82f23a8e575f803adb2972c382c4c9003951ae8d788fe12df87195950490505028'
|
7
|
+
data.tar.gz: bd463ddb326f4db34ef9ad6948cdb9466a56c87514f2a18fcafba6dff29b54baf5640b97b490657b92e438c336869f35adc3e407b91be80351f427fd84f28c35
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
language: ruby
|
2
|
+
cache: bundler
|
3
|
+
bundler_args: --without benchmarks tools
|
2
4
|
rvm:
|
3
|
-
-
|
4
|
-
- 2.
|
5
|
+
- ruby-head
|
6
|
+
- 2.7
|
7
|
+
- 2.6
|
8
|
+
- 2.5
|
9
|
+
- 2.4
|
5
10
|
gemfile:
|
6
|
-
- gemfiles/
|
7
|
-
|
11
|
+
- gemfiles/1.5.0.gemfile
|
12
|
+
- gemfiles/0.13.0.gemfile
|
8
13
|
matrix:
|
9
14
|
fast_finish: true
|
10
|
-
|
11
|
-
|
15
|
+
allow_failures:
|
16
|
+
- rvm: ruby-head
|
data/Appraisals
ADDED
data/CHANGES.md
CHANGED
@@ -1,9 +1,62 @@
|
|
1
|
+
## 2.3.3
|
2
|
+
|
3
|
+
* Rename validation option for dry-v 1+ to `contract` instead of `schema`
|
4
|
+
|
5
|
+
## 2.3.2
|
6
|
+
|
7
|
+
* Fix Validation block option :form incorrectly memoized between tests
|
8
|
+
|
9
|
+
## 2.3.1
|
10
|
+
* With dry-validation 1.5 the form is always injected. Just add option :form to access it in the schema.
|
11
|
+
* Removed global monkey patching of Dry::Schema::DSL
|
12
|
+
* Tests in ruby 2.7
|
13
|
+
|
14
|
+
## 2.3.0
|
15
|
+
|
16
|
+
You can upgrade from 2.2.0 without worries.
|
17
|
+
|
18
|
+
* Require Representable 3.0.0 and **removed Representable 2.4 deprecation code**.
|
19
|
+
* Require Disposable 0.4.0 which fixes issues with `nil` field values, `sync {}` and dry-validation.
|
20
|
+
* Fix boolean coercion.
|
21
|
+
* Allow using `:populator` classes marked with `Uber::Callable`.
|
22
|
+
* Introduce `parse: false` as a shortcut for `deserialzer: { writeable: false}`. Thanks to @pabloh for insisting on this handy change.
|
23
|
+
* Memoize the deserializer instance on the class level via `::deserializer`. This saves the inferal of a deserializing representer and speeds up following calls by 130%.
|
24
|
+
* Deprecated positional arguments for `validation :default, options: {}`. New API: `validation name: :default, **`.
|
25
|
+
* Reform now maintains a generic `Dry::Schema` class for global schema configuration. Can be overridden via `::validation`.
|
26
|
+
* 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.
|
27
|
+
* [private] `Group#call` API now is: `call(form, errors)`.
|
28
|
+
* Modify `Form#valid?` - simply calls `validate({})`.
|
29
|
+
* In `:if` for validation groups, you now get a hash of result objects, not just true/false.
|
30
|
+
* Allow adding a custom error AFTER validate has been already called
|
31
|
+
|
32
|
+
Compatibility with `dry-validation` with 1.x:
|
33
|
+
* [CHANGE] seems like "custom" predicate are not supported by `dry-schema` anymore or better the same result is reached using the `rule` method:
|
34
|
+
Something like this:
|
35
|
+
```ruby
|
36
|
+
validation do
|
37
|
+
def a_song?(value)
|
38
|
+
value == :really_cool_song
|
39
|
+
end
|
40
|
+
|
41
|
+
required(:songs).filled(:a_song?)
|
42
|
+
end
|
43
|
+
```
|
44
|
+
will be something like:
|
45
|
+
```ruby
|
46
|
+
validation do
|
47
|
+
required(:songs).filled
|
48
|
+
|
49
|
+
rule(:songs) do
|
50
|
+
key.failure(:a_song?) unless value == :really_cool_song
|
51
|
+
end
|
52
|
+
end
|
53
|
+
```
|
54
|
+
* [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
|
55
|
+
|
1
56
|
## 2.2.4
|
2
57
|
|
3
|
-
*
|
4
|
-
|
5
|
-
The only difference here is that `Form#sync`/`#save` with a block will include `nil` properties into the nested hash.
|
6
|
-
* Remove `uber` dependency.
|
58
|
+
* You can now use any object with `call` as a populator, no need to `include Uber::Callable` anymore. This is because we have only three types and don't need a `is_a?` or `respond_to?` check.
|
59
|
+
* Use `declarative-option` and loosen `uber` dependency.
|
7
60
|
|
8
61
|
## 2.2.3
|
9
62
|
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
## How to contribute to Reform
|
2
|
+
|
3
|
+
#### **Did you find a bug?**
|
4
|
+
|
5
|
+
* **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/trailblazer/reform/issues).
|
6
|
+
|
7
|
+
* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/trailblazer/reform/issues/new). Be sure to follow the issue template.
|
8
|
+
|
9
|
+
#### **Did you write a patch that fixes a bug?**
|
10
|
+
|
11
|
+
* Open a new GitHub pull request with the patch.
|
12
|
+
|
13
|
+
* Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
|
14
|
+
|
15
|
+
* All code in pull requests is assumed to be MIT licensed. Do not submit a pull request if that isn't the case.
|
16
|
+
|
17
|
+
#### **Do you intend to add a new feature or change an existing one?**
|
18
|
+
|
19
|
+
* Suggest your change in the [Trailblazer Gitter Room](https://gitter.im/trailblazer/chat) and start writing code.
|
20
|
+
|
21
|
+
* Do not open an issue on GitHub until you have collected positive feedback about the change. GitHub issues are primarily intended for bug reports and fixes.
|
22
|
+
|
23
|
+
#### **Do you have questions using Reform?**
|
24
|
+
|
25
|
+
* Ask any questions about how to use Reform in the [Trailblazer Gitter Room](https://gitter.im/trailblazer/chat). Github issues are restricted to bug reports and fixes.
|
26
|
+
|
27
|
+
* GitHub Issues should not be used as a help forum and any such issues will be closed.
|
28
|
+
|
29
|
+
#### **Do you want to contribute to the Reform documentation?**
|
30
|
+
|
31
|
+
* Reform documentation is provided via the [Trailblazer site](http://trailblazer.to/gems/reform/) and not the repository readme. Please add your contributions to the [Trailblazer site repository](https://github.com/trailblazer/trailblazer.github.io)
|
data/Gemfile
CHANGED
@@ -1,19 +1,5 @@
|
|
1
|
-
source
|
1
|
+
source "https://rubygems.org"
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
|
6
|
-
# gem "representable", "2.4.0.rc5"
|
7
|
-
# gem 'representable', path: "../representable"
|
8
|
-
# # gem 'representable', github: "apotonick/representable"
|
9
|
-
# gem "disposable", path: "../disposable"
|
10
|
-
# gem "disposable", github: "apotonick/disposable"
|
11
|
-
|
12
|
-
|
13
|
-
# gem "declarative", path: "../declarative"
|
14
|
-
|
15
|
-
gem "minitest-line"
|
16
|
-
gem 'byebug'
|
17
|
-
|
18
|
-
# gem "uber", path: "../uber"
|
19
|
-
gem "representable", ">= 3.0.1"
|
5
|
+
gem "appraisal", "~> 2.2"
|
data/ISSUE_TEMPLATE.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
Note: If you have a question about Reform, would like help using
|
2
|
+
Reform, want to request a feature, or do anything else other than
|
3
|
+
submit a bug report, please use the [Trailblazer gitter channel](https://gitter.im/trailblazer/chat).
|
4
|
+
|
5
|
+
Note: Rails/ ActiveRecord/ ActiveModel support.
|
6
|
+
As of Reform 2.2.0 all Rails/ Active-* code was moved to the [reform-rails](https://github.com/trailblazer/reform-rails) gem.
|
7
|
+
Make sure you are contributing to the correct gem!
|
8
|
+
|
9
|
+
### Complete Description of Issue
|
10
|
+
|
11
|
+
|
12
|
+
### Steps to reproduce
|
13
|
+
|
14
|
+
|
15
|
+
### Expected behavior
|
16
|
+
Tell us what should happen
|
17
|
+
|
18
|
+
### Actual behavior
|
19
|
+
Tell us what happens instead
|
20
|
+
|
21
|
+
### System configuration
|
22
|
+
**Reform version**:
|
23
|
+
|
24
|
+
### Full Backtrace of Exception (if any)
|
25
|
+
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
[](https://gitter.im/trailblazer/chat)
|
4
4
|
[](http://trailblazer.to/newsletter/)
|
5
5
|
[](https://travis-ci.org/trailblazer/reform)
|
7
7
|
[](http://badge.fury.io/rb/reform)
|
8
8
|
|
9
9
|
_Form objects decoupled from your models._
|
@@ -296,7 +296,7 @@ Put this in an initializer or on top of your script.
|
|
296
296
|
Reform allows to map multiple models to one form. The [complete documentation](https://github.com/apotonick/disposable#composition) is here, however, this is how it works.
|
297
297
|
|
298
298
|
```ruby
|
299
|
-
class
|
299
|
+
class AlbumForm < Reform::Form
|
300
300
|
include Composition
|
301
301
|
|
302
302
|
property :id, on: :album
|
@@ -315,20 +315,18 @@ 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
|
-

|
320
|
-
</a>
|
318
|
+
[](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
|
|
331
|
-
Temporary note: This is the README and API for Reform 2. On the public API, only a few tiny things have changed. Here are the [Reform 1.2 docs](https://github.com/
|
329
|
+
Temporary note: This is the README and API for Reform 2. On the public API, only a few tiny things have changed. Here are the [Reform 1.2 docs](https://github.com/trailblazer/reform/blob/v1.2.6/README.md).
|
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
|
|
data/Rakefile
CHANGED
@@ -1,15 +1,22 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
-
require
|
2
|
+
require "rake/testtask"
|
3
|
+
require "dry/types/version"
|
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
|
+
api = Gem::Version.new(Dry::Types::VERSION).to_s.split('.').first.to_i >= 1 ? "new" : "old"
|
14
|
+
TEST_WITH_OLD_AND_NEW_API.map { |file| "test/#{file}_#{api}_api.rb" }
|
9
15
|
end
|
10
16
|
|
11
|
-
Rake::TestTask.new(:
|
12
|
-
test.libs <<
|
13
|
-
test.test_files = FileList[
|
17
|
+
Rake::TestTask.new(:test) do |test|
|
18
|
+
test.libs << "test"
|
19
|
+
test.test_files = FileList["test/*_test.rb"] + FileList["test/validation/*_test.rb"] + dry_v_test_files
|
14
20
|
test.verbose = true
|
15
21
|
end
|
22
|
+
|
data/lib/reform.rb
CHANGED
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
|
@@ -27,14 +26,13 @@ module Reform
|
|
27
26
|
super
|
28
27
|
end
|
29
28
|
|
30
|
-
# FIXME: test me.
|
31
29
|
def self.properties(*args)
|
32
30
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
33
31
|
args.each { |name| property(name, options.dup) }
|
34
32
|
end
|
35
33
|
|
36
|
-
require "reform/
|
37
|
-
require
|
34
|
+
require "reform/result"
|
35
|
+
require "reform/contract/validate"
|
38
36
|
include Reform::Contract::Validate
|
39
37
|
|
40
38
|
require "reform/validation"
|
@@ -44,23 +42,16 @@ module Reform
|
|
44
42
|
require "disposable/twin/sync"
|
45
43
|
include Disposable::Twin::Sync
|
46
44
|
|
45
|
+
private
|
47
46
|
|
48
|
-
|
49
|
-
# module ValidatesWarning
|
50
|
-
# def validates(*)
|
51
|
-
# raise "[Reform] Please include either Reform::Form::ActiveModel::Validations or Reform::Form::Lotus in your form class."
|
52
|
-
# end
|
53
|
-
# end
|
54
|
-
# extend ValidatesWarning
|
55
|
-
|
56
|
-
private
|
57
47
|
# DISCUSS: separate file?
|
58
48
|
module Readonly
|
59
49
|
def readonly?(name)
|
60
50
|
options_for(name)[:writeable] == false
|
61
51
|
end
|
52
|
+
|
62
53
|
def options_for(name)
|
63
|
-
|
54
|
+
self.class.options_for(name)
|
64
55
|
end
|
65
56
|
end
|
66
57
|
|
@@ -69,7 +60,6 @@ module Reform
|
|
69
60
|
end
|
70
61
|
include Readonly
|
71
62
|
|
72
|
-
|
73
63
|
def self.clone # TODO: test. THIS IS ONLY FOR Trailblazer when contract gets cloned in suboperation.
|
74
64
|
Class.new(self)
|
75
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
|
@@ -1,33 +1,63 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
class Reform::Contract < Disposable::Twin
|
2
|
+
module Validate
|
3
|
+
def initialize(*)
|
4
|
+
# this will be removed in Reform 3.0. we need this for the presenting form, form builders
|
5
|
+
# call the Form#errors method before validation.
|
6
|
+
super
|
7
|
+
@result = Result.new([])
|
8
|
+
end
|
6
9
|
|
7
|
-
|
10
|
+
def validate
|
11
|
+
validate!(nil).success?
|
12
|
+
end
|
8
13
|
|
9
|
-
|
10
|
-
|
14
|
+
# The #errors method will be removed in Reform 2.4/3.0 core.
|
15
|
+
def errors(*args)
|
16
|
+
Result::Errors.new(@result, self)
|
17
|
+
end
|
11
18
|
|
12
|
-
|
13
|
-
|
19
|
+
#:private:
|
20
|
+
# only used in tests so far. this will be the new API in #call, where you will get @result.
|
21
|
+
def to_result
|
22
|
+
@result
|
23
|
+
end
|
24
|
+
|
25
|
+
def custom_errors
|
26
|
+
@result.to_results.select { |result| result.is_a? Reform::Contract::CustomError }
|
27
|
+
end
|
14
28
|
|
15
|
-
|
16
|
-
|
29
|
+
def validate!(name, pointers = [])
|
30
|
+
# run local validations. this could be nested schemas, too.
|
31
|
+
local_errors_by_group = Reform::Validation::Groups::Validate.(self.class.validation_groups, self).compact # TODO: discss compact
|
17
32
|
|
18
|
-
|
33
|
+
# blindly add injected pointers. will be readable via #errors.
|
34
|
+
# also, add pointers from local errors here.
|
35
|
+
pointers_for_nested = pointers + local_errors_by_group.collect { |errs| Result::Pointer.new(errs, []) }.compact
|
19
36
|
|
20
|
-
|
21
|
-
|
22
|
-
|
37
|
+
nested_errors = validate_nested!(pointers_for_nested)
|
38
|
+
|
39
|
+
# Result: unified interface #success?, #messages, etc.
|
40
|
+
@result = Result.new(custom_errors + local_errors_by_group + pointers, nested_errors)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
# Recursively call validate! on nested forms.
|
46
|
+
# A pointer keeps an entire result object (e.g. Dry result) and
|
47
|
+
# the relevant path to its fragment, e.g. <Dry::result{.....} path=songs,0>
|
48
|
+
def validate_nested!(pointers)
|
49
|
+
arr = []
|
50
|
+
|
51
|
+
schema.each(twin: true) do |dfn|
|
52
|
+
# on collections, this calls validate! on each item form.
|
53
|
+
Disposable::Twin::PropertyProcessor.new(dfn, self).() do |form, i|
|
54
|
+
nested_pointers = pointers.collect { |pointer| pointer.advance(dfn[:name].to_sym, i) }.compact # pointer contains fragment for us, so go deeper
|
23
55
|
|
24
|
-
|
56
|
+
arr << form.validate!(dfn[:name], nested_pointers)
|
57
|
+
end
|
58
|
+
end
|
25
59
|
|
26
|
-
|
27
|
-
def validate_nested!(errors, prefixes)
|
28
|
-
schema.each(twin: true) do |dfn|
|
29
|
-
# recursively call valid? on nested form.
|
30
|
-
Disposable::Twin::PropertyProcessor.new(dfn, self).() { |form| form.validate!(errors, prefixes+[dfn[:name]]) }
|
60
|
+
arr
|
31
61
|
end
|
32
62
|
end
|
33
|
-
end
|
63
|
+
end
|