neewom 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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