easy_params 0.9.0 → 0.9.1
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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +71 -0
- data/lib/easy_params/base.rb +8 -9
- data/lib/easy_params/composition.rb +2 -2
- data/lib/easy_params/types/generic.rb +5 -3
- data/lib/easy_params/types/struct.rb +15 -3
- data/lib/easy_params/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2bee55f0854b77323d19e97acace58d7de0602aa1bb4500c19a0b9ea79f26013
|
|
4
|
+
data.tar.gz: 2587c8ae019b986041b712ddf9eb433666ff99efa7dcacbe1b4f6d2ae31ec66a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b66f092c49e32afc330b5230184edad67af9c7ede2362befd80861978e90a22efe8dc86d9166121432416b9014fed2467654b294aa7c316dcf557ed13e987c1d
|
|
7
|
+
data.tar.gz: 45aaac0c0cb73909c1d75d9288fb1d3ab357a1a549295bebe160cbadb8cf0355b1bf1a112b14191fc2ca0d540b5a2667dd8b8b24ceedb01523e33086b6d9425d
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -173,6 +173,77 @@ params.comments.first.created_at # => Date.today
|
|
|
173
173
|
- **Replaces parent**: The new subclass completely replaces the original schema class
|
|
174
174
|
- **Collection support**: Works with both `has` (struct) and `each` (collection) parameters
|
|
175
175
|
|
|
176
|
+
### Composition and Owner Context
|
|
177
|
+
|
|
178
|
+
EasyParams supports composition through an owner relationship, allowing nested objects to access methods from their parent objects or an external owner object. This is particularly useful for conditional validations and accessing context from nested structures.
|
|
179
|
+
|
|
180
|
+
Every `EasyParams::Base` instance has an `owner` attribute that is automatically set for nested objects:
|
|
181
|
+
- Objects created with `has` get their parent as the owner
|
|
182
|
+
- Objects in collections created with `each` get the collection as their owner, and the collection gets the parent as its owner
|
|
183
|
+
|
|
184
|
+
You can access methods on the owner chain using the `owner_` prefix:
|
|
185
|
+
|
|
186
|
+
```ruby
|
|
187
|
+
class Owner
|
|
188
|
+
def check_name?
|
|
189
|
+
true
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def check_address_city?
|
|
193
|
+
true
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def check_phone_number?
|
|
197
|
+
true
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
class UserParams < EasyParams::Base
|
|
202
|
+
integer :id
|
|
203
|
+
string :name, presence: { if: :owner_check_name? }
|
|
204
|
+
|
|
205
|
+
has :address do
|
|
206
|
+
string :street
|
|
207
|
+
string :city, presence: { if: :owner_check_address_city? }
|
|
208
|
+
string :state
|
|
209
|
+
string :zip
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
each :phones do
|
|
213
|
+
string :number, presence: { if: :owner_check_phone_number? }
|
|
214
|
+
string :type
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Use with an external owner object
|
|
219
|
+
owner = Owner.new
|
|
220
|
+
params = UserParams.new(
|
|
221
|
+
id: 1,
|
|
222
|
+
address: { street: '123 Main St', city: nil },
|
|
223
|
+
phones: [{ number: nil, type: 'home' }]
|
|
224
|
+
)
|
|
225
|
+
params.owner = owner
|
|
226
|
+
|
|
227
|
+
# Validations will use the owner's methods
|
|
228
|
+
params.valid? # => false
|
|
229
|
+
params.errors[:name] # => ["can't be blank"]
|
|
230
|
+
params.address.errors[:city] # => ["can't be blank"]
|
|
231
|
+
params.phones[0].errors[:number] # => ["can't be blank"]
|
|
232
|
+
|
|
233
|
+
# Owner relationships are automatically established
|
|
234
|
+
params.owner # => owner
|
|
235
|
+
params.address.owner # => params (parent)
|
|
236
|
+
params.phones.owner # => params (parent)
|
|
237
|
+
params.phones[0].owner # => params.phones (collection)
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**Key Features:**
|
|
241
|
+
- **Automatic owner setup**: Nested objects automatically get their parent as owner
|
|
242
|
+
- **Owner chain**: The `owner_` prefix searches up the owner chain to find methods
|
|
243
|
+
- **External owners**: Set an external object as owner to provide additional context
|
|
244
|
+
- **Conditional validations**: Use owner methods in validation conditions (`if:`, `unless:`)
|
|
245
|
+
- **Nested access**: Works at any nesting level - nested objects can access parent methods
|
|
246
|
+
|
|
176
247
|
### Validation errors
|
|
177
248
|
|
|
178
249
|
```ruby
|
data/lib/easy_params/base.rb
CHANGED
|
@@ -52,7 +52,7 @@ module EasyParams
|
|
|
52
52
|
raise ArgumentError, "definition for attribute #{param_name.inspect} must be a subclass of EasyParams::Base"
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
-
handle_schema_definition(param_name, definition,
|
|
55
|
+
handle_schema_definition(param_name, definition, &block)
|
|
56
56
|
type = EasyParams::Types::Each.of(schemas[param_name].new)
|
|
57
57
|
type = customize_type(type, default, &normalize)
|
|
58
58
|
attribute(param_name, type)
|
|
@@ -101,24 +101,23 @@ module EasyParams
|
|
|
101
101
|
type
|
|
102
102
|
end
|
|
103
103
|
|
|
104
|
-
def handle_schema_definition(param_name, definition = nil,
|
|
104
|
+
def handle_schema_definition(param_name, definition = nil, &block)
|
|
105
105
|
schemas[param_name] = definition || Class.new(EasyParams::Base).tap { |c| c.class_eval(&block) }
|
|
106
|
-
define_schema_method(param_name
|
|
106
|
+
define_schema_method(param_name)
|
|
107
107
|
end
|
|
108
108
|
|
|
109
|
-
def define_schema_method(param_name
|
|
109
|
+
def define_schema_method(param_name)
|
|
110
110
|
define_singleton_method("#{param_name}_schema") do |&block|
|
|
111
|
-
default = schema[param_name].read_default
|
|
112
111
|
schemas[param_name] = Class.new(schemas[param_name]).tap { |c| c.class_eval(&block) }
|
|
113
|
-
type = create_schema_type(param_name,
|
|
112
|
+
type = create_schema_type(param_name, schema[param_name])
|
|
114
113
|
attribute(param_name, type)
|
|
115
114
|
end
|
|
116
115
|
end
|
|
117
116
|
|
|
118
|
-
def create_schema_type(param_name,
|
|
117
|
+
def create_schema_type(param_name, custom_type)
|
|
119
118
|
type = schemas[param_name].new
|
|
120
|
-
type = EasyParams::Types::Each.of(type) if
|
|
121
|
-
customize_type(type,
|
|
119
|
+
type = EasyParams::Types::Each.of(type) if custom_type.is_a?(Types::StructsCollection)
|
|
120
|
+
customize_type(type, custom_type.read_default, &custom_type.normalize_proc)
|
|
122
121
|
end
|
|
123
122
|
end
|
|
124
123
|
|
|
@@ -21,7 +21,7 @@ module EasyParams
|
|
|
21
21
|
return super unless name.to_s.start_with?('owner_')
|
|
22
22
|
|
|
23
23
|
owner_method = name.to_s.sub('owner_', '').to_sym
|
|
24
|
-
return super unless (handler = owners_chain.lazy.detect { |o| o.
|
|
24
|
+
return super unless (handler = owners_chain.lazy.detect { |o| o.respond_to?(owner_method) })
|
|
25
25
|
|
|
26
26
|
handler.public_send(owner_method, *attrs, **kwargs, &block)
|
|
27
27
|
end
|
|
@@ -37,7 +37,7 @@ module EasyParams
|
|
|
37
37
|
def owners_chain
|
|
38
38
|
@owners_chain ||= Enumerator.new do |y|
|
|
39
39
|
obj = self
|
|
40
|
-
y << obj = obj.owner while obj.
|
|
40
|
+
y << obj = obj.owner while obj.respond_to?(:owner)
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
end
|
|
@@ -4,9 +4,7 @@ module EasyParams
|
|
|
4
4
|
module Types
|
|
5
5
|
# base interface for simple types
|
|
6
6
|
class Generic
|
|
7
|
-
|
|
8
|
-
@title == :array
|
|
9
|
-
end
|
|
7
|
+
attr_reader :normalize_proc
|
|
10
8
|
|
|
11
9
|
def initialize(title, default = nil, normalize_proc = nil, &coerce_proc)
|
|
12
10
|
@title = title
|
|
@@ -15,6 +13,10 @@ module EasyParams
|
|
|
15
13
|
@normalize_proc = normalize_proc
|
|
16
14
|
end
|
|
17
15
|
|
|
16
|
+
def array?
|
|
17
|
+
@title == :array
|
|
18
|
+
end
|
|
19
|
+
|
|
18
20
|
def default(value)
|
|
19
21
|
self.class.new(@title, value, @normalize_proc, &@coerce_proc)
|
|
20
22
|
end
|
|
@@ -12,14 +12,26 @@ module EasyParams
|
|
|
12
12
|
@default
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
def normalize_proc
|
|
16
|
+
@normalize_proc
|
|
17
|
+
end
|
|
18
|
+
|
|
15
19
|
def default(value)
|
|
16
20
|
self.default = value
|
|
17
21
|
self
|
|
18
22
|
end
|
|
19
23
|
|
|
20
|
-
def
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
def normalize(&block)
|
|
25
|
+
@normalize_proc = block
|
|
26
|
+
self
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def coerce(value)
|
|
30
|
+
return if value.nil? && @default.nil?
|
|
31
|
+
|
|
32
|
+
input = value || @default
|
|
33
|
+
input = @normalize_proc.call(input) if @normalize_proc
|
|
34
|
+
return self.class.new(input) if input.is_a?(Hash)
|
|
23
35
|
|
|
24
36
|
self.class.new(input)
|
|
25
37
|
end
|
data/lib/easy_params/version.rb
CHANGED