attribeauty 0.3.4 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 04be2abe193a7faca2c172bb90713086e2a656bada649e0356ada8a444f54993
4
- data.tar.gz: e86ca7fb0fbc2d8e20679be174a98eced95c6facf3d98d2b3d1983961e99a9c8
3
+ metadata.gz: a594dd2b01526d1b89bea9ceeea3217bf0cb311b236981be2e77bd03dc1b5b2f
4
+ data.tar.gz: 4f79df9cca230c2c0c29c34746f381818535095383c54902e8a7b90f8ea205de
5
5
  SHA512:
6
- metadata.gz: 1fe0d80aca7c85b8a34bf233f8b72133f16b75eea1a1800e8046efe5df1b19612a060662dc4c80bbbcffd0462d8cf2dee229a1c36228bba155dcff1058d814a7
7
- data.tar.gz: 42ab8159a2117c43956b84699f7ba9025a156e854e355f389424b810ecdfa90ee83f2fbdbdf71b43b650f723d1310288c18dc0f1e03f0f4765f193a8d58a1cc0
6
+ metadata.gz: 4ab16692f1f34715726b3777889c5ee4f1797eeff0431ce73a116c7e02c5faac34d0453188f2469938b1c98076e172dd37e5b18a5a2c1bff009bb483c067a984
7
+ data.tar.gz: 78f5e064bc51b85fbb57877ce9bd9a7d3894f7798fdfd7dcfe0dc7989fad2618f3d0358e22467d02351745710b92e81227f6b243a74254e90d377be474b1655a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.4.1] - 2024-06-25
4
+
5
+ - Global default_args in accept, to apply your conditions to all attributes
6
+
7
+ ## [0.4.0] - 2024-06-25
8
+
9
+ - Breaking change:
10
+ - `:allow_nil`, and `:allow_empty` have been replaced with `:exclude_if`
11
+ - see readme for details
12
+
3
13
  ## [0.3.4] - 2024-06-24
4
14
 
5
15
  - tiny refactor
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- attribeauty (0.3.4)
4
+ attribeauty (0.4.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -103,17 +103,18 @@ class MyController
103
103
 
104
104
  def update_params
105
105
  params_filter.accept do
106
- attribute :title, :string, allow_nil: false, required: true
106
+ attribute :title, :string, required: true
107
107
  attribute :email do
108
- attribute :address, :string, allow_empty: false
109
- attribute :valid, :boolean, allow_nil: false
110
- attribute :ip_address, :string, allow_blank: true
108
+ attribute :address, :string
109
+ attribute :valid, :boolean
110
+ attribute :ip_address, :string, exclude_if: :empty?
111
111
  end
112
112
  end
113
113
  end
114
114
  ```
115
115
 
116
- If you have a "head" param, like in rails, you can exclude it like this:
116
+ If you have a "head" param, like in rails, you can exclude it, also note the `exclude_if` option, this will exclude the value completely, if it evaluates to true.
117
+ `exclude_if` will accept a single method call (`:nil?`) or an array (`[:nil?, :empty?]`)
117
118
 
118
119
  ```
119
120
  class MyController
@@ -126,7 +127,7 @@ class MyController
126
127
  private
127
128
 
128
129
  # your params look like this:
129
- # { user: { title: "woo", email: { address: "hmm@yep.com" } } }
130
+ # { user: { title: "woo", email: { address: "hmm@yep.com", ip_address: "" } } }
130
131
  #
131
132
  def params_filter
132
133
  Attribeauty::Params.with(request.params)
@@ -138,11 +139,11 @@ class MyController
138
139
  def update_params
139
140
  params_filter.accept do
140
141
  container :user do
141
- attribute :title, :string, allow_nil: false, required: true
142
+ attribute :title, :string, required: true
142
143
  attribute :email do
143
- attribute :address, :string, allow_empty: false
144
- attribute :valid, :boolean, allow_nil: false
145
- attribute :ip_address, :string, allow_blank: true
144
+ attribute :address, :string, exclude_if: [:empty?, :nil?]
145
+ attribute :valid, :boolean
146
+ attribute :ip_address, :string, exclude_if: :empty?
146
147
  end
147
148
  end
148
149
  end
@@ -177,11 +178,48 @@ class MyController
177
178
  def update_params
178
179
  params_filter.accept! do
179
180
  container :user do
180
- attribute :title, :string, allow_nil: false, required: true
181
+ attribute :title, :string, exclude_if: :nil?, required: true
181
182
  attribute :email do
182
- attribute :address, :string, allow_empty: false
183
- attribute :valid, :boolean, allow_nil: false
184
- attribute :ip_address, :string, allow_blank: true
183
+ attribute :address, :string
184
+ attribute :valid, :boolean
185
+ attribute :ip_address, :string
186
+ end
187
+ end
188
+ end
189
+ end
190
+ end
191
+
192
+ ```
193
+
194
+ what if you want to require all attributes? If you pass the `required: true` or `exclude_if: :nil?` with the `accept`, it will be applied to all attributes.
195
+
196
+ ```
197
+ class MyController
198
+ def update
199
+ MyRecord.update(update_params)
200
+
201
+ redirect_to index_path
202
+ end
203
+
204
+ private
205
+
206
+ # your params look like this:
207
+ # { user: { profile: [{ address: { street_name: "Main St" } }] } }
208
+ #
209
+ def params_filter
210
+ Attribeauty::Params.with(request.params)
211
+ end
212
+
213
+ # exclude_if and required will be passed onto all attributes
214
+ #
215
+ def update_params
216
+ params_filter.accept exclude_if: :nil?, required: true do
217
+ container :user do
218
+ attribute :title, :string,
219
+ attribute :email do
220
+ attribute :address, :string
221
+ attribute :valid, :boolean
222
+ attribute :ip_address, :string
185
223
  end
186
224
  end
187
225
  end
@@ -10,15 +10,16 @@ module Attribeauty
10
10
  new(request_params)
11
11
  end
12
12
 
13
- attr_reader :allow_nil, :prefix, :request_params, :acceptables, :to_h, :errors, :strict
13
+ attr_reader :prefix, :request_params, :acceptables, :to_h, :errors, :strict, :default_args
14
14
 
15
15
  def initialize(request_params)
16
- @request_params = request_params.transform_keys(&:to_sym)
16
+ @request_params = (request_params || {}).transform_keys(&:to_sym)
17
17
  @to_h = {}
18
18
  @errors = []
19
19
  end
20
20
 
21
- def accept(&)
21
+ def accept(**args, &)
22
+ @default_args = args
22
23
  instance_eval(&)
23
24
 
24
25
  raise MissingAttributeError, errors.join(", ") if errors.any? && strict?
@@ -26,10 +27,10 @@ module Attribeauty
26
27
  self
27
28
  end
28
29
 
29
- def accept!(&)
30
+ def accept!(**args, &)
30
31
  @strict = true
31
32
 
32
- accept(&)
33
+ accept(**args, &)
33
34
  end
34
35
 
35
36
  def to_hash = to_h
@@ -47,7 +48,6 @@ module Attribeauty
47
48
  #
48
49
  def attribute(name, type = nil, **args, &block)
49
50
  value = request_params[name]
50
- return if required?(value, **args)
51
51
  return hash_from_nested(name, value, &block) if block_given?
52
52
 
53
53
  value_from_validator(name, value, type, **args)
@@ -67,29 +67,28 @@ module Attribeauty
67
67
 
68
68
  private
69
69
 
70
- def required?(value, **args)
71
- value.nil? && args[:required].nil?
72
- end
73
-
74
70
  def value_from_validator(name, value, type, **args)
75
- validator = Validator.run(name, value, type, **args)
71
+ merged_args = args.merge(default_args || {})
72
+ validator = Validator.run(name, value, type, **merged_args)
76
73
  @errors.push(*validator.errors)
77
74
  @to_h[name.to_sym] = validator.value if validator.valid?
78
75
  end
79
76
 
80
77
  def hash_from_nested(name, value, &block)
81
- @to_h[name.to_sym] =
78
+ result =
82
79
  if value.is_a?(Array)
83
80
  value.map do |val|
84
- params = self.class.with(val).accept(&block)
81
+ params = self.class.with(val).accept(**default_args, &block)
85
82
  @errors.push(*params.errors)
86
83
  params.to_h
87
84
  end.reject(&:empty?)
88
85
  else
89
- params = self.class.with(value).accept(&block)
86
+ params = self.class.with(value).accept(**default_args, &block)
90
87
  @errors.push(*params.errors)
91
88
  params.to_h
92
89
  end
90
+
91
+ @to_h[name.to_sym] = result unless result.empty?
93
92
  end
94
93
  end
95
94
  end
@@ -2,39 +2,36 @@
2
2
 
3
3
  module Attribeauty
4
4
  class Validator
5
- ALLOWS_HASH = {
6
- allow_nil: :nil?,
7
- allow_empty: :empty?
8
- }.freeze
9
-
10
5
  def self.run(name, type, original_val, **args)
11
6
  new(name, type, original_val, **args).run
12
7
  end
13
8
 
14
- attr_reader :original_val, :errors, :name, :type, :required, :default, :allows, :value, :valid
9
+ attr_reader :original_val, :errors, :name, :type, :required, :default, :excludes, :value, :valid
15
10
 
16
11
  def initialize(name, original_val, type = nil, **args)
17
12
  @name = name
18
13
  @type = type
19
14
  @original_val = original_val
20
15
  @default = args[:default]
21
- @required = args[:required] if args[:required] == true
22
- @allows = args.slice(*allows_array).delete_if { |_key, value| value == true }
16
+ args.delete_if { |key, value| key == :required && value == false }
17
+ @required = args[:required]
18
+ @excludes = args[:exclude_if]
23
19
 
24
20
  @valid = true
25
21
  @errors = []
26
22
  end
27
23
 
28
24
  def run
29
- if type.nil?
30
- @value = original_val
31
- else
32
- set_default
33
- cast_value
34
- handle_missing_required
35
- handle_predicates
36
- end
25
+ handle_missing_original_val!
26
+ handle_missing_required!
27
+ handle_missing_type
28
+
29
+ set_default
30
+ cast_value
31
+ handle_excludes
37
32
 
33
+ self
34
+ rescue ValueInvalidError
38
35
  self
39
36
  end
40
37
 
@@ -42,49 +39,46 @@ module Attribeauty
42
39
  valid
43
40
  end
44
41
 
42
+ def required?
43
+ required
44
+ end
45
+
45
46
  private
46
47
 
47
- def set_default
48
- return unless original_val.nil? && !default.nil?
48
+ def handle_missing_original_val!
49
+ return unless !required? && original_val.nil?
49
50
 
50
- @original_val = default
51
- end
52
-
53
- def cast_value
54
- @value = TypeCaster.run(original_val, type)
51
+ @valid = false
52
+ raise ValueInvalidError
55
53
  end
56
54
 
57
55
  # only returning errors if required is missing, not if nil?, or :empty?
58
- def handle_missing_required
56
+ def handle_missing_required!
59
57
  return unless required? && original_val.nil?
60
58
 
61
59
  errors << "#{name} required"
62
60
  @valid = false
61
+ raise ValueInvalidError
63
62
  end
64
63
 
65
- def handle_predicates
66
- return if predicate.nil? || !valid?
67
-
68
- @valid = !value.public_send(predicate)
64
+ def handle_missing_type
65
+ @value = original_val if type.nil?
69
66
  end
70
67
 
71
- def allows_array
72
- ALLOWS_HASH.keys
73
- end
68
+ def set_default
69
+ return unless original_val.nil? && !default.nil?
74
70
 
75
- # convert allow_nil -> :nil? or allow_empty -> :empty?
76
- # this will be used to public_send
77
- # NOTE: only one will be checked, if you pass both:
78
- # allow_nil and allow_empty, one will be ignored
79
- def predicate
80
- return if allows.empty?
71
+ @original_val = default
72
+ end
81
73
 
82
- key = allows.keys.first
83
- ALLOWS_HASH[key]
74
+ def cast_value
75
+ @value ||= TypeCaster.run(original_val, type)
84
76
  end
85
77
 
86
- def required?
87
- required
78
+ def handle_excludes
79
+ return if excludes.nil? || !valid?
80
+
81
+ @valid = ![*excludes].flatten.any? { |exclude| value.public_send(exclude) }
88
82
  end
89
83
  end
90
84
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Attribeauty
4
- VERSION = "0.3.4"
4
+ VERSION = "0.4.1"
5
5
  end
data/lib/attribeauty.rb CHANGED
@@ -8,6 +8,7 @@ require "forwardable"
8
8
  module Attribeauty
9
9
  class Error < StandardError; end
10
10
  class MissingAttributeError < StandardError; end
11
+ class ValueInvalidError < StandardError; end
11
12
 
12
13
  class << self
13
14
  def configuration
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attribeauty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Toby