formeze 4.2.1 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +36 -0
- data/README.md +36 -20
- data/formeze.gemspec +4 -3
- data/lib/formeze/block.rb +11 -0
- data/lib/formeze/errors.rb +20 -5
- data/lib/formeze/field.rb +38 -28
- data/lib/formeze/form_data.rb +42 -12
- data/lib/formeze/presence.rb +7 -4
- data/lib/formeze/validation.rb +2 -4
- data/lib/formeze.rb +36 -43
- metadata +21 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd2160c23942cd4a127e7f84993aceb1a416a687060fb4f907181d295d5b26d5
|
4
|
+
data.tar.gz: 7406001697348315beeeb47c7400756e4bf8fb8acb60b8d872004f8de2966382
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83a0278250e4a4d9a1e7adae850e34cc4d44bdfa0e71638cf15ec7042abce347889495a4c6466d189ca30a9eb7b35e23472db91237f85f11841ef83fee2e01f8
|
7
|
+
data.tar.gz: b4218dd2e97436668378a40863a652ef1e7f7e329c0fa903e44197846b935ba8af21c7d2e34f804e483c9fda385deb39529b8a2049f69e4130b2238ef1ef9c2b
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,39 @@
|
|
1
|
+
# 5.0.0
|
2
|
+
|
3
|
+
* Added a `fill` field option to specify how to fill a field. For example:
|
4
|
+
|
5
|
+
class ExampleForm < Formeze::Form
|
6
|
+
field :year, required: false, fill: ->{ _1.date&.year }
|
7
|
+
end
|
8
|
+
|
9
|
+
* Added functionality for defining field specific error messages via i18n.
|
10
|
+
|
11
|
+
Add translations to your locale files like this:
|
12
|
+
|
13
|
+
ExampleForm:
|
14
|
+
errors:
|
15
|
+
comments:
|
16
|
+
required: 'are required'
|
17
|
+
|
18
|
+
* Removed support for older rubies. **Required ruby version is now 3.0.0**
|
19
|
+
|
20
|
+
* Changed from cgi to rack for parsing form data, adding support for parsing
|
21
|
+
requests with different methods e.g. PUT and PATCH instead of just POST.
|
22
|
+
|
23
|
+
Whilst this should largely be backwards compatible there are some differences,
|
24
|
+
for example uploaded files will be instances of `Rack::Multipart::UploadedFile`
|
25
|
+
instead of `StringIO` instances as they were before.
|
26
|
+
|
27
|
+
* Changed the default blank value to `nil`
|
28
|
+
|
29
|
+
# 4.3.0
|
30
|
+
|
31
|
+
* Added dependency on cgi gem
|
32
|
+
|
33
|
+
* Added support for lambda conditions without arguments
|
34
|
+
|
35
|
+
* Fixed custom validation for fields with multiple values
|
36
|
+
|
1
37
|
# 4.2.1
|
2
38
|
|
3
39
|
* Fixed regression in v4.2.0 when mime-types gem is not loaded
|
data/README.md
CHANGED
@@ -3,19 +3,19 @@
|
|
3
3
|
![Gem Version](https://badge.fury.io/rb/formeze.svg)
|
4
4
|
![Test Status](https://github.com/readysteady/formeze/actions/workflows/test.yml/badge.svg)
|
5
5
|
|
6
|
-
Ruby gem for validating form data.
|
6
|
+
Ruby gem for parsing and validating form data.
|
7
7
|
|
8
8
|
|
9
9
|
## Motivation
|
10
10
|
|
11
|
-
Most web
|
11
|
+
Most web applications built for end users will need to process form data.
|
12
12
|
Registration forms, profile forms, checkout forms, contact forms, and forms
|
13
13
|
for adding/editing application specific data.
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
With formeze you can define form objects that explicitly define what your
|
16
|
+
application expects as input. This is more secure, and leads to much better
|
17
|
+
separation of responsibilities, and also allows for implementing different
|
18
|
+
validation rules in different contexts.
|
19
19
|
|
20
20
|
|
21
21
|
## Install
|
@@ -53,7 +53,8 @@ else
|
|
53
53
|
end
|
54
54
|
```
|
55
55
|
|
56
|
-
Formeze will automatically ignore the Rails "
|
56
|
+
Formeze will automatically ignore the Rails "authenticity_token", "commit",
|
57
|
+
and "utf8" parameters.
|
57
58
|
|
58
59
|
If you prefer not to inherit from the `Formeze::Form` class then you can
|
59
60
|
instead call the `Formeze.setup` method on your classes like this:
|
@@ -89,9 +90,9 @@ messages specific to a single field.
|
|
89
90
|
|
90
91
|
## Field options
|
91
92
|
|
92
|
-
By default fields cannot be blank, they are limited
|
93
|
-
and they cannot contain newlines. These restrictions can be
|
94
|
-
by setting various field options.
|
93
|
+
By default fields are required (i.e. they cannot be blank), they are limited
|
94
|
+
to 64 characters, and they cannot contain newlines. These restrictions can be
|
95
|
+
overridden by setting various field options.
|
95
96
|
|
96
97
|
Defining a field without any options works well for a simple text input.
|
97
98
|
If the default length limit is too big or too small you can override it
|
@@ -101,11 +102,14 @@ by setting the `maxlength` option. For example:
|
|
101
102
|
field :title, maxlength: 200
|
102
103
|
```
|
103
104
|
|
104
|
-
Similarly there is a `minlength` option for
|
105
|
-
|
105
|
+
Similarly there is a `minlength` option for defining a minimum length:
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
field :password, minlength: 8
|
109
|
+
```
|
106
110
|
|
107
111
|
Fields are required by default. Specify the `required` option if the field
|
108
|
-
is
|
112
|
+
is optional. For example:
|
109
113
|
|
110
114
|
```ruby
|
111
115
|
field :title, required: false
|
@@ -174,7 +178,7 @@ the `defined_if` or `defined_unless` options with a proc. Here's an example
|
|
174
178
|
of using the defined_if option:
|
175
179
|
|
176
180
|
```ruby
|
177
|
-
field :business_name, defined_if:
|
181
|
+
field :business_name, defined_if: ->{ @account.business? }
|
178
182
|
```
|
179
183
|
|
180
184
|
In this example the `business_name` field will only be defined and validated
|
@@ -185,7 +189,7 @@ Here's an example of using the defined_unless option:
|
|
185
189
|
```ruby
|
186
190
|
field :same_address, values: %w(true), key_required: false
|
187
191
|
|
188
|
-
field :billing_address_line_one, defined_unless:
|
192
|
+
field :billing_address_line_one, defined_unless: ->{ same_address? }
|
189
193
|
|
190
194
|
def same_address?
|
191
195
|
same_address == 'true'
|
@@ -308,11 +312,11 @@ would include the value of the `formeze.errors.does_not_match` I18n key.
|
|
308
312
|
|
309
313
|
## I18n integration
|
310
314
|
|
311
|
-
Formeze integrates with [
|
315
|
+
Formeze integrates with the [i18n gem](https://rubygems.org/gems/i18n)
|
312
316
|
so that you can define custom error messages and field labels within your
|
313
317
|
locales (useful both for localization, and when working with designers).
|
314
|
-
|
315
|
-
|
318
|
+
|
319
|
+
Here is an example of how you would change the "required" error message:
|
316
320
|
|
317
321
|
```yaml
|
318
322
|
# config/locales/en.yml
|
@@ -322,8 +326,20 @@ en:
|
|
322
326
|
required: "cannot be blank"
|
323
327
|
```
|
324
328
|
|
325
|
-
|
326
|
-
|
329
|
+
Error messages defined in this way apply globally to all Formeze forms.
|
330
|
+
|
331
|
+
You can also change error messages on a per field basis, for example:
|
332
|
+
|
333
|
+
```yaml
|
334
|
+
# config/locales/en.yml
|
335
|
+
en:
|
336
|
+
ExampleForm:
|
337
|
+
errors:
|
338
|
+
comments:
|
339
|
+
required: 'are required'
|
340
|
+
```
|
341
|
+
|
342
|
+
Here is an example of how to define a custom label for "first_name" fields:
|
327
343
|
|
328
344
|
```yaml
|
329
345
|
# config/locales/en.yml
|
data/formeze.gemspec
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'formeze'
|
3
|
-
s.version = '
|
3
|
+
s.version = '5.0.0'
|
4
4
|
s.license = 'LGPL-3.0'
|
5
5
|
s.platform = Gem::Platform::RUBY
|
6
6
|
s.authors = ['Tim Craft']
|
7
7
|
s.email = ['mail@timcraft.com']
|
8
8
|
s.homepage = 'https://github.com/readysteady/formeze'
|
9
|
-
s.description = 'Ruby gem for validating form data'
|
9
|
+
s.description = 'Ruby gem for parsing and validating form data'
|
10
10
|
s.summary = 'See description'
|
11
11
|
s.files = Dir.glob('lib/**/*.rb') + %w(CHANGES.md LICENSE.txt README.md formeze.gemspec)
|
12
|
-
s.required_ruby_version = '>=
|
12
|
+
s.required_ruby_version = '>= 3.0.0'
|
13
13
|
s.require_path = 'lib'
|
14
14
|
s.metadata = {
|
15
15
|
'homepage' => 'https://github.com/readysteady/formeze',
|
@@ -17,4 +17,5 @@ Gem::Specification.new do |s|
|
|
17
17
|
'bug_tracker_uri' => 'https://github.com/readysteady/formeze/issues',
|
18
18
|
'changelog_uri' => 'https://github.com/readysteady/formeze/blob/main/CHANGES.md'
|
19
19
|
}
|
20
|
+
s.add_dependency 'rack', '~> 3'
|
20
21
|
end
|
data/lib/formeze/errors.rb
CHANGED
@@ -1,11 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Formeze::Errors
|
2
4
|
SCOPE = [:formeze, :errors].freeze
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
6
|
+
DEFAULT = {
|
7
|
+
bad_value: 'is invalid',
|
8
|
+
not_accepted: 'is not an accepted file type',
|
9
|
+
not_multiline: 'cannot contain newlines',
|
10
|
+
no_match: 'is invalid',
|
11
|
+
required: 'is required',
|
12
|
+
too_large: 'is too large',
|
13
|
+
too_long: 'is too long',
|
14
|
+
too_short: 'is too short',
|
15
|
+
}
|
16
|
+
|
17
|
+
def self.translate(error, scope:)
|
18
|
+
default = DEFAULT[error] || 'is invalid'
|
19
|
+
|
20
|
+
return default unless defined?(I18n)
|
21
|
+
|
22
|
+
message = I18n.translate(error, scope: scope, default: nil)
|
8
23
|
|
9
|
-
default
|
24
|
+
message || I18n.translate(error, scope: SCOPE, default: default)
|
10
25
|
end
|
11
26
|
end
|
data/lib/formeze/field.rb
CHANGED
@@ -14,49 +14,41 @@ class Formeze::Field
|
|
14
14
|
|
15
15
|
values.each do |value|
|
16
16
|
if String === value
|
17
|
-
validate(value, form)
|
17
|
+
value = validate(value, form)
|
18
18
|
else
|
19
|
-
|
19
|
+
form.add_error(self, :not_accepted) unless acceptable_file?(value)
|
20
20
|
|
21
21
|
size += value.size
|
22
22
|
end
|
23
|
+
|
24
|
+
value = Array(form.send(name)).push(value) if multiple?
|
25
|
+
|
26
|
+
form.send(:"#{name}=", value)
|
23
27
|
end
|
24
28
|
|
25
|
-
form.add_error(self, :too_large
|
29
|
+
form.add_error(self, :too_large) if maxsize? && size > maxsize
|
26
30
|
end
|
27
31
|
|
28
32
|
def validate(value, form)
|
29
33
|
value = Formeze.scrub(value, @options[:scrub])
|
30
34
|
|
31
35
|
if blank?(value)
|
32
|
-
form.add_error(self, :required
|
36
|
+
form.add_error(self, :required) if required?
|
33
37
|
|
34
|
-
value = blank_value
|
38
|
+
value = blank_value
|
35
39
|
else
|
36
|
-
form.add_error(self, :not_multiline
|
37
|
-
|
38
|
-
form.add_error(self, :too_long, 'is too long') if too_long?(value)
|
39
|
-
|
40
|
-
form.add_error(self, :too_short, 'is too short') if too_short?(value)
|
41
|
-
|
42
|
-
form.add_error(self, :no_match, 'is invalid') if no_match?(value)
|
40
|
+
form.add_error(self, :not_multiline) if !multiline? && value.lines.count > 1
|
43
41
|
|
44
|
-
form.add_error(self, :
|
45
|
-
end
|
42
|
+
form.add_error(self, :too_long) if too_long?(value)
|
46
43
|
|
47
|
-
|
44
|
+
form.add_error(self, :too_short) if too_short?(value)
|
48
45
|
|
49
|
-
|
50
|
-
end
|
46
|
+
form.add_error(self, :no_match) if no_match?(value)
|
51
47
|
|
52
|
-
|
53
|
-
unless acceptable_file?(object)
|
54
|
-
form.add_error(self, :not_accepted, 'is not an accepted file type')
|
48
|
+
form.add_error(self, :bad_value) if values? && !values.include?(value)
|
55
49
|
end
|
56
50
|
|
57
|
-
|
58
|
-
|
59
|
-
form.send(:"#{name}=", object)
|
51
|
+
value
|
60
52
|
end
|
61
53
|
|
62
54
|
def acceptable_file?(object)
|
@@ -103,6 +95,10 @@ class Formeze::Field
|
|
103
95
|
@options.fetch(:maxsize)
|
104
96
|
end
|
105
97
|
|
98
|
+
def accept?
|
99
|
+
@options.key?(:accept)
|
100
|
+
end
|
101
|
+
|
106
102
|
def accept
|
107
103
|
@accept ||= @options.fetch(:accept).split(',').flat_map { |type| MIME::Types[type] }
|
108
104
|
end
|
@@ -119,12 +115,8 @@ class Formeze::Field
|
|
119
115
|
@options.key?(:pattern) && value !~ @options[:pattern]
|
120
116
|
end
|
121
117
|
|
122
|
-
def blank_value?
|
123
|
-
@options.key?(:blank)
|
124
|
-
end
|
125
|
-
|
126
118
|
def blank_value
|
127
|
-
@options
|
119
|
+
@options[:blank]
|
128
120
|
end
|
129
121
|
|
130
122
|
def values?
|
@@ -150,4 +142,22 @@ class Formeze::Field
|
|
150
142
|
def defined_unless
|
151
143
|
@options.fetch(:defined_unless)
|
152
144
|
end
|
145
|
+
|
146
|
+
def undefined?(form)
|
147
|
+
if defined_if?
|
148
|
+
!Formeze::Block.evaluate(form, defined_if)
|
149
|
+
elsif defined_unless?
|
150
|
+
Formeze::Block.evaluate(form, defined_unless)
|
151
|
+
else
|
152
|
+
false
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def fill_proc?
|
157
|
+
@options.key?(:fill)
|
158
|
+
end
|
159
|
+
|
160
|
+
def fill_proc
|
161
|
+
@options[:fill]
|
162
|
+
end
|
153
163
|
end
|
data/lib/formeze/form_data.rb
CHANGED
@@ -1,23 +1,53 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'rack'
|
2
3
|
|
3
4
|
module Formeze::FormData
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
def self.parse(input)
|
6
|
+
if input.is_a?(String)
|
7
|
+
query_parser.parse_query(input)
|
8
|
+
elsif input.respond_to?(:env)
|
9
|
+
body = input.body
|
10
|
+
body.rewind if body.respond_to?(:rewind)
|
11
|
+
case input.media_type
|
12
|
+
when 'multipart/form-data'
|
13
|
+
Rack::Multipart.parse_multipart(input.env, Params)
|
14
|
+
when 'application/x-www-form-urlencoded'
|
15
|
+
query_parser.parse_query(body.read)
|
16
|
+
else
|
17
|
+
raise ArgumentError, "can't parse #{input.media_type.inspect} form data"
|
18
|
+
end
|
19
|
+
else
|
20
|
+
raise ArgumentError, "can't parse #{input.class} form data"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module Params
|
25
|
+
def self.make_params
|
26
|
+
ParamsHash.new { |h, k| h[k] = Array.new }
|
7
27
|
end
|
8
28
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
29
|
+
def self.normalize_params(params, key, value)
|
30
|
+
if value.is_a?(Hash)
|
31
|
+
value = Rack::Multipart::UploadedFile.new(io: value[:tempfile], filename: value[:filename], content_type: value[:type])
|
12
32
|
end
|
33
|
+
|
34
|
+
params[key] << value
|
13
35
|
end
|
14
36
|
end
|
15
37
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
38
|
+
class ParamsHash < ::Hash
|
39
|
+
alias_method :to_params_hash, :to_h
|
40
|
+
end
|
41
|
+
|
42
|
+
class QueryParser < Rack::QueryParser
|
43
|
+
def make_params
|
44
|
+
Hash.new { |h, k| h[k] = Array.new }
|
21
45
|
end
|
22
46
|
end
|
47
|
+
|
48
|
+
def self.query_parser
|
49
|
+
@query_parser ||= QueryParser.new(nil, 0)
|
50
|
+
end
|
51
|
+
|
52
|
+
private_class_method :query_parser
|
23
53
|
end
|
data/lib/formeze/presence.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
module Formeze::Presence
|
2
2
|
REGEXP = /\S/
|
3
3
|
|
4
|
-
def present?(
|
5
|
-
|
4
|
+
def present?(value)
|
5
|
+
return false if value.nil?
|
6
|
+
return false if value.respond_to?(:empty?) && value.empty?
|
7
|
+
return false if value.is_a?(String) && value !~ REGEXP
|
8
|
+
return true
|
6
9
|
end
|
7
10
|
|
8
|
-
def blank?(
|
9
|
-
|
11
|
+
def blank?(value)
|
12
|
+
!present?(value)
|
10
13
|
end
|
11
14
|
end
|
data/lib/formeze/validation.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
class Formeze::Validation
|
4
2
|
include Formeze::Presence
|
5
3
|
|
@@ -14,7 +12,7 @@ class Formeze::Validation
|
|
14
12
|
end
|
15
13
|
|
16
14
|
def validates?(form)
|
17
|
-
@precondition ?
|
15
|
+
@precondition ? Formeze::Block.evaluate(form, @precondition) : true
|
18
16
|
end
|
19
17
|
|
20
18
|
def field_value?(form)
|
@@ -33,7 +31,7 @@ class Formeze::Validation
|
|
33
31
|
form.instance_eval(&@block)
|
34
32
|
end
|
35
33
|
|
36
|
-
form.add_error(@field, @error
|
34
|
+
form.add_error(@field, @error) unless return_value
|
37
35
|
end
|
38
36
|
end
|
39
37
|
end
|
data/lib/formeze.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Formeze
|
4
|
+
autoload :Block, 'formeze/block'
|
4
5
|
autoload :Errors, 'formeze/errors'
|
5
6
|
autoload :Field, 'formeze/field'
|
6
7
|
autoload :Form, 'formeze/form'
|
@@ -35,16 +36,24 @@ module Formeze
|
|
35
36
|
|
36
37
|
class ValueError < StandardError; end
|
37
38
|
|
38
|
-
class ValidationError < StandardError
|
39
|
+
class ValidationError < StandardError
|
40
|
+
def initialize(field, message)
|
41
|
+
@field = field
|
39
42
|
|
40
|
-
|
43
|
+
super("#{field.label} #{message}")
|
44
|
+
end
|
41
45
|
|
42
|
-
|
46
|
+
def field_name
|
47
|
+
@field.name
|
48
|
+
end
|
49
|
+
end
|
43
50
|
|
44
51
|
module InstanceMethods
|
45
52
|
def fill(object)
|
46
53
|
self.class.fields.each_value do |field|
|
47
|
-
if
|
54
|
+
if field.fill_proc?
|
55
|
+
send(:"#{field.name}=", Formeze::Block.evaluate(object, field.fill_proc))
|
56
|
+
elsif Hash === object && object.key?(field.name)
|
48
57
|
send(:"#{field.name}=", object[field.name])
|
49
58
|
elsif object.respond_to?(field.name)
|
50
59
|
send(:"#{field.name}=", object.send(field.name))
|
@@ -58,27 +67,31 @@ module Formeze
|
|
58
67
|
form_data = FormData.parse(input)
|
59
68
|
|
60
69
|
self.class.fields.each_value do |field|
|
61
|
-
next
|
70
|
+
next if field.undefined?(self)
|
62
71
|
|
63
72
|
unless form_data.key?(field.key)
|
64
73
|
next if field.multiple? || !field.key_required?
|
65
74
|
|
66
|
-
raise KeyError, "missing form key: #{field.key}"
|
75
|
+
raise KeyError, "missing form key: #{field.key}" unless field.accept?
|
67
76
|
end
|
68
77
|
|
69
78
|
values = form_data.delete(field.key)
|
70
79
|
|
71
|
-
if values.
|
72
|
-
|
73
|
-
|
80
|
+
if values.is_a?(Array)
|
81
|
+
if values.length > 1
|
82
|
+
raise ValueError, "multiple values for #{field.key} field" unless field.multiple?
|
83
|
+
end
|
74
84
|
|
75
|
-
|
85
|
+
field.validate_all(values, self)
|
86
|
+
else
|
87
|
+
field.validate(values, self)
|
88
|
+
end
|
76
89
|
end
|
77
90
|
|
78
91
|
if defined?(Rails)
|
79
|
-
|
80
|
-
|
81
|
-
|
92
|
+
form_data.delete('authenticity_token')
|
93
|
+
form_data.delete('commit')
|
94
|
+
form_data.delete('utf8')
|
82
95
|
end
|
83
96
|
|
84
97
|
unless form_data.empty?
|
@@ -92,14 +105,10 @@ module Formeze
|
|
92
105
|
return self
|
93
106
|
end
|
94
107
|
|
95
|
-
def add_error(field,
|
96
|
-
message = Formeze::Errors.translate(
|
97
|
-
|
98
|
-
error = ValidationError.new("#{field.label} #{message}")
|
108
|
+
def add_error(field, error)
|
109
|
+
message = Formeze::Errors.translate(error, scope: "#{self.class.name}.errors.#{field.name}")
|
99
110
|
|
100
|
-
errors <<
|
101
|
-
|
102
|
-
field_errors[field.name] << error
|
111
|
+
errors << ValidationError.new(field, message)
|
103
112
|
end
|
104
113
|
|
105
114
|
def valid?
|
@@ -115,11 +124,11 @@ module Formeze
|
|
115
124
|
end
|
116
125
|
|
117
126
|
def errors_on?(field_name)
|
118
|
-
|
127
|
+
errors.any? { |error| error.field_name == field_name }
|
119
128
|
end
|
120
129
|
|
121
130
|
def errors_on(field_name)
|
122
|
-
|
131
|
+
errors.select { |error| error.field_name == field_name }
|
123
132
|
end
|
124
133
|
|
125
134
|
def to_h
|
@@ -129,22 +138,6 @@ module Formeze
|
|
129
138
|
end
|
130
139
|
|
131
140
|
alias_method :to_hash, :to_h
|
132
|
-
|
133
|
-
private
|
134
|
-
|
135
|
-
def field_defined?(field)
|
136
|
-
if field.defined_if?
|
137
|
-
instance_eval(&field.defined_if)
|
138
|
-
elsif field.defined_unless?
|
139
|
-
!instance_eval(&field.defined_unless)
|
140
|
-
else
|
141
|
-
true
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
def field_errors
|
146
|
-
@field_errors ||= Hash.new { |h, k| h[k] = [] }
|
147
|
-
end
|
148
141
|
end
|
149
142
|
|
150
143
|
def self.label(field_name)
|
@@ -153,11 +146,11 @@ module Formeze
|
|
153
146
|
|
154
147
|
def self.scrub_methods
|
155
148
|
@scrub_methods ||= {
|
156
|
-
:
|
157
|
-
:
|
158
|
-
:
|
159
|
-
:
|
160
|
-
:
|
149
|
+
strip: :strip.to_proc,
|
150
|
+
upcase: :upcase.to_proc,
|
151
|
+
downcase: :downcase.to_proc,
|
152
|
+
squeeze: proc { |string| string.squeeze(' ') },
|
153
|
+
squeeze_lines: proc { |string| string.gsub(/(\r?\n)(\r?\n)(\r?\n)+/, '\\1\\2') }
|
161
154
|
}
|
162
155
|
end
|
163
156
|
|
metadata
CHANGED
@@ -1,16 +1,30 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: formeze
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Craft
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
12
|
-
dependencies:
|
13
|
-
|
11
|
+
date: 2024-07-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3'
|
27
|
+
description: Ruby gem for parsing and validating form data
|
14
28
|
email:
|
15
29
|
- mail@timcraft.com
|
16
30
|
executables: []
|
@@ -22,6 +36,7 @@ files:
|
|
22
36
|
- README.md
|
23
37
|
- formeze.gemspec
|
24
38
|
- lib/formeze.rb
|
39
|
+
- lib/formeze/block.rb
|
25
40
|
- lib/formeze/errors.rb
|
26
41
|
- lib/formeze/field.rb
|
27
42
|
- lib/formeze/form.rb
|
@@ -45,14 +60,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
45
60
|
requirements:
|
46
61
|
- - ">="
|
47
62
|
- !ruby/object:Gem::Version
|
48
|
-
version:
|
63
|
+
version: 3.0.0
|
49
64
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
65
|
requirements:
|
51
66
|
- - ">="
|
52
67
|
- !ruby/object:Gem::Version
|
53
68
|
version: '0'
|
54
69
|
requirements: []
|
55
|
-
rubygems_version: 3.5.
|
70
|
+
rubygems_version: 3.5.11
|
56
71
|
signing_key:
|
57
72
|
specification_version: 4
|
58
73
|
summary: See description
|