reform 2.0.2 → 2.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +8 -1
- data/README.md +7 -0
- data/database.sqlite3 +0 -0
- data/lib/reform/form/active_model.rb +7 -2
- data/lib/reform/form/active_model/validations.rb +23 -14
- data/lib/reform/form/lotus.rb +6 -5
- data/lib/reform/version.rb +1 -1
- data/test/active_model_custom_validation_translations_test.rb +42 -14
- data/test/dummy/config/locales/en.yml +9 -203
- data/test/test_helper.rb +3 -0
- data/test/validate_test.rb +9 -0
- 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: 27711bf7172cfebfc6c1d62d3fd0d0c2cf30ca9b
|
4
|
+
data.tar.gz: 32a1f9984118720c0f5672fa05234399ce5de3a5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5919186056ee49ad7ed00f00257e2c6e3dcaa18f7f0e4df7c2218b42f7365fd958dcd541b32987e6423cfc275d2a62fcd983dab98236c81643154e3f27c5bd5
|
7
|
+
data.tar.gz: a874aa0a645f17c46ba95aa0f379af4a00f9857bba184a88a5f82c57b3a2343ff6c07c69137ed75553452cf0038b726b858dd9ff72513ba109722ee4f4e07d69
|
data/CHANGES.md
CHANGED
@@ -1,7 +1,14 @@
|
|
1
|
+
## 2.0.3
|
2
|
+
|
3
|
+
* `Form#valid?` is private now. Sorry for the inconvenience, but this has never been documented as public. Reason is that the only entry point for validation is `#validate` to give the form as less public API as possible and minimize misunderstandings.
|
4
|
+
|
5
|
+
The idea is that you set up the object graph before/while `#validate` and then invoke the validators once.
|
6
|
+
* Fixed AM to find proper i18n for error messages. This happens by injecting the form's `model_name` into the `Validator` object in ActiveModel.
|
7
|
+
|
1
8
|
## 2.0.2
|
2
9
|
|
3
10
|
* Fix `unique: true` validation in combination with `Composition`.
|
4
|
-
* Use newest Disposable 0.1.
|
11
|
+
* Use newest Disposable 0.1.9 which does not set `:pass_options` anymore.
|
5
12
|
|
6
13
|
## 2.0.1
|
7
14
|
|
data/README.md
CHANGED
@@ -16,6 +16,13 @@ Temporary note: This is the README and API for Reform 2. On the public API, only
|
|
16
16
|
|
17
17
|
Every form in Reform is a _twin_. Twins are non-persistent domain objects from the [Disposable gem](https://github.com/apotonick/disposable). All features of Disposable, like renaming fields, change tracking, etc. are available in Reform, too.
|
18
18
|
|
19
|
+
<!--
|
20
|
+
## ActiveModel
|
21
|
+
|
22
|
+
**WARNING: Reform will soon drop support for ActiveModel validations.**
|
23
|
+
|
24
|
+
This is mostly to save my mental integrity. The amount of problems we have in Reform with ActiveModel's poor object design, its lack of interfaces and encapsulation do outweigh the benefits. Please consider using Lotus::Validations instead, which will soon be mature enough to replace this dinosaur.
|
25
|
+
-->
|
19
26
|
|
20
27
|
## Defining Forms
|
21
28
|
|
data/database.sqlite3
CHANGED
Binary file
|
@@ -61,8 +61,13 @@ module Reform::Form::ActiveModel
|
|
61
61
|
form_name = model_options.first.to_s.camelize
|
62
62
|
namespace = model_options.last[:namespace].present? ? model_options.last[:namespace].to_s.camelize.constantize : nil
|
63
63
|
else
|
64
|
-
|
65
|
-
|
64
|
+
if name
|
65
|
+
form_name = name.sub(/(::)?Form$/, "") # Song::Form => "Song"
|
66
|
+
namespace = nil
|
67
|
+
else # anonymous forms. let's drop AM and forget about all this.
|
68
|
+
form_name = "reform"
|
69
|
+
namespace = nil
|
70
|
+
end
|
66
71
|
end
|
67
72
|
|
68
73
|
active_model_name_for(form_name, namespace)
|
@@ -44,32 +44,41 @@ module Reform::Form::ActiveModel
|
|
44
44
|
# on instance, it exposes #valid?.
|
45
45
|
class Validator
|
46
46
|
# current i18n scope: :activemodel.
|
47
|
-
|
48
47
|
include ActiveModel::Validations
|
49
|
-
# extend ActiveModel::Naming
|
50
48
|
|
51
|
-
|
52
|
-
|
53
|
-
|
49
|
+
class << self
|
50
|
+
def model_name
|
51
|
+
@_active_model_sucks || ActiveModel::Name.new(Reform::Form, nil, "Reform::Form")
|
52
|
+
end
|
54
53
|
|
55
|
-
|
56
|
-
|
54
|
+
def model_name=(name)
|
55
|
+
@_active_model_sucks = name
|
56
|
+
end
|
57
|
+
|
58
|
+
def clone
|
59
|
+
Class.new(self)
|
60
|
+
end
|
57
61
|
end
|
58
62
|
|
59
|
-
def
|
60
|
-
|
63
|
+
def initialize(form, name)
|
64
|
+
@form = form
|
65
|
+
self.class.model_name = name # one of the many reasons why i will drop support for AM::V in 2.1.
|
61
66
|
end
|
62
|
-
# we can also do self.name and return "reform/form" but then run into "wrong constant name reform/form" from the autoloader. wtf?
|
63
67
|
|
64
|
-
def
|
65
|
-
|
68
|
+
def method_missing(method_name, *args, &block)
|
69
|
+
@form.send(method_name, *args, &block)
|
66
70
|
end
|
67
71
|
end
|
68
72
|
|
73
|
+
private
|
74
|
+
|
69
75
|
# Needs to be implemented by every validation backend and implements the
|
70
76
|
# actual validation. See Reform::Form::Lotus, too!
|
71
77
|
def valid?
|
72
|
-
validator
|
78
|
+
# we always pass the model_name into the validator now, so AM:V can do its magic. problem is that
|
79
|
+
# AM does validator.class.model_name so we have to hack the dynamic model name into the
|
80
|
+
# Validator class.
|
81
|
+
validator = self.class.validator.new(self, model_name)
|
73
82
|
validator.valid? # run the Validations object's validator with the form as context. this won't pollute anything in the form.
|
74
83
|
|
75
84
|
|
@@ -81,4 +90,4 @@ module Reform::Form::ActiveModel
|
|
81
90
|
errors.empty?
|
82
91
|
end
|
83
92
|
end
|
84
|
-
end
|
93
|
+
end
|
data/lib/reform/form/lotus.rb
CHANGED
@@ -42,14 +42,15 @@ module Reform::Form::Lotus
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
def build_errors
|
46
|
+
Errors.new
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
45
50
|
|
46
51
|
def valid?
|
47
52
|
# DISCUSS: by using @fields here, we avoid setters being called. win!
|
48
53
|
validator = Lotus::Validations::Validator.new(self.class.validations, @fields, errors)
|
49
54
|
validator.validate
|
50
55
|
end
|
51
|
-
|
52
|
-
def build_errors
|
53
|
-
Errors.new
|
54
|
-
end
|
55
|
-
end
|
56
|
+
end
|
data/lib/reform/version.rb
CHANGED
@@ -3,45 +3,73 @@ require 'test_helper'
|
|
3
3
|
class ActiveModelCustomValidationTranslationsTest < MiniTest::Spec
|
4
4
|
module SongForm
|
5
5
|
class WithBlock < Reform::Form
|
6
|
+
model :song
|
6
7
|
property :title
|
7
8
|
|
8
9
|
validate do
|
9
10
|
errors.add :title, :blank
|
11
|
+
errors.add :title, :custom_error_message
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
13
15
|
class WithLambda < Reform::Form
|
16
|
+
model :song
|
14
17
|
property :title
|
15
18
|
|
16
|
-
validate ->{ errors.add :title, :blank
|
19
|
+
validate ->{ errors.add :title, :blank
|
20
|
+
errors.add :title, :custom_error_message }
|
17
21
|
end
|
18
22
|
|
19
23
|
class WithMethod < Reform::Form
|
24
|
+
model :song
|
20
25
|
property :title
|
21
26
|
|
22
27
|
validate :custom_validation_method
|
23
28
|
def custom_validation_method
|
24
29
|
errors.add :title, :blank
|
30
|
+
errors.add :title, :custom_error_message
|
25
31
|
end
|
26
32
|
end
|
27
33
|
end
|
28
34
|
|
29
35
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
36
|
+
describe 'when using a default translation' do
|
37
|
+
it 'translates the error message when custom validation is used with block' do
|
38
|
+
form = SongForm::WithBlock.new(Song.new)
|
39
|
+
form.validate({})
|
40
|
+
form.errors[:title].must_include "can't be blank"
|
41
|
+
end
|
35
42
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
43
|
+
it 'translates the error message when custom validation is used with lambda' do
|
44
|
+
form = SongForm::WithLambda.new(Song.new)
|
45
|
+
form.validate({})
|
46
|
+
form.errors[:title].must_include "can't be blank"
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'translates the error message when custom validation is used with method' do
|
50
|
+
form = SongForm::WithMethod.new(Song.new)
|
51
|
+
form.validate({})
|
52
|
+
form.errors[:title].must_include "can't be blank"
|
53
|
+
end
|
40
54
|
end
|
41
55
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
56
|
+
describe 'when using a custom translation' do
|
57
|
+
it 'translates the error message when custom validation is used with block' do
|
58
|
+
form = SongForm::WithBlock.new(Song.new)
|
59
|
+
form.validate({})
|
60
|
+
form.errors[:title].must_include "Custom Error Message"
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'translates the error message when custom validation is used with lambda' do
|
64
|
+
form = SongForm::WithLambda.new(Song.new)
|
65
|
+
form.validate({})
|
66
|
+
form.errors[:title].must_include "Custom Error Message"
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'translates the error message when custom validation is used with method' do
|
70
|
+
form = SongForm::WithMethod.new(Song.new)
|
71
|
+
form.validate({})
|
72
|
+
form.errors[:title].must_include "Custom Error Message"
|
73
|
+
end
|
46
74
|
end
|
47
75
|
end
|
@@ -1,205 +1,11 @@
|
|
1
1
|
---
|
2
2
|
en:
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
abbr_month_names:
|
13
|
-
-
|
14
|
-
- Jan
|
15
|
-
- Feb
|
16
|
-
- Mar
|
17
|
-
- Apr
|
18
|
-
- May
|
19
|
-
- Jun
|
20
|
-
- Jul
|
21
|
-
- Aug
|
22
|
-
- Sep
|
23
|
-
- Oct
|
24
|
-
- Nov
|
25
|
-
- Dec
|
26
|
-
day_names:
|
27
|
-
- Sunday
|
28
|
-
- Monday
|
29
|
-
- Tuesday
|
30
|
-
- Wednesday
|
31
|
-
- Thursday
|
32
|
-
- Friday
|
33
|
-
- Saturday
|
34
|
-
formats:
|
35
|
-
default: "%Y-%m-%d"
|
36
|
-
long: "%B %d, %Y"
|
37
|
-
short: "%b %d"
|
38
|
-
month_names:
|
39
|
-
-
|
40
|
-
- January
|
41
|
-
- February
|
42
|
-
- March
|
43
|
-
- April
|
44
|
-
- May
|
45
|
-
- June
|
46
|
-
- July
|
47
|
-
- August
|
48
|
-
- September
|
49
|
-
- October
|
50
|
-
- November
|
51
|
-
- December
|
52
|
-
order:
|
53
|
-
- :year
|
54
|
-
- :month
|
55
|
-
- :day
|
56
|
-
datetime:
|
57
|
-
distance_in_words:
|
58
|
-
about_x_hours:
|
59
|
-
one: about 1 hour
|
60
|
-
other: about %{count} hours
|
61
|
-
about_x_months:
|
62
|
-
one: about 1 month
|
63
|
-
other: about %{count} months
|
64
|
-
about_x_years:
|
65
|
-
one: about 1 year
|
66
|
-
other: about %{count} years
|
67
|
-
almost_x_years:
|
68
|
-
one: almost 1 year
|
69
|
-
other: almost %{count} years
|
70
|
-
half_a_minute: half a minute
|
71
|
-
less_than_x_minutes:
|
72
|
-
one: less than a minute
|
73
|
-
other: less than %{count} minutes
|
74
|
-
less_than_x_seconds:
|
75
|
-
one: less than 1 second
|
76
|
-
other: less than %{count} seconds
|
77
|
-
over_x_years:
|
78
|
-
one: over 1 year
|
79
|
-
other: over %{count} years
|
80
|
-
x_days:
|
81
|
-
one: 1 day
|
82
|
-
other: "%{count} days"
|
83
|
-
x_minutes:
|
84
|
-
one: 1 minute
|
85
|
-
other: "%{count} minutes"
|
86
|
-
x_months:
|
87
|
-
one: 1 month
|
88
|
-
other: "%{count} months"
|
89
|
-
x_seconds:
|
90
|
-
one: 1 second
|
91
|
-
other: "%{count} seconds"
|
92
|
-
prompts:
|
93
|
-
day: Day
|
94
|
-
hour: Hour
|
95
|
-
minute: Minute
|
96
|
-
month: Month
|
97
|
-
second: Seconds
|
98
|
-
year: Year
|
99
|
-
errors:
|
100
|
-
format: "%{attribute} %{message}"
|
101
|
-
messages:
|
102
|
-
accepted: must be accepted
|
103
|
-
blank: can't be blank
|
104
|
-
present: must be blank
|
105
|
-
confirmation: doesn't match %{attribute}
|
106
|
-
empty: can't be empty
|
107
|
-
equal_to: must be equal to %{count}
|
108
|
-
even: must be even
|
109
|
-
exclusion: is reserved
|
110
|
-
greater_than: must be greater than %{count}
|
111
|
-
greater_than_or_equal_to: must be greater than or equal to %{count}
|
112
|
-
inclusion: is not included in the list
|
113
|
-
invalid: is invalid
|
114
|
-
less_than: must be less than %{count}
|
115
|
-
less_than_or_equal_to: must be less than or equal to %{count}
|
116
|
-
not_a_number: is not a number
|
117
|
-
not_an_integer: must be an integer
|
118
|
-
odd: must be odd
|
119
|
-
record_invalid: 'Validation failed: %{errors}'
|
120
|
-
restrict_dependent_destroy:
|
121
|
-
one: Cannot delete record because a dependent %{record} exists
|
122
|
-
many: Cannot delete record because dependent %{record} exist
|
123
|
-
taken: has already been taken
|
124
|
-
too_long:
|
125
|
-
one: is too long (maximum is 1 character)
|
126
|
-
other: is too long (maximum is %{count} characters)
|
127
|
-
too_short:
|
128
|
-
one: is too short (minimum is 1 character)
|
129
|
-
other: is too short (minimum is %{count} characters)
|
130
|
-
wrong_length:
|
131
|
-
one: is the wrong length (should be 1 character)
|
132
|
-
other: is the wrong length (should be %{count} characters)
|
133
|
-
other_than: must be other than %{count}
|
134
|
-
template:
|
135
|
-
body: 'There were problems with the following fields:'
|
136
|
-
header:
|
137
|
-
one: 1 error prohibited this %{model} from being saved
|
138
|
-
other: "%{count} errors prohibited this %{model} from being saved"
|
139
|
-
helpers:
|
140
|
-
select:
|
141
|
-
prompt: Please select
|
142
|
-
submit:
|
143
|
-
create: Create %{model}
|
144
|
-
submit: Save %{model}
|
145
|
-
update: Update %{model}
|
146
|
-
number:
|
147
|
-
currency:
|
148
|
-
format:
|
149
|
-
delimiter: ","
|
150
|
-
format: "%u%n"
|
151
|
-
precision: 2
|
152
|
-
separator: "."
|
153
|
-
significant: false
|
154
|
-
strip_insignificant_zeros: false
|
155
|
-
unit: "$"
|
156
|
-
format:
|
157
|
-
delimiter: ","
|
158
|
-
precision: 3
|
159
|
-
separator: "."
|
160
|
-
significant: false
|
161
|
-
strip_insignificant_zeros: false
|
162
|
-
human:
|
163
|
-
decimal_units:
|
164
|
-
format: "%n %u"
|
165
|
-
units:
|
166
|
-
billion: Billion
|
167
|
-
million: Million
|
168
|
-
quadrillion: Quadrillion
|
169
|
-
thousand: Thousand
|
170
|
-
trillion: Trillion
|
171
|
-
unit: ''
|
172
|
-
format:
|
173
|
-
delimiter: ''
|
174
|
-
precision: 3
|
175
|
-
significant: true
|
176
|
-
strip_insignificant_zeros: true
|
177
|
-
storage_units:
|
178
|
-
format: "%n %u"
|
179
|
-
units:
|
180
|
-
byte:
|
181
|
-
one: Byte
|
182
|
-
other: Bytes
|
183
|
-
gb: GB
|
184
|
-
kb: KB
|
185
|
-
mb: MB
|
186
|
-
tb: TB
|
187
|
-
percentage:
|
188
|
-
format:
|
189
|
-
delimiter: ''
|
190
|
-
format: "%n%"
|
191
|
-
precision:
|
192
|
-
format:
|
193
|
-
delimiter: ''
|
194
|
-
support:
|
195
|
-
array:
|
196
|
-
last_word_connector: ", and "
|
197
|
-
two_words_connector: " and "
|
198
|
-
words_connector: ", "
|
199
|
-
time:
|
200
|
-
am: am
|
201
|
-
formats:
|
202
|
-
default: "%a, %d %b %Y %H:%M:%S %z"
|
203
|
-
long: "%B %d, %Y %H:%M"
|
204
|
-
short: "%d %b %H:%M"
|
205
|
-
pm: pm
|
3
|
+
# custom validation error messages
|
4
|
+
|
5
|
+
activemodel:
|
6
|
+
errors:
|
7
|
+
models:
|
8
|
+
song:
|
9
|
+
attributes:
|
10
|
+
title:
|
11
|
+
custom_error_message: Custom Error Message
|
data/test/test_helper.rb
CHANGED
data/test/validate_test.rb
CHANGED
@@ -132,6 +132,15 @@ class ValidateWithoutConfigurationTest < MiniTest::Spec
|
|
132
132
|
form.songs[1].composer.name.must_equal "SNFU"
|
133
133
|
form.artist.name.must_equal "The Police"
|
134
134
|
end
|
135
|
+
|
136
|
+
# throws exception when no populators.
|
137
|
+
it do
|
138
|
+
album = Album.new("The Dissent Of Man", [])
|
139
|
+
|
140
|
+
assert_raises RuntimeError do
|
141
|
+
AlbumForm.new(album).validate(songs: {title: "Resist-Stance"})
|
142
|
+
end
|
143
|
+
end
|
135
144
|
end
|
136
145
|
|
137
146
|
class ValidateWithDeserializerOptionTest < MiniTest::Spec
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reform
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-07-
|
12
|
+
date: 2015-07-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: disposable
|