tramway 0.4.1 → 0.4.2

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: dee256141e588202061885354d7669ee2a5bb1ce99a57a709129031002ab13c8
4
- data.tar.gz: 36b036fc2890c2710a12684f78ea36f9a2d8ae7e5f11f252973d81ae905f9e3a
3
+ metadata.gz: 9c08642e343cc49c4a282e4b8ae7741c9ecce0aa1aeaf2c345cfe1bd4c1770e4
4
+ data.tar.gz: 5e077f0ddad19fad81e7b575a473958d0ecbadf48914a37ee6885775538a7880
5
5
  SHA512:
6
- metadata.gz: b8ee38fd18865625ffdb1c9671cedbba4c780d001b47743f3b0be3657e525eb0d96c84529a9023dc6a68acc6507df1646ca712f4c26dd47df8caadc174c66aa3
7
- data.tar.gz: 453471063d91beecf588b590008b37546a36b035fed4065499b87f4ef6182ea8fd2a551fcc124f88f1ee07a1ec4df501bfbbafa607a03ea05d1ca28925f5f7c9
6
+ metadata.gz: 0106dd32bbd48209be6aae488811d589266b5c485bb05bd4da483bf757bc9469933820472445c0fdd807d9c7cde21edf5e36db5a83f9f61dbbc38fbe5d523855
7
+ data.tar.gz: 1f534e4b5bc44dd6f532897042cd53d6385c1e55578281fe10172235ca5695dfa5f5acb2b5dc14849946f47256e5eda69f375f6d0e54163e7d2f291aa9f4f83c
data/README.md CHANGED
@@ -134,9 +134,7 @@ Tramway provides **convenient** form objects for Rails applications. List proper
134
134
  class UserForm < Tramway::BaseForm
135
135
  properties :email, :password, :first_name, :last_name, :phone
136
136
 
137
- def password=(value)
138
- object.password = value if value.present?
139
- end
137
+ normalizes :email, ->(value) { value.strip.downcase }
140
138
  end
141
139
  ```
142
140
 
@@ -249,15 +247,35 @@ class Admin::UsersController < Admin::ApplicationController
249
247
  end
250
248
  ```
251
249
 
250
+ ### Normalizes
251
+
252
+ Tramway Form supports `normalizes` method. It's almost the same [as in Rails](https://edgeapi.rubyonrails.org/classes/ActiveRecord/Normalization.html)
253
+
254
+ ```ruby
255
+ class UserForm < Tramway::BaseForme
256
+ properties :email, :first_name, :last_name
257
+
258
+ normalizes :email, with: ->(value) { value.strip.downcase }
259
+ normalizes :first_name, :last_name, with: ->(value) { value.strip }
260
+ end
261
+ ```
262
+
263
+ `normalizes` method arguments:
264
+ * `*properties` - collection of properties that will be normalized
265
+ * `with:` - a proc with a normalization
266
+ * `apply_on_nil` - by default is `false`. When `true` Tramway Form applies normalization on `nil` values
267
+
252
268
  ### Form inheritance
253
269
 
254
- Tramway Form supports inheritance of `properties`
270
+ Tramway Form supports inheritance of `properties` and `normalizations`
255
271
 
256
272
  **Example**
257
273
 
258
274
  ```ruby
259
275
  class UserForm < TramwayForm
260
276
  properties :email, :password
277
+
278
+ normalizes :email, with: ->(value) { value.strip.downcase }
261
279
  end
262
280
 
263
281
  class AdminForm < UserForm
@@ -265,6 +283,7 @@ class AdminForm < UserForm
265
283
  end
266
284
 
267
285
  AdminForm.properties # returns [:email, :password, :permissions]
286
+ AdminForm.normalizations # contains the normalization of :email
268
287
  ```
269
288
 
270
289
  ### Make flexible and extendable forms
@@ -274,12 +293,7 @@ Tramway Form properties are not mapped to a model. You're able to make extended
274
293
  *app/forms/user_form.rb*
275
294
  ```ruby
276
295
  class UserForm < Tramway::BaseForm
277
- properties :email, :password, :full_name
278
-
279
- # RULE: in case password is empty, don't save
280
- def password=(value)
281
- object.password = value if value.present?
282
- end
296
+ properties :email, :full_name
283
297
 
284
298
  # EXTENDED FIELD: full name
285
299
  def full_name=(value)
@@ -1,10 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # :reek:ClassVariable { enabled: false }
3
+ require 'tramway/forms/properties'
4
+ require 'tramway/forms/normalizations'
5
+
4
6
  module Tramway
5
7
  # Provides form object for Tramway
6
8
  #
7
9
  class BaseForm
10
+ include Tramway::Forms::Properties
11
+ include Tramway::Forms::Normalizations
12
+
8
13
  attr_reader :object
9
14
 
10
15
  %i[model_name to_key to_model errors attributes].each do |method_name|
@@ -19,39 +24,11 @@ module Tramway
19
24
 
20
25
  class << self
21
26
  def inherited(subclass)
22
- subclass.instance_variable_set(:@properties, [])
27
+ __initialize_properties subclass
28
+ __initialize_normalizations subclass
23
29
 
24
30
  super
25
31
  end
26
-
27
- def property(attribute)
28
- @properties << attribute
29
-
30
- delegate attribute, to: :object
31
- end
32
-
33
- def properties(*attributes)
34
- attributes.any? ? __set_properties(attributes) : __properties
35
- end
36
-
37
- def __set_properties(attributes)
38
- attributes.each do |attribute|
39
- property(attribute)
40
- end
41
- end
42
-
43
- def __properties
44
- (__ancestor_properties + @properties).uniq
45
- end
46
-
47
- # :reek:ManualDispatch { enabled: false }
48
- def __ancestor_properties(klass = superclass)
49
- superklass = klass.superclass
50
-
51
- return [] unless superklass.respond_to?(:properties)
52
-
53
- klass.properties + __ancestor_properties(superklass)
54
- end
55
32
  end
56
33
 
57
34
  def submit(params)
@@ -85,9 +62,7 @@ module Tramway
85
62
  private
86
63
 
87
64
  def __submit(params)
88
- self.class.properties.each do |attribute|
89
- public_send("#{attribute}=", params[attribute]) if params.keys.include? attribute.to_s
90
- end
65
+ __apply_properties __apply_normalizations params
91
66
  end
92
67
 
93
68
  def __object
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tramway
4
+ module Forms
5
+ # This is the same `normalizes` feature like in Rails
6
+ # https://api.rubyonrails.org/v7.1/classes/ActiveRecord/Normalization/ClassMethods.html#method-i-normalizes
7
+ module Normalizations
8
+ # A collection of methods that would be using in users forms
9
+ module ClassMethods
10
+ # :reek:BooleanParameter { enabled: false }
11
+ def normalizes(*attributes, with:, apply_to_nil: false)
12
+ attributes.each do |attribute|
13
+ @normalizations.merge!(attribute => { proc: with, apply_to_nil: })
14
+ end
15
+ end
16
+
17
+ def normalizations
18
+ __ancestor_normalizations.merge(@normalizations)
19
+ end
20
+
21
+ # :reek:ManualDispatch { enabled: false }
22
+ def __ancestor_normalizations(klass = superclass)
23
+ superklass = klass.superclass
24
+
25
+ return {} unless superklass.respond_to?(:normalizations)
26
+
27
+ klass.normalizations.merge!(__ancestor_normalizations(superklass))
28
+ end
29
+
30
+ # :reek:UtilityFunction { enabled: false }
31
+ def __initialize_normalizations(subclass)
32
+ subclass.instance_variable_set(:@normalizations, {})
33
+ end
34
+ end
35
+
36
+ def self.included(base)
37
+ base.extend ClassMethods
38
+ end
39
+
40
+ def __apply_normalizations(params)
41
+ self.class.normalizations.reduce(params) do |hash, (attribute, normalization)|
42
+ if hash.key?(attribute) || normalization[:apply_to_nil]
43
+ hash.merge(attribute => instance_exec(hash[attribute], &normalization[:proc]))
44
+ else
45
+ hash
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tramway
4
+ module Forms
5
+ # This is `properties`. The main feature of Tramway Form
6
+ module Properties
7
+ # A collection of methods that would be using in users forms
8
+ module ClassMethods
9
+ def property(attribute)
10
+ @properties << attribute
11
+
12
+ delegate attribute, to: :object
13
+ end
14
+
15
+ def properties(*attributes)
16
+ attributes.any? ? __set_properties(attributes) : __properties
17
+ end
18
+
19
+ def __set_properties(attributes)
20
+ attributes.each do |attribute|
21
+ property(attribute)
22
+ end
23
+ end
24
+
25
+ def __properties
26
+ (__ancestor_properties + @properties).uniq
27
+ end
28
+
29
+ # :reek:ManualDispatch { enabled: false }
30
+ def __ancestor_properties(klass = superclass)
31
+ superklass = klass.superclass
32
+
33
+ return [] unless superklass.respond_to?(:properties)
34
+
35
+ klass.properties + __ancestor_properties(superklass)
36
+ end
37
+
38
+ # :reek:UtilityFunction { enabled: false }
39
+ def __initialize_properties(subclass)
40
+ subclass.instance_variable_set(:@properties, [])
41
+ end
42
+ end
43
+
44
+ def self.included(base)
45
+ base.extend ClassMethods
46
+ end
47
+
48
+ def __apply_properties(params)
49
+ self.class.properties.each do |attribute|
50
+ public_send("#{attribute}=", params[attribute]) if params.key?(attribute)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tramway
4
- VERSION = '0.4.1'
4
+ VERSION = '0.4.2'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tramway
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - kalashnikovisme
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-02-05 00:00:00.000000000 Z
12
+ date: 2024-02-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: dry-struct
@@ -126,6 +126,8 @@ files:
126
126
  - lib/tramway/decorators/collection_decorator.rb
127
127
  - lib/tramway/engine.rb
128
128
  - lib/tramway/forms/class_helper.rb
129
+ - lib/tramway/forms/normalizations.rb
130
+ - lib/tramway/forms/properties.rb
129
131
  - lib/tramway/helpers/decorate_helper.rb
130
132
  - lib/tramway/helpers/form_helper.rb
131
133
  - lib/tramway/helpers/navbar_helper.rb