fend 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +44 -11
- data/fend.gemspec +2 -2
- data/lib/fend.rb +9 -18
- data/lib/fend/plugins/base_errors.rb +53 -0
- data/lib/fend/plugins/dependencies.rb +5 -46
- data/lib/fend/plugins/full_messages.rb +60 -12
- data/lib/fend/version.rb +1 -1
- metadata +6 -6
- data/lib/fend/plugins/collective_params.rb +0 -62
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d0f5edff32bf78090df43951c3a7aa95628ac4e2417566a51db60971bef24634
|
4
|
+
data.tar.gz: 201f363db87219f57403f6c665fdcad4e0f7e07a049604775503a68810ad015d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d7c9f4ac50bf03c2c6f3ba5f97e2a241b7dcf8b7e49139d4e3d5d889e4f6da6608483cb1e95b078407d9abd4b20fb53ad141e9a5d30cb9188977dbff82e1eba9
|
7
|
+
data.tar.gz: 9f4f65a5fea0b112712a86d07be79bbf852040040400ee3f4af65b30e8d8bb04cce5668cd8001f2d023ecca96f905f29a1d392f90af451e7df6c0aa008f1e8e3
|
data/README.md
CHANGED
@@ -11,6 +11,7 @@ Fend is a small and extensible data validation toolkit.
|
|
11
11
|
* [**Introduction**](#introduction)
|
12
12
|
* [Core functionalities](#core-functionalities)
|
13
13
|
* [Nested params](#nested-params)
|
14
|
+
* [Iterating over nested hash params](#iterating-over-nested-hash-params)
|
14
15
|
* [Arrays](#arrays)
|
15
16
|
* [**Plugins overview**](#plugins-overview)
|
16
17
|
* [Value helpers](#value-helpers)
|
@@ -40,7 +41,7 @@ Some of the features include:
|
|
40
41
|
|
41
42
|
## Documentation
|
42
43
|
|
43
|
-
For detailed documentation visit [
|
44
|
+
For detailed documentation visit [aradunovic.github.io/fend](https://aradunovic.github.io/fend)
|
44
45
|
|
45
46
|
## Why?
|
46
47
|
|
@@ -82,11 +83,12 @@ require "fend"
|
|
82
83
|
class UserValidation < Fend
|
83
84
|
# define validation block
|
84
85
|
validation do |i|
|
85
|
-
# specify
|
86
|
+
# specify username and email params that needs to be validated
|
86
87
|
i.params(:username, :email) do |username, email|
|
87
88
|
# append error if username value is not string
|
88
89
|
username.add_error("must be string") unless username.value.is_a?(String)
|
89
90
|
|
91
|
+
# append error is email is invalid or already exists
|
90
92
|
email.add_error("is not a valid email address") unless email.match?(EMAIL_REGEX)
|
91
93
|
email.add_error("must be unique") if email.valid? && !unique?(email: email.value)
|
92
94
|
|
@@ -130,7 +132,7 @@ result.failure? #=> true
|
|
130
132
|
result.input #=> { username: 1234, email: "invalid@email" }
|
131
133
|
|
132
134
|
# get result output
|
133
|
-
result.
|
135
|
+
result.output #=> { username: 1234, email: "invalid@email" }
|
134
136
|
|
135
137
|
# get error messages
|
136
138
|
result.messages #=> { username: ["must be string"], email: ["is not a valid email address"] }
|
@@ -161,14 +163,43 @@ result.failure? #=> true
|
|
161
163
|
result.messages #=> { address: ["must be hash"] }
|
162
164
|
```
|
163
165
|
|
164
|
-
|
165
|
-
|
166
|
+
**NOTE:** Nested param(s) validations won't be run if parent param
|
167
|
+
is invalid.
|
166
168
|
|
167
169
|
```ruby
|
168
170
|
result = UserValidation.call(username: "test", address: {})
|
169
171
|
result.messages #=> { address: { city: ["must be string"], street: ["must be string"] } }
|
170
172
|
```
|
171
173
|
|
174
|
+
#### Iterating over nested hash params
|
175
|
+
|
176
|
+
In order to iterate over nested hash params while ignoring the keys/names
|
177
|
+
use `Param#each` method with `hash: true` option:
|
178
|
+
|
179
|
+
```ruby
|
180
|
+
i.params(:emails) do |emails|
|
181
|
+
|
182
|
+
emails.each(hash: true) do |email_address|
|
183
|
+
email_address.params(:email, :confirmed) do |email, confirmed|
|
184
|
+
email.add_error("must be provided") if email.nil?
|
185
|
+
email.add_error("must be confirmed") if email.valid? && confirmed == false
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
user_params = {
|
191
|
+
emails: {
|
192
|
+
"0" => { email: "love@ruby.com", confirmed: false },
|
193
|
+
"1" => { email: "", confirmed: "" },
|
194
|
+
}
|
195
|
+
}
|
196
|
+
|
197
|
+
result = UserValidation.call(user_params)
|
198
|
+
|
199
|
+
result.messages
|
200
|
+
#=> { emails: { "0" => { email: ["must be confirmed"] }, "1" => { email: ["must be provided"] } } }
|
201
|
+
```
|
202
|
+
|
172
203
|
### Arrays
|
173
204
|
|
174
205
|
Validating array members is done by passing a block to `Param#each` method:
|
@@ -188,7 +219,7 @@ result = UserValidation.call(tags: [1, 2])
|
|
188
219
|
result.messages #=> { tags: { 0 => ["must be string"], 1 => ["must be string"] } }
|
189
220
|
```
|
190
221
|
|
191
|
-
|
222
|
+
**NOTE:** Member validations won't be run if `tags` is not an array.
|
192
223
|
|
193
224
|
Fend makes it possible to validate specific array members, since `#each` method
|
194
225
|
also provides an `index`:
|
@@ -205,7 +236,7 @@ end
|
|
205
236
|
|
206
237
|
## Plugins overview
|
207
238
|
|
208
|
-
For complete plugins documentation, go to [
|
239
|
+
For complete plugins documentation, go to [aradunovic.github.io/fend](https://aradunovic.github.io/fend).
|
209
240
|
|
210
241
|
### Value helpers
|
211
242
|
|
@@ -252,7 +283,7 @@ validation do |i|
|
|
252
283
|
|
253
284
|
address.validate_type(Hash)
|
254
285
|
|
255
|
-
address.
|
286
|
+
address.params(:city) do |city|
|
256
287
|
city.validate_presence
|
257
288
|
city.validate_type(String)
|
258
289
|
end
|
@@ -362,14 +393,16 @@ class UserValidation < Fend
|
|
362
393
|
end
|
363
394
|
|
364
395
|
validate do |i|
|
365
|
-
i.
|
366
|
-
|
396
|
+
i.params(:username, :foo) do |username, foo|
|
397
|
+
username.value #=>"john"
|
398
|
+
foo.value #=> "foo"
|
399
|
+
end
|
367
400
|
end
|
368
401
|
end
|
369
402
|
|
370
403
|
result = UserValidation.call(username: "john")
|
371
404
|
|
372
|
-
result.input #=> { username: "john" }
|
405
|
+
result.input #=> { username: "john", foo: "foo" }
|
373
406
|
result.output #=> { username: "john", timestamp: 2018-01-01 00:00:00 UTC }
|
374
407
|
```
|
375
408
|
|
data/fend.gemspec
CHANGED
@@ -4,11 +4,11 @@ Gem::Specification.new do |gem|
|
|
4
4
|
gem.name = "fend"
|
5
5
|
gem.version = Fend.version
|
6
6
|
gem.authors = ["Aleksandar Radunovic"]
|
7
|
-
gem.email = ["
|
7
|
+
gem.email = ["a.radunovic@pm.me"]
|
8
8
|
|
9
9
|
gem.summary = "Small and extensible data validation toolkit"
|
10
10
|
gem.description = gem.summary
|
11
|
-
gem.homepage = "https://
|
11
|
+
gem.homepage = "https://aradunovic.github.io/fend"
|
12
12
|
gem.license = "MIT"
|
13
13
|
|
14
14
|
gem.files = Dir["README.md", "LICENSE.txt", "lib/**/*.rb", "fend.gemspec", "doc/*.md"]
|
data/lib/fend.rb
CHANGED
@@ -186,20 +186,6 @@ class Fend
|
|
186
186
|
@value.fetch(name, nil) if @value.respond_to?(:fetch)
|
187
187
|
end
|
188
188
|
|
189
|
-
# Define child param and execute validation block
|
190
|
-
def param(name, &block)
|
191
|
-
Fend.deprecation("Calling Param#param to specify params is deprecated and will not be supported in Fend 0.3.0. Use Param#params method instead.")
|
192
|
-
|
193
|
-
return if flat? && invalid?
|
194
|
-
|
195
|
-
value = self[name]
|
196
|
-
param = _build_param(name, value)
|
197
|
-
|
198
|
-
yield(param)
|
199
|
-
|
200
|
-
_nest_errors(name, param.errors) if param.invalid?
|
201
|
-
end
|
202
|
-
|
203
189
|
# Define child params and execute validation block
|
204
190
|
def params(*names, &block)
|
205
191
|
return if flat? && invalid?
|
@@ -214,16 +200,21 @@ class Fend
|
|
214
200
|
params.each { |name, param| _nest_errors(name, param.errors) if param.invalid? }
|
215
201
|
end
|
216
202
|
|
217
|
-
# Define
|
218
|
-
def each(&block)
|
203
|
+
# Define enumerable param member and execute validation block
|
204
|
+
def each(opts = {}, &block)
|
219
205
|
return if (flat? && invalid?) || !@value.is_a?(Enumerable)
|
220
206
|
|
207
|
+
is_hash = opts[:hash].eql?(true)
|
208
|
+
|
209
|
+
return if is_hash && !@value.is_a?(Hash)
|
210
|
+
|
221
211
|
@value.each_with_index do |value, index|
|
222
|
-
|
212
|
+
param_name, param_value = is_hash ? value : [index, value]
|
213
|
+
param = _build_param(param_name, param_value)
|
223
214
|
|
224
215
|
yield(param, index)
|
225
216
|
|
226
|
-
_nest_errors(
|
217
|
+
_nest_errors(param.name, param.errors) if param.invalid?
|
227
218
|
end
|
228
219
|
end
|
229
220
|
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Fend
|
4
|
+
module Plugins
|
5
|
+
# `base_errors` plugin allows you to add validation errors which are
|
6
|
+
# not related to a specific param, but to validation input as a whole.
|
7
|
+
#
|
8
|
+
# class AuthValidation < Fend
|
9
|
+
# plugin :base_errors
|
10
|
+
#
|
11
|
+
# validate do |i|
|
12
|
+
# i.params(:email, :password) do |email, password|
|
13
|
+
# # ...
|
14
|
+
#
|
15
|
+
# if email.invalid? || password.invalid?
|
16
|
+
# add_base_error("Invalid email or password")
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# Messages are available under `:base` key by default.
|
23
|
+
#
|
24
|
+
# AuthValidation.call(email: nil, password: nil).messages
|
25
|
+
# #=> { base: ["Invalid email or password"] }
|
26
|
+
#
|
27
|
+
# You can specify custom key when loading the plugin:
|
28
|
+
#
|
29
|
+
# plugin :base_errors, key: :general
|
30
|
+
module BaseErrors
|
31
|
+
DEFAULT_KEY = :base
|
32
|
+
|
33
|
+
def self.configure(validation, opts = {})
|
34
|
+
validation.opts[:base_errors_key] = opts[:key] || validation.opts[:base_errors_key] || DEFAULT_KEY
|
35
|
+
end
|
36
|
+
|
37
|
+
module InstanceMethods
|
38
|
+
def add_base_error(message)
|
39
|
+
messages = @_input_param.errors
|
40
|
+
key = self.class.opts[:base_errors_key]
|
41
|
+
|
42
|
+
if messages.is_a?(Hash) && messages.key?(key)
|
43
|
+
messages[key] << message
|
44
|
+
else
|
45
|
+
@_input_param.params(key) { |base| base.add_error(message) }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
register_plugin(:base_errors, BaseErrors)
|
52
|
+
end
|
53
|
+
end
|
@@ -9,15 +9,7 @@ class Fend
|
|
9
9
|
#
|
10
10
|
# ## Registering dependencies
|
11
11
|
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
# 1. **Inheritable dependencies** - available in current validation class
|
15
|
-
# and in subclasses
|
16
|
-
# 2. *[DEPRECATED] **Local dependencies** - available only in current validation class
|
17
|
-
#
|
18
|
-
# ### Inheritable dependencies
|
19
|
-
#
|
20
|
-
# Inheritable dependencies can be registered when plugin is loaded:
|
12
|
+
# Dependencies can be registered when plugin is loaded:
|
21
13
|
#
|
22
14
|
# plugin :dependencies, user_class: User
|
23
15
|
#
|
@@ -30,27 +22,6 @@ class Fend
|
|
30
22
|
#
|
31
23
|
# Now, all `Fend` subclasses will be able to resolve `address_checker`
|
32
24
|
#
|
33
|
-
# ### Local dependencies *[DEPRECATED]
|
34
|
-
#
|
35
|
-
# Local dependencies can be registered in `deps` registry, on instance level.
|
36
|
-
# Recommended place to do this is the initializer.
|
37
|
-
#
|
38
|
-
# class UserValidation < Fend
|
39
|
-
# plugin :dependencies
|
40
|
-
#
|
41
|
-
# def initialize(model)
|
42
|
-
# # you can pass a dependency on initialization
|
43
|
-
# deps[:model] = model
|
44
|
-
#
|
45
|
-
# # or
|
46
|
-
#
|
47
|
-
# # hardcode it yourself
|
48
|
-
# deps[:address_checker] = AddressChecker.new
|
49
|
-
# end
|
50
|
-
# end
|
51
|
-
#
|
52
|
-
# user_validation = UserValidation.new(User)
|
53
|
-
#
|
54
25
|
# ## Resolving dependencies
|
55
26
|
#
|
56
27
|
# To resolve dependencies, `:inject` option needs to be provided to the
|
@@ -73,19 +44,13 @@ class Fend
|
|
73
44
|
# end
|
74
45
|
# end
|
75
46
|
#
|
76
|
-
# ## Overriding
|
47
|
+
# ## Overriding dependencies
|
77
48
|
#
|
78
|
-
# To override
|
79
|
-
#
|
49
|
+
# To override global dependency, just load the plugin again in a subclass
|
50
|
+
# and specify new dependecy value.
|
80
51
|
#
|
81
52
|
# plugin :dependencies, user_model: SpecialUser
|
82
53
|
#
|
83
|
-
# # or
|
84
|
-
#
|
85
|
-
# def initialize
|
86
|
-
# deps[:user_model] = SpecialUser
|
87
|
-
# end
|
88
|
-
#
|
89
54
|
# ## Example usage
|
90
55
|
#
|
91
56
|
# Here's an example of email uniqueness validation:
|
@@ -115,16 +80,10 @@ class Fend
|
|
115
80
|
end
|
116
81
|
|
117
82
|
module InstanceMethods
|
118
|
-
def deps
|
119
|
-
Fend.deprecation("Local dependencies are deprecated and will not be supported in Fend 0.3.0. Instead, you can set attributes or define custom methods which will be available in validation block.")
|
120
|
-
|
121
|
-
@_deps ||= self.class.opts[:dependencies].dup
|
122
|
-
end
|
123
|
-
|
124
83
|
def validate(&block)
|
125
84
|
super if self.class.specified_dependencies.nil?
|
126
85
|
|
127
|
-
dependencies =
|
86
|
+
dependencies = self.class.opts[:dependencies].values_at(*self.class.specified_dependencies)
|
128
87
|
|
129
88
|
yield(@_input_param, *dependencies) if block_given?
|
130
89
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
class Fend
|
4
4
|
module Plugins
|
5
5
|
# `full_messages` plugin adds `#full_messages` method to `Result` which
|
6
|
-
# returns error messages with prependend param name
|
6
|
+
# returns error messages with prependend param name.
|
7
7
|
#
|
8
8
|
# class UserValidation < Fend
|
9
9
|
# plugin :full_messages
|
@@ -23,7 +23,7 @@ class Fend
|
|
23
23
|
# { tags: { 0 => ["0 must be string"] } }
|
24
24
|
#
|
25
25
|
# In order to make full messages nicer for array elements,
|
26
|
-
# pass `:
|
26
|
+
# pass `:array_member_names` option when loading the plugin:
|
27
27
|
#
|
28
28
|
# plugin :full_messages, array_member_names: { tags: :tag }
|
29
29
|
#
|
@@ -35,30 +35,78 @@ class Fend
|
|
35
35
|
#
|
36
36
|
# Fend.plugin :full_messages, array_member_names: { octopi: :octopus }
|
37
37
|
#
|
38
|
+
# ## Base errors
|
39
|
+
#
|
40
|
+
# Full messages are **not** generated for errors added with `base_errors`
|
41
|
+
# plugin, since those messages are not connected to specific param(s).
|
38
42
|
module FullMessages
|
39
43
|
def self.configure(validation, opts = {})
|
40
44
|
validation.opts[:full_messages_array_member_names] = (validation.opts[:full_messages_array_member_names] || {}).merge(opts[:array_member_names] || {})
|
45
|
+
validation.const_set(:FullMessagesGenerator, Generator) unless validation.const_defined?(:FullMessagesGenerator)
|
41
46
|
end
|
42
47
|
|
43
48
|
module ResultMethods
|
44
49
|
def full_messages
|
45
|
-
@_full_messages ||=
|
50
|
+
@_full_messages ||= full_messages_generator.call(@errors)
|
46
51
|
end
|
47
52
|
|
48
53
|
private
|
49
54
|
|
50
|
-
def
|
51
|
-
|
52
|
-
|
53
|
-
|
55
|
+
def full_messages_generator
|
56
|
+
self.fend_class::FullMessagesGenerator.new(
|
57
|
+
array_member_names: fend_class.opts[:full_messages_array_member_names],
|
58
|
+
skip: [fend_class.opts[:base_errors_key]]
|
59
|
+
)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class Generator
|
64
|
+
def initialize(opts = {})
|
65
|
+
@array_params = opts.fetch(:array_member_names, {})
|
66
|
+
@skip_list = opts[:skip]
|
67
|
+
end
|
68
|
+
|
69
|
+
def call(errors)
|
70
|
+
errors.each_with_object({}) do |(param_name, messages), result|
|
71
|
+
result[param_name] = if @skip_list.include?(param_name)
|
72
|
+
messages
|
73
|
+
else
|
74
|
+
messages_for(param_name, messages)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
54
80
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
81
|
+
def messages_for(param, messages)
|
82
|
+
if messages.is_a?(Hash)
|
83
|
+
process_hash_messages(param, messages)
|
84
|
+
else
|
85
|
+
full_messages_for(param, messages)
|
60
86
|
end
|
61
87
|
end
|
88
|
+
|
89
|
+
def process_hash_messages(param, messages)
|
90
|
+
param_is_array = messages.first[0].is_a?(Integer)
|
91
|
+
|
92
|
+
messages.each_with_object({}) do |(_param, msgs), result|
|
93
|
+
param_name = if param_is_array
|
94
|
+
@array_params.fetch(param, _param)
|
95
|
+
else
|
96
|
+
_param
|
97
|
+
end
|
98
|
+
|
99
|
+
result[_param] = messages_for(param_name, msgs)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def full_messages_for(param_name, messages)
|
104
|
+
messages.map { |message| build_full_message(param_name, message) }
|
105
|
+
end
|
106
|
+
|
107
|
+
def build_full_message(param_name, message)
|
108
|
+
"#{param_name} #{message}"
|
109
|
+
end
|
62
110
|
end
|
63
111
|
end
|
64
112
|
|
data/lib/fend/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fend
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aleksandar Radunovic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -40,7 +40,7 @@ dependencies:
|
|
40
40
|
version: '0'
|
41
41
|
description: Small and extensible data validation toolkit
|
42
42
|
email:
|
43
|
-
-
|
43
|
+
- a.radunovic@pm.me
|
44
44
|
executables: []
|
45
45
|
extensions: []
|
46
46
|
extra_rdoc_files: []
|
@@ -49,8 +49,8 @@ files:
|
|
49
49
|
- README.md
|
50
50
|
- fend.gemspec
|
51
51
|
- lib/fend.rb
|
52
|
+
- lib/fend/plugins/base_errors.rb
|
52
53
|
- lib/fend/plugins/coercions.rb
|
53
|
-
- lib/fend/plugins/collective_params.rb
|
54
54
|
- lib/fend/plugins/contexts.rb
|
55
55
|
- lib/fend/plugins/data_processing.rb
|
56
56
|
- lib/fend/plugins/dependencies.rb
|
@@ -61,7 +61,7 @@ files:
|
|
61
61
|
- lib/fend/plugins/validation_options.rb
|
62
62
|
- lib/fend/plugins/value_helpers.rb
|
63
63
|
- lib/fend/version.rb
|
64
|
-
homepage: https://
|
64
|
+
homepage: https://aradunovic.github.io/fend
|
65
65
|
licenses:
|
66
66
|
- MIT
|
67
67
|
metadata: {}
|
@@ -81,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
81
|
version: '0'
|
82
82
|
requirements: []
|
83
83
|
rubyforge_project:
|
84
|
-
rubygems_version: 2.6
|
84
|
+
rubygems_version: 2.7.6
|
85
85
|
signing_key:
|
86
86
|
specification_version: 4
|
87
87
|
summary: Small and extensible data validation toolkit
|
@@ -1,62 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Fend
|
4
|
-
module Plugins
|
5
|
-
# *[DEPRECATED] `collective_params` plugin allows you to specify multiple params at once,
|
6
|
-
# instead of defining each one separately.
|
7
|
-
#
|
8
|
-
# Example:
|
9
|
-
#
|
10
|
-
# plugin :collective_params
|
11
|
-
# plugin :validation_helpers # just to make the example more concise
|
12
|
-
#
|
13
|
-
# validate do |i|
|
14
|
-
# i.params(:name, :email, :address) do |name, email, address|
|
15
|
-
# name.validate_presence
|
16
|
-
#
|
17
|
-
# email.validate_format(EMAIL_REGEX)
|
18
|
-
#
|
19
|
-
# address.params(:city, :street, :zip) do |city, street, zip|
|
20
|
-
# # ...
|
21
|
-
# end
|
22
|
-
# end
|
23
|
-
# end
|
24
|
-
#
|
25
|
-
# Since all params are then available in the same scope, you can add custom
|
26
|
-
# validations more easily:
|
27
|
-
#
|
28
|
-
# validate do |i|
|
29
|
-
# i.params(:started_at, :ended_at) do |started_at, ended_at|
|
30
|
-
# started_at.validate_presence
|
31
|
-
# started_at.validate_type(Time)
|
32
|
-
#
|
33
|
-
# ended_at.validate_presence
|
34
|
-
# ended_at.validate_type(Time)
|
35
|
-
#
|
36
|
-
# if started_at.valid? && ended_at.valid? && started_at > ended_at
|
37
|
-
# started_at.add_error("must happen before ended_at")
|
38
|
-
# end
|
39
|
-
# end
|
40
|
-
# end
|
41
|
-
module CollectiveParams
|
42
|
-
module ParamMethods
|
43
|
-
warn("collective_params plugin is deprecated and will be removed in Fend 0.3.0. #params method is now provided out of the box.")
|
44
|
-
|
45
|
-
def params(*names, &block)
|
46
|
-
return if flat? && invalid?
|
47
|
-
|
48
|
-
params = names.each_with_object({}) do |name, result|
|
49
|
-
param = _build_param(name, self[name])
|
50
|
-
result[name] = param
|
51
|
-
end
|
52
|
-
|
53
|
-
yield(*params.values)
|
54
|
-
|
55
|
-
params.each { |name, param| _nest_errors(name, param.errors) if param.invalid? }
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
register_plugin(:collective_params, CollectiveParams)
|
61
|
-
end
|
62
|
-
end
|