application_form 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Makefile +3 -0
- data/README.md +44 -1
- data/lib/application_form.rb +28 -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: d4e7f93eb4164ad8f2c1d57bc2b4ddb6fa0a2f2ccfcd198c8426d2835c7403dd
|
4
|
+
data.tar.gz: b8c36375600c846355f758a76350719aa46eef33c2c1d0acdd1c7d33d03a3015
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c729d4c8aedca0ecfcfc8282573d8ba2fbae16ac63bde9c829c81426c9ce2c58e4963ba80ecb2640a5213dd9f16760084d6f8bb9b30c93ce4ce2509ba78a285
|
7
|
+
data.tar.gz: 7544e013f81ea4e137d9b2e2a2949f541a9636cf2dd6a873253b6f89b28a87619d0b2174e9f8344964194761a81c228d36fd201d5294228fb7f5e8ef03148d0d
|
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
|
@@ -73,6 +73,49 @@ user = User.find(params[:id])
|
|
73
73
|
form = user.becomes(UserSignUpForm)
|
74
74
|
```
|
75
75
|
|
76
|
+
### Checks
|
77
|
+
|
78
|
+
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.
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
class ReservationCreateForm < Reservation
|
82
|
+
include ApplicationForm
|
83
|
+
|
84
|
+
permit :user_id, :vehicle_id, :start_at, :end_at, :pickup_location_id, :return_location_id
|
85
|
+
|
86
|
+
check :max_number_of_reservations_reached, ->(form) { !form.user&.reservations_limit_reached? }
|
87
|
+
check :car_is_on_maintenance, ->(form) { form.vehicle&.reservable? }
|
88
|
+
end
|
89
|
+
|
90
|
+
# In controller:
|
91
|
+
form = ReservationCreateForm.new(prepared_params)
|
92
|
+
|
93
|
+
if form.checks_passed?
|
94
|
+
# ...
|
95
|
+
else
|
96
|
+
render_error!(form.first_failed_check) # form.first_failed_check returns "max_number_of_reservations_reached"
|
97
|
+
end
|
98
|
+
```
|
99
|
+
|
100
|
+
You can also attach check to a specific field:
|
101
|
+
|
102
|
+
```
|
103
|
+
check :end_at_must_be_greater_then_start_at, ->(form) { form.end_at > form.start_at }, :end_at
|
104
|
+
```
|
105
|
+
|
106
|
+
In this case it will work as a regular validation.
|
107
|
+
|
108
|
+
### `assign_atrs`
|
109
|
+
|
110
|
+
It works as regular `assign_attributes` but it also returns the object, so that you can chain it:
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
form = current_user.becomes(UserApplyReferralProgramForm)
|
114
|
+
.assign_attrs(registration_referral_code: referral_code)
|
115
|
+
```
|
116
|
+
|
117
|
+
It is a usual pattern when you use for in `#update` action.
|
118
|
+
|
76
119
|
## Development
|
77
120
|
|
78
121
|
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,15 @@ 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(name, block, field = :base)
|
39
|
+
validate do |form|
|
40
|
+
if !block.call(form)
|
41
|
+
key = "#{self.class.table_name.singularize}.errors.#{name}"
|
42
|
+
form.add_error_key(field, key)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
38
46
|
end
|
39
47
|
|
40
48
|
def update(attrs = {})
|
@@ -55,4 +63,21 @@ module ApplicationForm
|
|
55
63
|
def permit_attrs(attrs)
|
56
64
|
attrs.respond_to?(:permit) ? attrs.send(:permit, self.class._permitted_args) : attrs
|
57
65
|
end
|
66
|
+
|
67
|
+
def first_error_message
|
68
|
+
errors&.full_messages&.first
|
69
|
+
end
|
70
|
+
|
71
|
+
def checks_passed?
|
72
|
+
valid?
|
73
|
+
end
|
74
|
+
|
75
|
+
def first_failed_check
|
76
|
+
errors.details[:base].first[:error].to_s
|
77
|
+
end
|
78
|
+
|
79
|
+
def assign_attrs(attrs)
|
80
|
+
assign_attributes(attrs)
|
81
|
+
self
|
82
|
+
end
|
58
83
|
end
|