application_form 0.4.0 → 0.5.3
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/Makefile +3 -0
- data/README.md +52 -2
- data/lib/application_form.rb +30 -3
- data/lib/application_form/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: b81f5d6a05cf8fcfabc3714481407e04d5ee752c6dced927000764de369b7172
|
4
|
+
data.tar.gz: e72b208fadad3073246fd8feb0819af6efefa87738930d7cab21e65913da423f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0cff5090a0feb65b5d2f243262f8679b47478a3407e8a957690f7d182ff45ecbe71292be1fd7d27af0558cb8a79182dd938c161697f1002095f5d3dbd99263ae
|
7
|
+
data.tar.gz: 290f830403a64539fc3f0bf7c9119ae3c0c9aca4627d4aa2bb363179064f2330d61de204a9feaf7071fca1b3e7f980fc32dfb01ed3423cfb4b70de271c56e2d5
|
data/Makefile
CHANGED
data/README.md
CHANGED
@@ -41,7 +41,7 @@ or with namespace model
|
|
41
41
|
|
42
42
|
$ rails g application_form:form admin_post --model=blog/post
|
43
43
|
|
44
|
-
###
|
44
|
+
### Basic usage
|
45
45
|
|
46
46
|
```ruby
|
47
47
|
# app/forms/user_sign_up_form.rb
|
@@ -66,13 +66,63 @@ class UserSignUpForm < User
|
|
66
66
|
end
|
67
67
|
```
|
68
68
|
|
69
|
-
|
69
|
+
```
|
70
|
+
form = UserSignUpForm.new(user_params)
|
71
|
+
form.valid?
|
72
|
+
```
|
73
|
+
|
74
|
+
### Usage with `becomes`
|
75
|
+
|
76
|
+
In some cases it is necessary to use ActiveRecord object directly without form. For such cases conveniently to use method `becomes()` (built-in ActiveRecord):
|
70
77
|
|
71
78
|
```ruby
|
72
79
|
user = User.find(params[:id])
|
73
80
|
form = user.becomes(UserSignUpForm)
|
74
81
|
```
|
75
82
|
|
83
|
+
### Checks
|
84
|
+
|
85
|
+
Checks are build on top of Rails validations. They are semantically separated from validations, because we treat them as business logic checks, not as data validation.
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
class ReservationCreateForm < Reservation
|
89
|
+
include ApplicationForm
|
90
|
+
|
91
|
+
permit :user_id, :vehicle_id, :start_at, :end_at, :pickup_location_id, :return_location_id
|
92
|
+
|
93
|
+
check :max_number_of_reservations_reached, ->(form) { !form.user&.reservations_limit_reached? }
|
94
|
+
check :car_is_on_maintenance, ->(form) { form.vehicle&.reservable? }
|
95
|
+
end
|
96
|
+
|
97
|
+
# In controller:
|
98
|
+
form = ReservationCreateForm.new(prepared_params)
|
99
|
+
|
100
|
+
if form.checks_passed?
|
101
|
+
# ...
|
102
|
+
else
|
103
|
+
render_error!(form.first_failed_check) # form.first_failed_check returns "reservation.error.max_number_of_reservations_reached"
|
104
|
+
end
|
105
|
+
```
|
106
|
+
|
107
|
+
You can also assign check to a specific field:
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
check :end_at_must_be_greater_then_start_at, ->(form) { form.end_at > form.start_at }, :end_at
|
111
|
+
```
|
112
|
+
|
113
|
+
In this case it will work as a regular validation.
|
114
|
+
|
115
|
+
### `assign_attrs`
|
116
|
+
|
117
|
+
It works as regular `assign_attributes` but it also returns the object, so that you can chain it:
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
form = current_user.becomes(UserApplyReferralProgramForm)
|
121
|
+
.assign_attrs(registration_referral_code: referral_code)
|
122
|
+
```
|
123
|
+
|
124
|
+
It is a usual pattern when you use for in `#update` action.
|
125
|
+
|
76
126
|
## Development
|
77
127
|
|
78
128
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/application_form.rb
CHANGED
@@ -24,9 +24,8 @@ module ApplicationForm
|
|
24
24
|
module ClassMethods
|
25
25
|
delegate :sti_name, to: :superclass
|
26
26
|
delegate :human_attribute_name, to: :superclass
|
27
|
-
# NOTE:
|
28
|
-
|
29
|
-
# delegate :name, to: :superclass
|
27
|
+
# NOTE: Controvertial thing. More details: https://github.com/Hexlet/active_form_model/issues/10
|
28
|
+
delegate :name, to: :superclass
|
30
29
|
|
31
30
|
def permit(*args)
|
32
31
|
@_permitted_args = args
|
@@ -35,6 +34,16 @@ module ApplicationForm
|
|
35
34
|
def _permitted_args
|
36
35
|
@_permitted_args || (superclass.respond_to?(:_permitted_args) && superclass._permitted_args) || []
|
37
36
|
end
|
37
|
+
|
38
|
+
def check(key, block, field = :base)
|
39
|
+
validate do |form|
|
40
|
+
if !block.call(form)
|
41
|
+
entity_name = self.class.superclass.to_s.tableize.split('/').last.singularize
|
42
|
+
full_key = "#{entity_name}.errors.#{key}"
|
43
|
+
form.add_error_key(field, full_key)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
38
47
|
end
|
39
48
|
|
40
49
|
def update(attrs = {})
|
@@ -55,4 +64,22 @@ module ApplicationForm
|
|
55
64
|
def permit_attrs(attrs)
|
56
65
|
attrs.respond_to?(:permit) ? attrs.send(:permit, self.class._permitted_args) : attrs
|
57
66
|
end
|
67
|
+
|
68
|
+
def first_error_message
|
69
|
+
errors&.full_messages&.first
|
70
|
+
end
|
71
|
+
|
72
|
+
def checks_passed?
|
73
|
+
valid?
|
74
|
+
end
|
75
|
+
|
76
|
+
def first_failed_check
|
77
|
+
errors.details[:base].first[:error].to_s
|
78
|
+
end
|
79
|
+
|
80
|
+
def assign_attrs(attrsibutes)
|
81
|
+
attrs = ActiveSupport::HashWithIndifferentAccess.new(attributes)
|
82
|
+
assign_attributes(attrs)
|
83
|
+
self
|
84
|
+
end
|
58
85
|
end
|