tramway 0.4.1 → 0.4.2

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: 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