neewom 0.1.0 → 0.1.1

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: d0ffd96cee9a740737d32948b45474858e28444c138e8a748f457985c5029541
4
- data.tar.gz: fa6e08472a06a00da8dfda822b815031ac25a4773d0181fb91b1b2e00b365d7a
3
+ metadata.gz: d163bc5e17faec7b60144b8c445d2f21139eee4dfc12748363a2c45ee561c685
4
+ data.tar.gz: 0e2a0312d4e137a2da16e8f57c6b2a2ffe4cc1774eff5b08f7fc26b574e60ed0
5
5
  SHA512:
6
- metadata.gz: 59d8669ecadba1e83624b7edd69eeb907b9e2b2c75dad39ccfc91e02dac790dd94ee6fe80695f1e11ac32b04b0768520555e1530bc0ad113c5e3e18b83506b93
7
- data.tar.gz: e030a33140221b88e775d1db3612cb233c35e03c204885ca6d47ac9c54f44d1e1d6f4217d70c02c0262ae58c26649a955cb911ac15c0e700404053330d79fdac
6
+ metadata.gz: 4c3e74e0a21f4f542bdefece564ad601d0765bcbb1c1100ac47f16617438db68b8832acbab921e60dfda7e3db23938e64b478cb96852d928181d7882e4068a41
7
+ data.tar.gz: 8d64de3fe84c30642e6d7ed5eb6b5126926ea9f463ca4cf01f538204ba854176c36554cbc913ca7bfd3410e2c04c8ffbce32e1da28b3893ee00a8a7ecae63f95
data/.gitignore CHANGED
@@ -5,7 +5,41 @@
5
5
  /doc/
6
6
  /pkg/
7
7
  /spec/reports/
8
- /tmp/
8
+ # Ignore bundler config.
9
+ /spec/dummy/.bundle
10
+
11
+ # Ignore the default SQLite database.
12
+ /spec/dummy/db/*.sqlite3
13
+ /spec/dummy/db/*.sqlite3-*
14
+
15
+ # Ignore all logfiles and tempfiles.
16
+ /spec/dummy/log/*
17
+ /spec/dummy/tmp/*
18
+ !/spec/dummy/log/.keep
19
+ !/spec/dummy/tmp/.keep
20
+
21
+ # Ignore pidfiles, but keep the directory.
22
+ /spec/dummy/tmp/pids/*
23
+ !/spec/dummy/tmp/pids/
24
+ !/spec/dummy/tmp/pids/.keep
25
+
26
+ # Ignore uploaded files in development.
27
+ /spec/dummy/storage/*
28
+ !/spec/dummy/storage/.keep
29
+
30
+ /spec/dummy/public/assets
31
+ /spec/dummy.byebug_history
32
+
33
+ # Ignore master key for decrypting credentials and more.
34
+ /spec/dummy/config/master.key
35
+
36
+ /spec/dummy/public/packs
37
+ /spec/dummy/public/packs-test
38
+ /spec/dummy/node_modules
39
+ /spec/dummy/yarn-error.log
40
+ /spec/dummyyarn-debug.log*
41
+ /spec/dummy.yarn-integrity
42
+ /spec/dummy/tmp/
9
43
 
10
44
  # rspec failure tracking
11
45
  .rspec_status
data/Gemfile CHANGED
@@ -2,20 +2,5 @@ source "https://rubygems.org"
2
2
 
3
3
  git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
- group :development, :test do
6
- gem 'rails-dummy'
7
- gem 'pg'
8
- gem 'rails'
9
- gem 'byebug'
10
- gem 'pry'
11
- end
12
-
13
- group :test do
14
- gem 'rspec-rails'
15
- gem 'database_cleaner'
16
- gem 'simplecov'
17
- end
18
-
19
-
20
5
  # Specify your gem's dependencies in neewom.gemspec
21
6
  gemspec
data/Gemfile.lock CHANGED
@@ -6,184 +6,175 @@ PATH
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- actioncable (6.0.0)
10
- actionpack (= 6.0.0)
9
+ actioncable (6.1.3.2)
10
+ actionpack (= 6.1.3.2)
11
+ activesupport (= 6.1.3.2)
11
12
  nio4r (~> 2.0)
12
13
  websocket-driver (>= 0.6.1)
13
- actionmailbox (6.0.0)
14
- actionpack (= 6.0.0)
15
- activejob (= 6.0.0)
16
- activerecord (= 6.0.0)
17
- activestorage (= 6.0.0)
18
- activesupport (= 6.0.0)
14
+ actionmailbox (6.1.3.2)
15
+ actionpack (= 6.1.3.2)
16
+ activejob (= 6.1.3.2)
17
+ activerecord (= 6.1.3.2)
18
+ activestorage (= 6.1.3.2)
19
+ activesupport (= 6.1.3.2)
19
20
  mail (>= 2.7.1)
20
- actionmailer (6.0.0)
21
- actionpack (= 6.0.0)
22
- actionview (= 6.0.0)
23
- activejob (= 6.0.0)
21
+ actionmailer (6.1.3.2)
22
+ actionpack (= 6.1.3.2)
23
+ actionview (= 6.1.3.2)
24
+ activejob (= 6.1.3.2)
25
+ activesupport (= 6.1.3.2)
24
26
  mail (~> 2.5, >= 2.5.4)
25
27
  rails-dom-testing (~> 2.0)
26
- actionpack (6.0.0)
27
- actionview (= 6.0.0)
28
- activesupport (= 6.0.0)
29
- rack (~> 2.0)
28
+ actionpack (6.1.3.2)
29
+ actionview (= 6.1.3.2)
30
+ activesupport (= 6.1.3.2)
31
+ rack (~> 2.0, >= 2.0.9)
30
32
  rack-test (>= 0.6.3)
31
33
  rails-dom-testing (~> 2.0)
32
34
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
33
- actiontext (6.0.0)
34
- actionpack (= 6.0.0)
35
- activerecord (= 6.0.0)
36
- activestorage (= 6.0.0)
37
- activesupport (= 6.0.0)
35
+ actiontext (6.1.3.2)
36
+ actionpack (= 6.1.3.2)
37
+ activerecord (= 6.1.3.2)
38
+ activestorage (= 6.1.3.2)
39
+ activesupport (= 6.1.3.2)
38
40
  nokogiri (>= 1.8.5)
39
- actionview (6.0.0)
40
- activesupport (= 6.0.0)
41
+ actionview (6.1.3.2)
42
+ activesupport (= 6.1.3.2)
41
43
  builder (~> 3.1)
42
44
  erubi (~> 1.4)
43
45
  rails-dom-testing (~> 2.0)
44
46
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
45
- activejob (6.0.0)
46
- activesupport (= 6.0.0)
47
+ activejob (6.1.3.2)
48
+ activesupport (= 6.1.3.2)
47
49
  globalid (>= 0.3.6)
48
- activemodel (6.0.0)
49
- activesupport (= 6.0.0)
50
- activerecord (6.0.0)
51
- activemodel (= 6.0.0)
52
- activesupport (= 6.0.0)
53
- activestorage (6.0.0)
54
- actionpack (= 6.0.0)
55
- activejob (= 6.0.0)
56
- activerecord (= 6.0.0)
57
- marcel (~> 0.3.1)
58
- activesupport (6.0.0)
50
+ activemodel (6.1.3.2)
51
+ activesupport (= 6.1.3.2)
52
+ activerecord (6.1.3.2)
53
+ activemodel (= 6.1.3.2)
54
+ activesupport (= 6.1.3.2)
55
+ activestorage (6.1.3.2)
56
+ actionpack (= 6.1.3.2)
57
+ activejob (= 6.1.3.2)
58
+ activerecord (= 6.1.3.2)
59
+ activesupport (= 6.1.3.2)
60
+ marcel (~> 1.0.0)
61
+ mini_mime (~> 1.0.2)
62
+ activesupport (6.1.3.2)
59
63
  concurrent-ruby (~> 1.0, >= 1.0.2)
60
- i18n (>= 0.7, < 2)
61
- minitest (~> 5.1)
62
- tzinfo (~> 1.1)
63
- zeitwerk (~> 2.1, >= 2.1.8)
64
- builder (3.2.3)
65
- byebug (11.0.1)
66
- coderay (1.1.2)
67
- concurrent-ruby (1.1.5)
68
- crass (1.0.4)
69
- database_cleaner (1.7.0)
70
- diff-lcs (1.3)
71
- docile (1.3.2)
72
- erubi (1.8.0)
64
+ i18n (>= 1.6, < 2)
65
+ minitest (>= 5.1)
66
+ tzinfo (~> 2.0)
67
+ zeitwerk (~> 2.3)
68
+ builder (3.2.4)
69
+ byebug (11.1.3)
70
+ coderay (1.1.3)
71
+ concurrent-ruby (1.1.9)
72
+ crass (1.0.6)
73
+ diff-lcs (1.4.4)
74
+ docile (1.4.0)
75
+ erubi (1.10.0)
73
76
  globalid (0.4.2)
74
77
  activesupport (>= 4.2.0)
75
- i18n (1.6.0)
78
+ i18n (1.8.10)
76
79
  concurrent-ruby (~> 1.0)
77
- json (2.2.0)
78
- loofah (2.2.3)
80
+ loofah (2.10.0)
79
81
  crass (~> 1.0.2)
80
82
  nokogiri (>= 1.5.9)
81
83
  mail (2.7.1)
82
84
  mini_mime (>= 0.1.1)
83
- marcel (0.3.3)
84
- mimemagic (~> 0.3.2)
85
- method_source (0.9.2)
86
- mimemagic (0.3.3)
87
- mini_mime (1.0.2)
88
- mini_portile2 (2.4.0)
89
- minitest (5.11.3)
90
- nio4r (2.5.1)
91
- nokogiri (1.10.4)
92
- mini_portile2 (~> 2.4.0)
93
- pg (1.1.4)
94
- pry (0.12.2)
95
- coderay (~> 1.1.0)
96
- method_source (~> 0.9.0)
97
- rack (2.0.7)
85
+ marcel (1.0.1)
86
+ method_source (1.0.0)
87
+ mini_mime (1.0.3)
88
+ minitest (5.14.4)
89
+ nio4r (2.5.7)
90
+ nokogiri (1.11.7-x86_64-linux)
91
+ racc (~> 1.4)
92
+ pry (0.14.1)
93
+ coderay (~> 1.1)
94
+ method_source (~> 1.0)
95
+ racc (1.5.2)
96
+ rack (2.2.3)
98
97
  rack-test (1.1.0)
99
98
  rack (>= 1.0, < 3)
100
- rails (6.0.0)
101
- actioncable (= 6.0.0)
102
- actionmailbox (= 6.0.0)
103
- actionmailer (= 6.0.0)
104
- actionpack (= 6.0.0)
105
- actiontext (= 6.0.0)
106
- actionview (= 6.0.0)
107
- activejob (= 6.0.0)
108
- activemodel (= 6.0.0)
109
- activerecord (= 6.0.0)
110
- activestorage (= 6.0.0)
111
- activesupport (= 6.0.0)
112
- bundler (>= 1.3.0)
113
- railties (= 6.0.0)
99
+ rails (6.1.3.2)
100
+ actioncable (= 6.1.3.2)
101
+ actionmailbox (= 6.1.3.2)
102
+ actionmailer (= 6.1.3.2)
103
+ actionpack (= 6.1.3.2)
104
+ actiontext (= 6.1.3.2)
105
+ actionview (= 6.1.3.2)
106
+ activejob (= 6.1.3.2)
107
+ activemodel (= 6.1.3.2)
108
+ activerecord (= 6.1.3.2)
109
+ activestorage (= 6.1.3.2)
110
+ activesupport (= 6.1.3.2)
111
+ bundler (>= 1.15.0)
112
+ railties (= 6.1.3.2)
114
113
  sprockets-rails (>= 2.0.0)
115
114
  rails-dom-testing (2.0.3)
116
115
  activesupport (>= 4.2.0)
117
116
  nokogiri (>= 1.6)
118
- rails-dummy (0.1.0)
119
- railties
120
- rails-html-sanitizer (1.2.0)
121
- loofah (~> 2.2, >= 2.2.2)
122
- railties (6.0.0)
123
- actionpack (= 6.0.0)
124
- activesupport (= 6.0.0)
117
+ rails-html-sanitizer (1.3.0)
118
+ loofah (~> 2.3)
119
+ railties (6.1.3.2)
120
+ actionpack (= 6.1.3.2)
121
+ activesupport (= 6.1.3.2)
125
122
  method_source
126
123
  rake (>= 0.8.7)
127
- thor (>= 0.20.3, < 2.0)
124
+ thor (~> 1.0)
128
125
  rake (10.5.0)
129
- rspec (3.8.0)
130
- rspec-core (~> 3.8.0)
131
- rspec-expectations (~> 3.8.0)
132
- rspec-mocks (~> 3.8.0)
133
- rspec-core (3.8.2)
134
- rspec-support (~> 3.8.0)
135
- rspec-expectations (3.8.4)
126
+ rspec-core (3.10.1)
127
+ rspec-support (~> 3.10.0)
128
+ rspec-expectations (3.10.1)
136
129
  diff-lcs (>= 1.2.0, < 2.0)
137
- rspec-support (~> 3.8.0)
138
- rspec-mocks (3.8.1)
130
+ rspec-support (~> 3.10.0)
131
+ rspec-mocks (3.10.2)
139
132
  diff-lcs (>= 1.2.0, < 2.0)
140
- rspec-support (~> 3.8.0)
141
- rspec-rails (3.8.2)
142
- actionpack (>= 3.0)
143
- activesupport (>= 3.0)
144
- railties (>= 3.0)
145
- rspec-core (~> 3.8.0)
146
- rspec-expectations (~> 3.8.0)
147
- rspec-mocks (~> 3.8.0)
148
- rspec-support (~> 3.8.0)
149
- rspec-support (3.8.2)
150
- simplecov (0.17.1)
133
+ rspec-support (~> 3.10.0)
134
+ rspec-rails (5.0.1)
135
+ actionpack (>= 5.2)
136
+ activesupport (>= 5.2)
137
+ railties (>= 5.2)
138
+ rspec-core (~> 3.10)
139
+ rspec-expectations (~> 3.10)
140
+ rspec-mocks (~> 3.10)
141
+ rspec-support (~> 3.10)
142
+ rspec-support (3.10.2)
143
+ simplecov (0.21.2)
151
144
  docile (~> 1.1)
152
- json (>= 1.8, < 3)
153
- simplecov-html (~> 0.10.0)
154
- simplecov-html (0.10.2)
155
- sprockets (3.7.2)
145
+ simplecov-html (~> 0.11)
146
+ simplecov_json_formatter (~> 0.1)
147
+ simplecov-html (0.12.3)
148
+ simplecov_json_formatter (0.1.3)
149
+ sprockets (4.0.2)
156
150
  concurrent-ruby (~> 1.0)
157
151
  rack (> 1, < 3)
158
- sprockets-rails (3.2.1)
152
+ sprockets-rails (3.2.2)
159
153
  actionpack (>= 4.0)
160
154
  activesupport (>= 4.0)
161
155
  sprockets (>= 3.0.0)
162
- thor (0.20.3)
163
- thread_safe (0.3.6)
164
- tzinfo (1.2.5)
165
- thread_safe (~> 0.1)
166
- websocket-driver (0.7.1)
156
+ sqlite3 (1.4.2)
157
+ thor (1.1.0)
158
+ tzinfo (2.0.4)
159
+ concurrent-ruby (~> 1.0)
160
+ websocket-driver (0.7.4)
167
161
  websocket-extensions (>= 0.1.0)
168
- websocket-extensions (0.1.4)
169
- zeitwerk (2.1.10)
162
+ websocket-extensions (0.1.5)
163
+ zeitwerk (2.4.2)
170
164
 
171
165
  PLATFORMS
172
- ruby
166
+ x86_64-linux
173
167
 
174
168
  DEPENDENCIES
175
- bundler (~> 1.17)
169
+ bundler (~> 2.2)
176
170
  byebug
177
- database_cleaner
178
171
  neewom!
179
- pg
180
172
  pry
181
- rails
182
- rails-dummy
173
+ rails (~> 6.1.3, >= 6.1.3.2)
183
174
  rake (~> 10.0)
184
- rspec (~> 3.0)
185
175
  rspec-rails
186
176
  simplecov
177
+ sqlite3
187
178
 
188
179
  BUNDLED WITH
189
- 1.17.3
180
+ 2.2.19
data/README.md CHANGED
@@ -46,14 +46,18 @@ Copy a default form template
46
46
  <% when Neewom::AbstractField::PHONE %>
47
47
  <%= f.phone_field field.name, field.input_html %>
48
48
  <% when Neewom::AbstractField::SELECT %>
49
- <% if field.collection.present? %>
50
- <% collection = field.collection %>
51
- <% else %>
52
- <% method_params = field.collection_params.map { |method_name| public_send(method_name) } %>
53
- <% collection = field.collection_klass.constintize.public_send(field.collection_method, *method_params) %>
54
- <% end %>
55
-
56
- <% options = collection.map { |i| [i.public_send(field.label_method), i.public_send(field.value_method)] } %>
49
+ <%
50
+ options = []
51
+ collection = field.build_collection(binding)
52
+
53
+ if collection.any?
54
+ if collection.first.is_a?(Array)
55
+ options = collection
56
+ else
57
+ options = collection.map { |i| [i.public_send(field.label_method), i.public_send(field.value_method)] }
58
+ end
59
+ end
60
+ %>
57
61
 
58
62
  <%= f.select field.name, options, field.input_html %>
59
63
  <% when Neewom::AbstractField::SUBMIT %>
@@ -130,6 +134,7 @@ Neewom::AbstractForm.build(
130
134
  2. **repository_klass** (*required*) - An active record model name with configured neewom attributes
131
135
  3. **fields** (*required*) - A hash with fields config.
132
136
  4. **template** - form template name ("form" by default)
137
+ 5. **persist_submit_controls** - flag for controling submit button persistance. Need if your submit not just a button, but also a value
133
138
 
134
139
  ### Field attrbutes
135
140
 
@@ -138,11 +143,12 @@ The hash keys are also a names.
138
143
  1. **label** - Input label. By default it's `name.to_s.humanize`
139
144
  2. **input** - Field input. By default it's 'text_field'. Check the `Neewom::AbstractField::SUPPORTED_FIELDS` to get the list of supported inputs
140
145
  3. **virtual** - Boolean, true by default. Should be false if you need to store data in a real column instead of the jsonb one
141
- 4. **validations** - Hash, by default an empty one. Should be the standard rails validations
146
+ 4. **validations** - Array of Hashes, or Hash by default an empty one. Should be the standard rails validations
142
147
  5. **collection** - Collection of objects for the select input. Can not be stored to the database
143
148
  6. **label_method** - A label method for collection. Used while building options for select
144
149
  7. **value_method** - A value method for collection. Used while building options for select. It's 'id' by default
145
150
  8. **input_html** - A hash with the HTML attributes
151
+ 9. **custom_options** - A hash to provide any other additional information
146
152
 
147
153
  Another way to define a collection is to pass three params
148
154
 
@@ -188,7 +194,11 @@ end
188
194
  ### The complete controller example
189
195
 
190
196
  ```ruby
191
- class CustomController < ApplicationController
197
+ class UsersController < ApplicationController
198
+ def index
199
+ @collection = User.all.map { |user| user.neewom_view(:name, :role) }
200
+ end
201
+
192
202
  def new
193
203
  @resource = form.build_resource
194
204
  render "neewom_forms/#{form.template}"
@@ -204,6 +214,29 @@ class CustomController < ApplicationController
204
214
  end
205
215
  end
206
216
 
217
+ def edit
218
+ @resource = form.find(params[:id])
219
+
220
+ render "neewom_forms/#{form.template}"
221
+ end
222
+
223
+ def update
224
+ @resource = form.find_and_apply_inputs(params[:id], permitted_params)
225
+
226
+ if @resource.save
227
+ redirect_to root_path
228
+ else
229
+ render "neewom_forms/#{form.template}"
230
+ end
231
+ end
232
+
233
+ def destroy
234
+ @resource = form.find(params[:id])
235
+ @resource.destroy
236
+
237
+ redirect_to root_path
238
+ end
239
+
207
240
  private
208
241
 
209
242
  def permitted_params
@@ -211,12 +244,12 @@ class CustomController < ApplicationController
211
244
  end
212
245
 
213
246
  def form_url
214
- custom_index_path
247
+ @resource && @resource.persisted? ? user_path(@resource) : users_path
215
248
  end
216
249
  helper_method :form_url
217
250
 
218
251
  def form_method
219
- :post
252
+ @resource && @resource.persisted? ? :patch : :post
220
253
  end
221
254
  helper_method :form_method
222
255
 
@@ -228,6 +261,25 @@ class CustomController < ApplicationController
228
261
  name: {
229
262
  virtual: true
230
263
  },
264
+ role: {
265
+ virtual: true,
266
+ input: 'select_field',
267
+ collection: ['admin', 'quest'].map { |r| [r, r] }
268
+ },
269
+ inviter: {
270
+ virtual: true,
271
+ input: 'select_field',
272
+ collection_klass: 'User',
273
+ collection_method: :all_with_neewom,
274
+ collection_params: [:form]
275
+ },
276
+ manager: {
277
+ virtual: true,
278
+ input: 'select_field',
279
+ collection_klass: 'Managers',
280
+ collection_method: :for_user,
281
+ collection_params: [Neewom::Collection.serialize('EN'), :current_user, "some_helper(current_user)"]
282
+ },
231
283
  email: {
232
284
  virtual: false,
233
285
  input: 'email_field'
@@ -235,7 +287,7 @@ class CustomController < ApplicationController
235
287
  password: {
236
288
  virtual: false,
237
289
  input: 'password_field',
238
- validations: {presence: true, confirmation: true}
290
+ validations: [{presence: true, on: :update}, {confirmation: true, allow_blank: true }]
239
291
  },
240
292
  password_confirmation: {
241
293
  virtual: false,
@@ -252,6 +304,142 @@ class CustomController < ApplicationController
252
304
  end
253
305
  ```
254
306
 
307
+ # Reading fields
308
+
309
+ To be able to read data from the model you need to define form fields. There are several ways to do this
310
+
311
+ ```ruby
312
+ @user = User.first
313
+
314
+ # in this case you need to specify the virtual fields list
315
+ @user = @user.neewom_view(:name, :role, :some_field)
316
+
317
+ # in this case you need to specify the instance of the Neewom::AbstractForm
318
+ form = Neewom::AbstractForm.build(
319
+ id: :custom_user_form,
320
+ repository_klass: 'User',
321
+ fields: {
322
+ name: {
323
+ virtual: true
324
+ },
325
+ }
326
+ )
327
+ @user = @user.neewom(form)
328
+
329
+ # in this case you need to specify the instance of the Neewom::CustomForm
330
+ form = Neewom::CustomForm.first
331
+ @user = @user.neewom(form)
332
+
333
+ # in this case you need to specify the id of of the stored Neewom::CustomForm
334
+ form = Neewom::AbstractForm.build(
335
+ id: :custom_user_form,
336
+ repository_klass: 'User',
337
+ fields: {
338
+ name: {
339
+ virtual: true
340
+ },
341
+ }
342
+ )
343
+ form.store!
344
+ @user = @user.neewom(:custom_user_form)
345
+ ```
346
+
347
+
348
+ ## Validations
349
+
350
+ Multiple validations example
351
+
352
+ ```ruby
353
+ def form
354
+ @form ||= Neewom::AbstractForm.build(
355
+ id: :custom_user_form,
356
+ repository_klass: 'User',
357
+ fields: {
358
+ name: {
359
+ virtual: true,
360
+ validations: [
361
+ {presence: true, on: :update},
362
+ {length: { minimum: 10 }}
363
+ ]
364
+ },
365
+ }
366
+ )
367
+ end
368
+ helper_method :form
369
+ ```
370
+
371
+ ## Collections
372
+
373
+ You can build a field collection within the form object.
374
+
375
+ ```ruby
376
+ def form
377
+ @form ||= Neewom::AbstractForm.build(
378
+ id: :custom_user_form,
379
+ repository_klass: 'User',
380
+ fields: {
381
+ name: {
382
+ virtual: true,
383
+ collection: [OpenStruct.new(id: '1', name: 'Dave'), OpenStruct.new(id: '1', name: 'Bruce')]
384
+ },
385
+ }
386
+ )
387
+ end
388
+ helper_method :form
389
+ ```
390
+
391
+ Specifying custom methods also allowed
392
+
393
+ ```ruby
394
+ def form
395
+ @form ||= Neewom::AbstractForm.build(
396
+ id: :custom_user_form,
397
+ repository_klass: 'User',
398
+ fields: {
399
+ name: {
400
+ virtual: true,
401
+ collection: [OpenStruct.new(uid: '1', title: 'London'), OpenStruct.new(uid: '1', title: 'Paris')],
402
+ label_method: :title,
403
+ value_method: :uid,
404
+ },
405
+ }
406
+ )
407
+ end
408
+ helper_method :form
409
+ ```
410
+
411
+ Or you can specify the collection builder class
412
+
413
+ ```ruby
414
+ def form
415
+ @form ||= Neewom::AbstractForm.build(
416
+ id: :custom_user_form,
417
+ repository_klass: 'User',
418
+ fields: {
419
+ name: {
420
+ virtual: true,
421
+ collection_klass: 'CollectionBuilder',
422
+ collection_method: 'called_method',
423
+ collection_params: [Neewom::Colllection.serialize(42), :current_user, "some_helper(current_user)"],
424
+ },
425
+ }
426
+ )
427
+ end
428
+ helper_method :form
429
+ ```
430
+
431
+ In this example the `called_method` of the `CollectionBuilder` class (**class but not instance!**) will receive the next values:
432
+
433
+ ```ruby
434
+ [42, current_user(), some_helper(current_user())]
435
+ ```
436
+
437
+ It will use binding with eval under the hood, this is why this things works.
438
+
439
+ ## Custom field inputs
440
+
441
+ You can push new value into the `Neewom::AbstractField::SUPPORTED_FIELDS` array and then update your view to support new field
442
+
255
443
  ## Storing forms in the database.
256
444
 
257
445
  If you didn't used a `collection` in any field, you can store the form to the database.
@@ -266,6 +454,7 @@ def change
266
454
  t.string :crc32, null: false, index: { unique: true }
267
455
  t.string :repository_klass, null: false
268
456
  t.string :template, null: false
457
+ t.boolean :persist_submit_controls
269
458
 
270
459
  t.timestamps null: false
271
460
  end
@@ -283,6 +472,8 @@ def change
283
472
  t.string :label_method
284
473
  t.string :value_method
285
474
  t.string :input_html
475
+ t.string :custom_options
476
+ t.integer :order, default: 0
286
477
 
287
478
  t.timestamps null: false
288
479
  end
data/lib/neewom.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require "neewom/version"
2
2
 
3
3
  require "neewom/proxies/builders_and_finders"
4
+ require "neewom/collection"
4
5
  require "neewom/serializer"
5
6
  require "neewom/abstract_field"
6
7
  require "neewom/abstract_form"
@@ -11,7 +11,7 @@ module Neewom
11
11
  # 'radio_button_collection',
12
12
  SELECT = 'select_field',
13
13
  MULTIPLE_SELECT = 'multiple_select_field',
14
- SUBMIT = 'submit',
14
+ SUBMIT = 'submit',
15
15
  TEXTAREA = 'text_area',
16
16
  TEXT = 'text_field',
17
17
  CHECKBOX = 'checkbox',
@@ -32,10 +32,10 @@ module Neewom
32
32
  def label
33
33
  @label || name.to_s.humanize
34
34
  end
35
-
35
+
36
36
  def input
37
37
  @input || 'text_field'
38
- end
38
+ end
39
39
 
40
40
  def virtual
41
41
  @virtual.nil? ? true : @virtual
@@ -64,5 +64,11 @@ module Neewom
64
64
  def value_method
65
65
  @value_method || :id
66
66
  end
67
+
68
+ def build_collection(bind)
69
+ return collection if collection.present?
70
+
71
+ Neewom::Collection.build_for_field(self, bind)
72
+ end
67
73
  end
68
- end
74
+ end
@@ -0,0 +1,40 @@
1
+ module Neewom
2
+ class Collection
3
+ SEQ_KEY = "neewom|value|"
4
+ MOD_KEY = "|mods:"
5
+
6
+ def self.build_for_field(field, bind)
7
+ if field.collection_params.present?
8
+ method_params = field.collection_params.map do |param|
9
+ if param.start_with?(SEQ_KEY)
10
+ deserialize(param)
11
+ else
12
+ eval param.to_s, bind
13
+ end
14
+ end
15
+
16
+ field.collection_klass.constantize.public_send(field.collection_method, *method_params)
17
+ else
18
+ field.collection_klass.constantize.public_send(field.collection_method)
19
+ end
20
+ end
21
+
22
+ def self.deserialize(param)
23
+ token = param.gsub(SEQ_KEY, "")
24
+
25
+ value, mods = token.split(MOD_KEY)
26
+ value = JSON.parse(value)
27
+
28
+ value = mods.split('.').reduce(value) { |acc, mod| acc.public_send(mod) } if mods.present?
29
+
30
+ value
31
+ end
32
+
33
+ def self.serialize(value, mods="")
34
+ token = "#{SEQ_KEY}#{value.to_json}"
35
+ token += "#{MOD_KEY}#{mods}" unless mods.blank?
36
+
37
+ token
38
+ end
39
+ end
40
+ end
data/lib/neewom/model.rb CHANGED
@@ -6,39 +6,52 @@ module Neewom
6
6
  attr_accessor :neewom_form
7
7
 
8
8
  def initialize_neewom_attributes(key_or_form)
9
- data_column = self.class.neewom_attributes_column
10
-
11
- self.neewom_form =
9
+ self.neewom_form =
12
10
  case key_or_form
13
11
  when Neewom::AbstractForm
14
12
  key_or_form
15
13
  when Neewom::CustomForm
16
14
  key_or_form.to_form
17
- else
15
+ else
18
16
  Neewom::CustomForm.find_by!(key: key_or_form).to_form
19
17
  end
20
18
 
21
- neewom_form.virtual_fields.map do |field|
22
- name = field.name.to_sym
23
-
24
- singleton_class.class_eval do
25
- store_accessor data_column, name
26
- end
27
- end
19
+ initialize_neewom_view neewom_form.virtual_fields.map(&:name).map(&:to_sym)
28
20
 
29
21
  neewom_form.fields.map do |field|
30
22
  name = field.name.to_sym
31
23
  validations_config = field.validations
32
-
24
+
33
25
  singleton_class.class_eval do
34
26
  if validations_config.present?
35
- validates [name, validations_config].flatten
27
+ Array(validations_config).each do |config|
28
+ next if config.blank?
29
+
30
+ validates *[name, config]
31
+ end
36
32
  end
37
33
  end
38
34
  end
39
- end
35
+
36
+ self
37
+ end
38
+ alias_method :neewom, :initialize_neewom_attributes
39
+
40
+ def initialize_neewom_view(*names)
41
+ data_column = self.class.neewom_attributes_column
42
+
43
+ names.each do |name|
44
+ singleton_class.class_eval do
45
+ store_accessor data_column, name
46
+ end
47
+ end
48
+
49
+ self
50
+ end
51
+ alias_method :neewom_view, :initialize_neewom_view
40
52
  end
41
53
 
54
+
42
55
  module ClassMethods
43
56
  attr_accessor :neewom_attributes_column
44
57
 
@@ -48,4 +61,4 @@ module Neewom
48
61
  end
49
62
  end
50
63
  end
51
- end
64
+ end
@@ -5,14 +5,14 @@ module Neewom
5
5
  resource = repository_klass.constantize.new
6
6
  apply_inputs(resource, controller_params, initial_values: initial_values)
7
7
  end
8
-
8
+
9
9
  def apply_inputs(resource, controller_params, initial_values: {})
10
10
  return unless resource.present?
11
11
 
12
- resource.initialize_neewom_attributes(self) if resource.respond_to?(:initialize_neewom_attributes)
12
+ resource.initialize_neewom_attributes(self) if resource.respond_to?(:initialize_neewom_attributes)
13
13
 
14
14
  if controller_params.present?
15
- params = permit_params(controller_params)
15
+ params = controller_params
16
16
 
17
17
  initial_values.each do |field, value|
18
18
  if resource.respond_to?(:"#{field}=")
@@ -22,40 +22,40 @@ module Neewom
22
22
  end
23
23
  end
24
24
 
25
- data = persisted_fields.each_with_object({}) do |field, acc|
26
- acc[field.name.to_sym] = params[field.name.to_sym] if params.has_key?(field.name.to_sym)
25
+ data = persisted_fields.each_with_object({}) do |field, acc|
26
+ acc[field.name.to_sym] = params[field.name.to_sym] if params.has_key?(field.name.to_sym)
27
27
  end
28
28
 
29
- resource.assign_attributes(data)
29
+ resource.assign_attributes(data)
30
30
  end
31
-
31
+
32
32
  resource
33
- end
33
+ end
34
34
 
35
35
  def parse_submit_control_value(controller_params)
36
- submit_fields.each_with_object({}) do |field, acc|
36
+ submit_fields.each_with_object({}) do |field, acc|
37
37
  acc[field.name.to_sym] = controller_params[field.name.to_sym] if controller_params.has_key?(field.name.to_sym)
38
38
  end
39
39
  end
40
-
40
+
41
41
  def find(id)
42
42
  resource = repository_klass.constantize.find(id)
43
43
  resource.initialize_neewom_attributes(self)
44
-
44
+
45
45
  resource
46
46
  end
47
-
47
+
48
48
  def find_by(options)
49
49
  resource = repository_klass.constantize.find_by(options)
50
50
  resource.initialize_neewom_attributes(self) if resource.present?
51
-
51
+
52
52
  resource
53
53
  end
54
-
54
+
55
55
  def find_by!(options)
56
56
  resource = repository_klass.constantize.find_by!(options)
57
57
  resource.initialize_neewom_attributes(self)
58
-
58
+
59
59
  resource
60
60
  end
61
61
 
@@ -71,17 +71,13 @@ module Neewom
71
71
  apply_inputs(find_by!(options), form_params, initial_values: initial_values)
72
72
  end
73
73
 
74
- def permit_params(controller_params)
75
- controller_params.require(strong_params_require).permit(strong_params_permit)
76
- end
77
-
78
74
  def strong_params_require
79
75
  repository_klass.constantize.model_name.param_key.to_sym
80
76
  end
81
-
77
+
82
78
  def strong_params_permit
83
79
  fields.map(&:name)
84
80
  end
85
81
  end
86
82
  end
87
- end
83
+ end
@@ -1,3 +1,3 @@
1
1
  module Neewom
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/neewom-0.1.0.gem ADDED
Binary file
data/neewom.gemspec CHANGED
@@ -6,8 +6,8 @@ require "neewom/version"
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "neewom"
8
8
  spec.version = Neewom::VERSION
9
- spec.authors = ["Oleg Zaporozhchenko"]
10
- spec.email = ["olegz@jetruby.com"]
9
+ spec.authors = ["Igor Deadman"]
10
+ spec.email = ["knightwhosayni@yandex.ru"]
11
11
 
12
12
  spec.summary = %q{Rails ActiveRecord custom fields and forms based on Postgres json fields}
13
13
  spec.description = %q{The most flexible solution for organizing custom fields for Rails ActiveRecord}
@@ -36,7 +36,7 @@ Gem::Specification.new do |spec|
36
36
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
37
37
  spec.require_paths = ["lib"]
38
38
 
39
- spec.add_development_dependency "bundler", "~> 1.17"
39
+ spec.add_development_dependency "bundler", "~> 2.2"
40
40
  spec.add_development_dependency "rake", "~> 10.0"
41
- spec.add_development_dependency "rspec", "~> 3.0"
41
+ spec.add_development_dependency "rspec-rails", "~> 3.0"
42
42
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neewom
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
- - Oleg Zaporozhchenko
7
+ - Igor Deadman
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-09-21 00:00:00.000000000 Z
11
+ date: 2021-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.17'
19
+ version: '2.2'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.17'
26
+ version: '2.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rspec
42
+ name: rspec-rails
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: '3.0'
55
55
  description: The most flexible solution for organizing custom fields for Rails ActiveRecord
56
56
  email:
57
- - olegz@jetruby.com
57
+ - knightwhosayni@yandex.ru
58
58
  executables: []
59
59
  extensions: []
60
60
  extra_rdoc_files: []
@@ -73,6 +73,7 @@ files:
73
73
  - lib/neewom.rb
74
74
  - lib/neewom/abstract_field.rb
75
75
  - lib/neewom/abstract_form.rb
76
+ - lib/neewom/collection.rb
76
77
  - lib/neewom/custom_field.rb
77
78
  - lib/neewom/custom_form.rb
78
79
  - lib/neewom/model.rb
@@ -80,6 +81,7 @@ files:
80
81
  - lib/neewom/repository.rb
81
82
  - lib/neewom/serializer.rb
82
83
  - lib/neewom/version.rb
84
+ - neewom-0.1.0.gem
83
85
  - neewom.gemspec
84
86
  homepage: https://github.com/trueknightwhosayni/neewom
85
87
  licenses:
@@ -103,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
105
  - !ruby/object:Gem::Version
104
106
  version: '0'
105
107
  requirements: []
106
- rubygems_version: 3.0.4
108
+ rubygems_version: 3.1.4
107
109
  signing_key:
108
110
  specification_version: 4
109
111
  summary: Rails ActiveRecord custom fields and forms based on Postgres json fields