optimism 0.4.2 → 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: 8966741ac69e6f62196d1ea78a71a30dda97fa56e6618fb844a829a5d8d93008
4
- data.tar.gz: 5f7e64c28e697af5dd3a782549abf6a4872870f7bab9833868ed196a251bc806
3
+ metadata.gz: 9519a511dec44dd176cdd2f1f13ba50b31846cc9f9247088b821d3117728c052
4
+ data.tar.gz: 26acc98ea3fbd2fafec358ecd007b7258518b2cc75e4c387b16e7106771a2e91
5
5
  SHA512:
6
- metadata.gz: 936c07c2d033fc9d0f932cb31ef073a62a919cc53c635b14b896520d387c4ba8beaa94348e3b67a42786aca948fd0f3760a80530d90f874099db7d177d61bd47
7
- data.tar.gz: 8526dc93dd499644f9ebcf63ea3bb3fd24ff672a8ea7579518900800a2738b40cfefb3b96e9de228cb5e97ed718f05c6064871579487c49229e9288309d63a1a
6
+ metadata.gz: 7294ff7de16b9119b348af7db1e29747747cc968546ea5610e2463cbe8f72804412a36b3f73a4eafc4c49d72f38d59b4765e0c0e824867f786e7886884615728
7
+ data.tar.gz: ac8eef02349c7cea595bfa4235609ebe4e33ff6e0fcc28599a887667cc9daee584a76ef38b02e59eac16caab629ffe1f2474945252af6f3679d723076835369d
data/Gemfile.lock CHANGED
@@ -2,67 +2,67 @@ PATH
2
2
  remote: .
3
3
  specs:
4
4
  optimism (0.3.5)
5
- cable_ready (>= 4)
5
+ cable_ready (>= 4.4.6)
6
6
  rack (~> 2.0)
7
7
  rails (>= 6, >= 5.2)
8
8
 
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- actioncable (6.1.0)
13
- actionpack (= 6.1.0)
14
- activesupport (= 6.1.0)
12
+ actioncable (6.1.4.1)
13
+ actionpack (= 6.1.4.1)
14
+ activesupport (= 6.1.4.1)
15
15
  nio4r (~> 2.0)
16
16
  websocket-driver (>= 0.6.1)
17
- actionmailbox (6.1.0)
18
- actionpack (= 6.1.0)
19
- activejob (= 6.1.0)
20
- activerecord (= 6.1.0)
21
- activestorage (= 6.1.0)
22
- activesupport (= 6.1.0)
17
+ actionmailbox (6.1.4.1)
18
+ actionpack (= 6.1.4.1)
19
+ activejob (= 6.1.4.1)
20
+ activerecord (= 6.1.4.1)
21
+ activestorage (= 6.1.4.1)
22
+ activesupport (= 6.1.4.1)
23
23
  mail (>= 2.7.1)
24
- actionmailer (6.1.0)
25
- actionpack (= 6.1.0)
26
- actionview (= 6.1.0)
27
- activejob (= 6.1.0)
28
- activesupport (= 6.1.0)
24
+ actionmailer (6.1.4.1)
25
+ actionpack (= 6.1.4.1)
26
+ actionview (= 6.1.4.1)
27
+ activejob (= 6.1.4.1)
28
+ activesupport (= 6.1.4.1)
29
29
  mail (~> 2.5, >= 2.5.4)
30
30
  rails-dom-testing (~> 2.0)
31
- actionpack (6.1.0)
32
- actionview (= 6.1.0)
33
- activesupport (= 6.1.0)
31
+ actionpack (6.1.4.1)
32
+ actionview (= 6.1.4.1)
33
+ activesupport (= 6.1.4.1)
34
34
  rack (~> 2.0, >= 2.0.9)
35
35
  rack-test (>= 0.6.3)
36
36
  rails-dom-testing (~> 2.0)
37
37
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
38
- actiontext (6.1.0)
39
- actionpack (= 6.1.0)
40
- activerecord (= 6.1.0)
41
- activestorage (= 6.1.0)
42
- activesupport (= 6.1.0)
38
+ actiontext (6.1.4.1)
39
+ actionpack (= 6.1.4.1)
40
+ activerecord (= 6.1.4.1)
41
+ activestorage (= 6.1.4.1)
42
+ activesupport (= 6.1.4.1)
43
43
  nokogiri (>= 1.8.5)
44
- actionview (6.1.0)
45
- activesupport (= 6.1.0)
44
+ actionview (6.1.4.1)
45
+ activesupport (= 6.1.4.1)
46
46
  builder (~> 3.1)
47
47
  erubi (~> 1.4)
48
48
  rails-dom-testing (~> 2.0)
49
49
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
50
- activejob (6.1.0)
51
- activesupport (= 6.1.0)
50
+ activejob (6.1.4.1)
51
+ activesupport (= 6.1.4.1)
52
52
  globalid (>= 0.3.6)
53
- activemodel (6.1.0)
54
- activesupport (= 6.1.0)
55
- activerecord (6.1.0)
56
- activemodel (= 6.1.0)
57
- activesupport (= 6.1.0)
58
- activestorage (6.1.0)
59
- actionpack (= 6.1.0)
60
- activejob (= 6.1.0)
61
- activerecord (= 6.1.0)
62
- activesupport (= 6.1.0)
63
- marcel (~> 0.3.1)
64
- mimemagic (~> 0.3.2)
65
- activesupport (6.1.0)
53
+ activemodel (6.1.4.1)
54
+ activesupport (= 6.1.4.1)
55
+ activerecord (6.1.4.1)
56
+ activemodel (= 6.1.4.1)
57
+ activesupport (= 6.1.4.1)
58
+ activestorage (6.1.4.1)
59
+ actionpack (= 6.1.4.1)
60
+ activejob (= 6.1.4.1)
61
+ activerecord (= 6.1.4.1)
62
+ activesupport (= 6.1.4.1)
63
+ marcel (~> 1.0.0)
64
+ mini_mime (>= 1.1.0)
65
+ activesupport (6.1.4.1)
66
66
  concurrent-ruby (~> 1.0, >= 1.0.2)
67
67
  i18n (>= 1.6, < 2)
68
68
  minitest (>= 5.1)
@@ -70,32 +70,34 @@ GEM
70
70
  zeitwerk (~> 2.3)
71
71
  ast (2.4.0)
72
72
  builder (3.2.4)
73
- cable_ready (4.4.5)
73
+ cable_ready (4.5.0)
74
74
  rails (>= 5.2)
75
+ thread-local (>= 1.1.0)
75
76
  coderay (1.1.2)
76
- concurrent-ruby (1.1.7)
77
+ concurrent-ruby (1.1.9)
77
78
  crass (1.0.6)
78
79
  erubi (1.10.0)
79
- globalid (0.4.2)
80
- activesupport (>= 4.2.0)
81
- i18n (1.8.5)
80
+ globalid (0.5.2)
81
+ activesupport (>= 5.0)
82
+ i18n (1.8.10)
82
83
  concurrent-ruby (~> 1.0)
83
84
  jaro_winkler (1.5.4)
84
- loofah (2.8.0)
85
+ loofah (2.12.0)
85
86
  crass (~> 1.0.2)
86
87
  nokogiri (>= 1.5.9)
87
88
  mail (2.7.1)
88
89
  mini_mime (>= 0.1.1)
89
- marcel (0.3.3)
90
- mimemagic (~> 0.3.2)
90
+ marcel (1.0.1)
91
91
  method_source (0.9.2)
92
- mimemagic (0.3.5)
93
- mini_mime (1.0.2)
94
- mini_portile2 (2.4.0)
95
- minitest (5.14.2)
96
- nio4r (2.5.4)
97
- nokogiri (1.10.10-x64-mingw32)
98
- mini_portile2 (~> 2.4.0)
92
+ mini_mime (1.1.1)
93
+ mini_portile2 (2.6.1)
94
+ minitest (5.14.4)
95
+ nio4r (2.5.8)
96
+ nokogiri (1.12.3)
97
+ mini_portile2 (~> 2.6.1)
98
+ racc (~> 1.4)
99
+ nokogiri (1.12.3-x64-mingw32)
100
+ racc (~> 1.4)
99
101
  parallel (1.19.1)
100
102
  parser (2.7.0.2)
101
103
  ast (~> 2.4.0)
@@ -104,34 +106,35 @@ GEM
104
106
  method_source (~> 0.9.0)
105
107
  pry-nav (0.3.0)
106
108
  pry (>= 0.9.10, < 0.13.0)
109
+ racc (1.5.2)
107
110
  rack (2.2.3)
108
111
  rack-test (1.1.0)
109
112
  rack (>= 1.0, < 3)
110
- rails (6.1.0)
111
- actioncable (= 6.1.0)
112
- actionmailbox (= 6.1.0)
113
- actionmailer (= 6.1.0)
114
- actionpack (= 6.1.0)
115
- actiontext (= 6.1.0)
116
- actionview (= 6.1.0)
117
- activejob (= 6.1.0)
118
- activemodel (= 6.1.0)
119
- activerecord (= 6.1.0)
120
- activestorage (= 6.1.0)
121
- activesupport (= 6.1.0)
113
+ rails (6.1.4.1)
114
+ actioncable (= 6.1.4.1)
115
+ actionmailbox (= 6.1.4.1)
116
+ actionmailer (= 6.1.4.1)
117
+ actionpack (= 6.1.4.1)
118
+ actiontext (= 6.1.4.1)
119
+ actionview (= 6.1.4.1)
120
+ activejob (= 6.1.4.1)
121
+ activemodel (= 6.1.4.1)
122
+ activerecord (= 6.1.4.1)
123
+ activestorage (= 6.1.4.1)
124
+ activesupport (= 6.1.4.1)
122
125
  bundler (>= 1.15.0)
123
- railties (= 6.1.0)
126
+ railties (= 6.1.4.1)
124
127
  sprockets-rails (>= 2.0.0)
125
128
  rails-dom-testing (2.0.3)
126
129
  activesupport (>= 4.2.0)
127
130
  nokogiri (>= 1.6)
128
- rails-html-sanitizer (1.3.0)
131
+ rails-html-sanitizer (1.4.2)
129
132
  loofah (~> 2.3)
130
- railties (6.1.0)
131
- actionpack (= 6.1.0)
132
- activesupport (= 6.1.0)
133
+ railties (6.1.4.1)
134
+ actionpack (= 6.1.4.1)
135
+ activesupport (= 6.1.4.1)
133
136
  method_source
134
- rake (>= 0.8.7)
137
+ rake (>= 0.13)
135
138
  thor (~> 1.0)
136
139
  rainbow (3.0.0)
137
140
  rake (13.0.1)
@@ -157,11 +160,12 @@ GEM
157
160
  rubocop-performance (~> 1.5.1)
158
161
  standardrb (1.0.0)
159
162
  standard
160
- thor (1.0.1)
163
+ thor (1.1.0)
164
+ thread-local (1.1.0)
161
165
  tzinfo (2.0.4)
162
166
  concurrent-ruby (~> 1.0)
163
167
  unicode-display_width (1.6.1)
164
- websocket-driver (0.7.3)
168
+ websocket-driver (0.7.5)
165
169
  websocket-extensions (>= 0.1.0)
166
170
  websocket-extensions (0.1.5)
167
171
  zeitwerk (2.4.2)
data/lib/optimism/rake.rb CHANGED
@@ -16,7 +16,7 @@ task :"optimism:install" do
16
16
  $stderr.puts "=> [ skipping ] #{channel[:app_path]} already exists"
17
17
  else
18
18
  FileUtils.cp(File.expand_path(channel[:template_path], __dir__), "./#{channel[:app_path]}")
19
- $stderr.puts "=> #{channel[:app_path]} created"
19
+ $stdout.puts "=> #{channel[:app_path]} created"
20
20
  end
21
21
  end
22
22
  end
@@ -1,3 +1,3 @@
1
1
  module Optimism
2
- VERSION = "0.4.2"
2
+ VERSION = "0.5.0"
3
3
  end
data/lib/optimism.rb CHANGED
@@ -21,7 +21,7 @@ module Optimism
21
21
  yield self
22
22
  end
23
23
 
24
- def broadcast_errors(model, attributes)
24
+ def broadcast_errors(model, attributes, reverse_attributes_for: [])
25
25
  return unless model&.errors&.messages
26
26
  resource = ActiveModel::Naming.param_key(model)
27
27
  form_selector, submit_selector = Optimism.form_selector.sub("RESOURCE", resource), Optimism.submit_selector.sub("RESOURCE", resource)
@@ -36,7 +36,7 @@ module Optimism
36
36
  raise Exception.new "attributes must be a Hash (Parameters, Indifferent or standard), Array, Symbol or String"
37
37
  end
38
38
  model.valid? if model.errors.empty?
39
- process_resource(model, attributes, [resource])
39
+ process_resource(model, attributes, [resource], reverse_attributes_for: reverse_attributes_for)
40
40
  if model.errors.any?
41
41
  CableReady::Channels.instance[Optimism.channel_proc[self]].dispatch_event(name: "optimism:form:invalid", detail: {resource: resource}) if Optimism.emit_events
42
42
  CableReady::Channels.instance[Optimism.channel_proc[self]].add_css_class(selector: form_selector, name: Optimism.form_class) if Optimism.form_class.present?
@@ -50,11 +50,12 @@ module Optimism
50
50
  head :ok if defined?(head)
51
51
  end
52
52
 
53
- def process_resource(model, attributes, ancestry)
53
+ def process_resource(model, attributes, ancestry, reverse_attributes_for: [])
54
54
  attributes.keys.each do |attribute|
55
55
  if attribute.ends_with?("_attributes")
56
56
  resource = attribute[0..-12]
57
57
  association = model.send(resource.to_sym)
58
+ association = association.reverse if reverse_attributes_for.include?(resource.to_sym)
58
59
  if association.respond_to? :each_with_index
59
60
  association.each_with_index do |nested, index|
60
61
  process_resource(nested, attributes[attribute][index.to_s], ancestry + [resource, index]) if attributes[attribute].key?(index.to_s)
@@ -76,15 +77,22 @@ module Optimism
76
77
  resource += "_#{ancestry.shift}_attributes_#{ancestry.shift}" until ancestry.empty?
77
78
  end
78
79
  container_selector, error_selector = Optimism.container_selector.sub("RESOURCE", resource).sub("ATTRIBUTE", attribute), Optimism.error_selector.sub("RESOURCE", resource).sub("ATTRIBUTE", attribute)
79
- if model.errors.any? && model.errors.messages.map(&:first).include?(attribute.to_sym)
80
- message = "#{model.errors.full_message(attribute.to_sym, model.errors.messages[attribute.to_sym].first)}#{Optimism.suffix}"
81
- CableReady::Channels.instance[Optimism.channel_proc[self]].dispatch_event(name: "optimism:attribute:invalid", detail: {resource: resource, attribute: attribute, text: message}) if Optimism.emit_events
82
- CableReady::Channels.instance[Optimism.channel_proc[self]].add_css_class(selector: container_selector, name: Optimism.error_class) if Optimism.add_css
83
- CableReady::Channels.instance[Optimism.channel_proc[self]].text_content(selector: error_selector, text: message) if Optimism.inject_inline
84
- else
85
- CableReady::Channels.instance[Optimism.channel_proc[self]].dispatch_event(name: "optimism:attribute:valid", detail: {resource: resource, attribute: attribute}) if Optimism.emit_events
86
- CableReady::Channels.instance[Optimism.channel_proc[self]].remove_css_class(selector: container_selector, name: Optimism.error_class) if Optimism.add_css
87
- CableReady::Channels.instance[Optimism.channel_proc[self]].text_content(selector: error_selector, text: "") if Optimism.inject_inline
80
+ if model.errors.any?
81
+ if attribute.ends_with?("_id") && model.errors.messages.include?(attribute.delete_suffix("_id").to_sym)
82
+ model.errors.messages[attribute.delete_suffix("_id").to_sym].each do |msg|
83
+ model.errors.add(attribute.to_sym, msg)
84
+ end
85
+ end
86
+ if model.errors.messages.map(&:first).include?(attribute.to_sym)
87
+ message = "#{model.errors.full_message(attribute.to_sym, model.errors.messages[attribute.to_sym].first)}#{Optimism.suffix}"
88
+ CableReady::Channels.instance[Optimism.channel_proc[self]].dispatch_event(name: "optimism:attribute:invalid", detail: {resource: resource, attribute: attribute, text: message}) if Optimism.emit_events
89
+ CableReady::Channels.instance[Optimism.channel_proc[self]].add_css_class(selector: container_selector, name: Optimism.error_class) if Optimism.add_css
90
+ CableReady::Channels.instance[Optimism.channel_proc[self]].text_content(selector: error_selector, text: message) if Optimism.inject_inline
91
+ else
92
+ CableReady::Channels.instance[Optimism.channel_proc[self]].dispatch_event(name: "optimism:attribute:valid", detail: {resource: resource, attribute: attribute}) if Optimism.emit_events
93
+ CableReady::Channels.instance[Optimism.channel_proc[self]].remove_css_class(selector: container_selector, name: Optimism.error_class) if Optimism.add_css
94
+ CableReady::Channels.instance[Optimism.channel_proc[self]].text_content(selector: error_selector, text: "") if Optimism.inject_inline
95
+ end
88
96
  end
89
97
  end
90
98
  end
data/typical-usage.md CHANGED
@@ -27,17 +27,17 @@ Now that you have seen what Optimism can do, let's flex our muscles a bit and se
27
27
  {% endcode %}
28
28
  {% endtab %}
29
29
 
30
- {% tab title="Bootstrap 4" %}
30
+ {% tab title="Bootstrap" %}
31
31
  {% code title="app/views/posts/\_form.html.erb" %}
32
32
  ```rust
33
33
  <%= form_with(model: post, id: "posts_form") do |form| %>
34
- <%= form.container_for :name, class: "form-group" do %>
34
+ <%= form.container_for :name, class: "input-group" do %>
35
35
  <%= form.label :name %>
36
36
  <%= form.text_field :name, class: "form-control" %>
37
37
  <%= form.error_for :name, class: "small align-bottom text-danger d-none" %>
38
38
  <% end %>
39
39
 
40
- <%= form.container_for :body, class: "form-group" do %>
40
+ <%= form.container_for :body, class: "input-group" do %>
41
41
  <%= form.label :body %>
42
42
  <%= form.text_area :body, class: "form-control" %>
43
43
  <%= form.error_for :body, class: "small align-bottom text-danger d-none" %>
@@ -76,14 +76,14 @@ Here we introduce the `container_for` helper, which wraps a form element in a `d
76
76
  ```
77
77
  {% endtab %}
78
78
 
79
- {% tab title="Bootstrap 4" %}
79
+ {% tab title="Bootstrap" %}
80
80
  ```css
81
- .form-group.error > .d-none {
81
+ .input-group.error > .d-none {
82
82
  display: inline !important;
83
83
  }
84
84
 
85
- .form-group.error > input,
86
- .form-group.error > textarea {
85
+ .input-group.error > input,
86
+ .input-group.error > textarea {
87
87
  background-color: rgba(255, 239, 213, 0.7);
88
88
  }
89
89
  ```
@@ -98,5 +98,15 @@ If you assign an id to the form itself that matches the expected format - in thi
98
98
  Unfortunately, we can't automatically generate the id for the form during its own declaration. Luckily, the format is pretty easy: **resources\_form**.
99
99
  {% endhint %}
100
100
 
101
+ ## Gotchas
102
+
103
+ Optimism is a fundamentally simple library, which means that inevitably, there's going to be scenarios that require some extra consideration.
104
+
105
+ #### Radio buttons and checkboxes
106
+
107
+ Thanks to a quirk of the way certain OG form input elements work, it's possible for an unchecked element to not be included in a form's parameters. For example, if you have a set of radio buttons with no default selection, your `params` hash will not include data for it.
108
+
109
+ Make sure to use the `checkbox` helpers that Rails provides, which implement a clever hack to make sure that unchecked checkboxes produce a `false` value in your `params`.
110
+
101
111
  ![](.gitbook/assets/web_developer.svg)
102
112
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: optimism
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - leastbad
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-24 00:00:00.000000000 Z
11
+ date: 2021-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -183,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
183
183
  - !ruby/object:Gem::Version
184
184
  version: '0'
185
185
  requirements: []
186
- rubygems_version: 3.1.4
186
+ rubygems_version: 3.1.6
187
187
  signing_key:
188
188
  specification_version: 4
189
189
  summary: Drop-in Rails form validations