attribeauty 0.3.4 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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