application_form 0.4.0 → 0.5.0

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: 05c6c488f4f25253c2fb3889eda3776207218a8a1bfb7101b18e9fc38fc5e663
4
- data.tar.gz: e8c073b39558f58391202b6d7353cc4be57e7c4df01987f31b1b624012fd010f
3
+ metadata.gz: d4e7f93eb4164ad8f2c1d57bc2b4ddb6fa0a2f2ccfcd198c8426d2835c7403dd
4
+ data.tar.gz: b8c36375600c846355f758a76350719aa46eef33c2c1d0acdd1c7d33d03a3015
5
5
  SHA512:
6
- metadata.gz: e174c55c53544fd420808519c705f546fe166a44965c279a09ac25ccbd52c47e09329c06031aa3f1e143987400678322f870fa5736717f68c7397f7579097b86
7
- data.tar.gz: d1f64700776c503711dc40a6ee4530963058cac534bfd49473a5567c01b2bda117b375f223eeedb434196ee3fb2275ca35db7ad6c165f7ee3da14138383f6552
6
+ metadata.gz: 5c729d4c8aedca0ecfcfc8282573d8ba2fbae16ac63bde9c829c81426c9ce2c58e4963ba80ecb2640a5213dd9f16760084d6f8bb9b30c93ce4ce2509ba78a285
7
+ data.tar.gz: 7544e013f81ea4e137d9b2e2a2949f541a9636cf2dd6a873253b6f89b28a87619d0b2174e9f8344964194761a81c228d36fd201d5294228fb7f5e8ef03148d0d
data/Makefile CHANGED
@@ -16,4 +16,7 @@ release:
16
16
  build:
17
17
  bundle exec rake build
18
18
 
19
+ push:
20
+ git push origin master
21
+
19
22
  .PHONY: test
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
- ### Example
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.
@@ -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: too many side effects if it is enabled
28
- # examples: form names, translations
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ApplicationForm
4
- VERSION = '0.4.0'
4
+ VERSION = '0.5.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: application_form
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kirill Mokevnin