dry_crud 6.0.0 → 7.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +2 -2
  3. data/README.rdoc +7 -6
  4. data/VERSION +1 -1
  5. data/app/assets/stylesheets/sample.scss +45 -24
  6. data/app/controllers/crud_controller.rb +19 -19
  7. data/app/controllers/dry_crud/generic_model.rb +2 -4
  8. data/app/controllers/dry_crud/render_callbacks.rb +3 -3
  9. data/app/controllers/list_controller.rb +1 -1
  10. data/app/helpers/actions_helper.rb +7 -7
  11. data/app/helpers/dry_crud/form/builder.rb +40 -43
  12. data/app/helpers/dry_crud/form/control.rb +8 -11
  13. data/app/helpers/dry_crud/table/actions.rb +12 -12
  14. data/app/helpers/dry_crud/table/builder.rb +10 -10
  15. data/app/helpers/dry_crud/table/col.rb +4 -4
  16. data/app/helpers/form_helper.rb +6 -8
  17. data/app/helpers/format_helper.rb +7 -7
  18. data/app/helpers/i18n_helper.rb +5 -5
  19. data/app/helpers/table_helper.rb +15 -16
  20. data/app/helpers/utility_helper.rb +3 -3
  21. data/app/views/crud/new.html.erb +1 -1
  22. data/app/views/crud/new.html.haml +1 -1
  23. data/app/views/layouts/application.html.erb +8 -6
  24. data/app/views/layouts/application.html.haml +6 -5
  25. data/app/views/list/_search.html.erb +1 -3
  26. data/app/views/list/_search.html.haml +1 -2
  27. data/app/views/shared/_error_messages.html.erb +2 -2
  28. data/lib/generators/dry_crud/dry_crud_generator.rb +1 -1
  29. data/lib/generators/dry_crud/templates/spec/controllers/crud_test_models_controller_spec.rb +4 -4
  30. data/lib/generators/dry_crud/templates/spec/helpers/dry_crud/form/builder_spec.rb +3 -3
  31. data/lib/generators/dry_crud/templates/spec/helpers/dry_crud/table/builder_spec.rb +1 -1
  32. data/lib/generators/dry_crud/templates/spec/helpers/form_helper_spec.rb +6 -5
  33. data/lib/generators/dry_crud/templates/spec/helpers/format_helper_spec.rb +2 -2
  34. data/lib/generators/dry_crud/templates/spec/helpers/table_helper_spec.rb +6 -6
  35. data/lib/generators/dry_crud/templates/spec/helpers/utility_helper_spec.rb +2 -2
  36. data/lib/generators/dry_crud/templates/spec/support/crud_controller_examples.rb +4 -6
  37. data/lib/generators/dry_crud/templates/spec/support/crud_controller_test_helper.rb +3 -3
  38. data/lib/generators/dry_crud/templates/test/controllers/crud_test_models_controller_test.rb +1 -1
  39. data/lib/generators/dry_crud/templates/test/helpers/custom_assertions_test.rb +5 -5
  40. data/lib/generators/dry_crud/templates/test/helpers/dry_crud/form/builder_test.rb +3 -3
  41. data/lib/generators/dry_crud/templates/test/helpers/form_helper_test.rb +8 -8
  42. data/lib/generators/dry_crud/templates/test/helpers/table_helper_test.rb +7 -7
  43. data/lib/generators/dry_crud/templates/test/helpers/utility_helper_test.rb +2 -2
  44. data/lib/generators/dry_crud/templates/test/support/crud_test_helper.rb +6 -6
  45. data/lib/generators/dry_crud/templates/test/support/crud_test_model.rb +2 -3
  46. data/lib/generators/dry_crud/templates/test/support/crud_test_models_controller.rb +4 -6
  47. data/lib/generators/dry_crud/templates/test/support/custom_assertions.rb +6 -6
  48. metadata +9 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3ff2a042dc7c846957d5e17001f9a538df726084e3695988d68066849938d544
4
- data.tar.gz: 504a97b4e2b0769cb260790725bb1a59aaffe33a16a093556d9462dd2403794f
3
+ metadata.gz: cf13269261b9cbae5f96418d05f9032805c3a50e1f1e7c02b79d71bfbf6c89c1
4
+ data.tar.gz: e28764d18296115dcae6119a97ed282d1d4da809585791333c0e6c328634d140
5
5
  SHA512:
6
- metadata.gz: 9808508def34a37d4d7bea43c5e7d810a4ac57d09c36ceadf8ee0fbf5bba3650611c5e3c5b010f5aa015666076ac3971fe824f2d6deeb17d913cc4404d2261bd
7
- data.tar.gz: c9b52ac7b06f5ab74f4fc3b8b0f340f1e3e5f35296296d109585dcb51906b46eb9615c393865cdde30aefb096dabf41dac197a24dc8e364d57e071551fbb0e5e
6
+ metadata.gz: a767e47df9be1a264bafa9af864278546e14fcfdf5bf728686c01bdf76d52823a73a215177a136a8c696c15898a82da899b88a2fc3252977d88c16a9da811436
7
+ data.tar.gz: d899147d340aae9dc0e75a64f718b3ada4debdd84a5d77970d2b6284cb9690f2f43877fe77319c900cb524a6da57a79be5c155098114d298cc040c09b6e3353b
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010-2013 Pascal Zumkehr
1
+ Copyright (c) 2010-2023 Pascal Zumkehr
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
@@ -16,4 +16,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
16
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
17
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
18
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- THE SOFTWARE.
19
+ THE SOFTWARE.
data/README.rdoc CHANGED
@@ -1,6 +1,8 @@
1
1
  = DRY CRUD
2
2
 
3
- {<img src="https://travis-ci.org/codez/dry_crud.svg?branch=master" />}[http://travis-ci.org/codez/dry_crud]
3
+ {rdoc-image:https://github.com/codez/dry_crud/actions/workflows/build.yml/badge.svg}[https://github.com/codez/dry_crud/actions/workflows/build.yml]
4
+ {rdoc-image:https://api.codeclimate.com/v1/badges/ef7488764a0d9805b37d/maintainability}[https://codeclimate.com/github/codez/dry_crud/maintainability]
5
+ {rdoc-image:https://api.codeclimate.com/v1/badges/ef7488764a0d9805b37d/test_coverage}[https://codeclimate.com/github/codez/dry_crud/test_coverage]
4
6
 
5
7
  dry_crud generates simple and extendable controllers, views and helpers that support you to DRY up the CRUD code in your Rails projects. List, search, sort, show, create, edit and destroy any model entries in just 5 minutes. Start with these artifacts and build a clean base to efficiently develop your application upon.
6
8
 
@@ -33,12 +35,11 @@ To integrate dry_crud into your code, only a few additions are required:
33
35
  * Optionally define a +list+ scope in your models to be used in the +index+ action.
34
36
  * Optionally define a +options_list+ scope in your models to be used in select dropdowns.
35
37
 
36
- From version 5.0 onwards, the major and minor version numbers will be kept in sync with Rails, and only the matching Rails version is supported. Version 3.0 is compatible 4.2, Version 2.0 and higher are compatible with Rails 4 and Rails 3.2. dry_crud is tested with Ruby 2.5. If you are using Ruby 1.9.3, please refer to version 3.0.0.
37
-
38
+ From version 5.0 onwards, the major and minor version numbers will be kept in sync with Rails, and only the matching Rails version is supported.
38
39
 
39
40
  == Background
40
41
 
41
- In most Rails applications, you have some models that require basic CRUD (create, read, update, delete) functionality. There are various possibilities like Rails scaffolding, {Inherited Resources}[https://github.com/activeadmin/inherited_resources] or {Rails Admin}[https://github.com/sferik/rails_admin]. Still, various parts in your application remain duplicated. While you might pull up common methods into a common superclass controller, most views still contain very similar code. And then you also have to remember the entire API of these frameworks.
42
+ In most Rails applications, you have some models that require basic CRUD (create, read, update, delete) functionality. There are various possibilities like Rails scaffolding, {Inherited Resources}[https://github.com/activeadmin/inherited_resources] or {Rails Admin}[https://github.com/railsadminteam/rails_admin]. Still, various parts in your application remain duplicated. While you might pull up common methods into a common superclass controller, most views still contain very similar code. And then you also have to remember the entire API of these frameworks.
42
43
 
43
44
  Enter dry_crud.
44
45
 
@@ -50,7 +51,7 @@ dry_crud is a Rails generator. All code resides in your application and is open
50
51
 
51
52
  dry_crud does not depend on any other gems, but easily allows you to integrate them in order to unify the behavior of your CRUD controllers. You might even use the gems mentioned above to adapt your generated CrudController base class. All classes come with thorough tests that provide you with a solid foundation for implementing your own adaptions.
52
53
 
53
- A basic CSS gets you started with your application's layout. For advanced needs, dry_crud supports the styles and classes used in {Bootstrap 4}[http://getbootstrap.com]. A great design never was so close.
54
+ A basic CSS gets you started with your application's layout. For advanced needs, dry_crud supports the styles and classes used in {Bootstrap}[http://getbootstrap.com]. As the views are generated into your application code, you are free to change the styling to your needs.
54
55
 
55
56
  If you find yourself adapting the same parts of dry_crud for your applications over and over, please feel free to {fork me on Github}[http://github.com/codez/dry_crud].
56
57
 
@@ -161,7 +162,7 @@ To render custom columns, use the +col+ method with an appropriate block:
161
162
  t.sortable_attrs(:lastname, :firstname)
162
163
  t.col('', class: 'center') { |entry| image_tag(entry.picture) }
163
164
  t.attr(:street)
164
- t.col('Map') { |entry| link_to(entry.city, "http://maps.google.com/?q=#{entry.city}" }
165
+ t.col('Map') { |entry| link_to(entry.city, "http://maps.google.com/?q=#{entry.city}") }
165
166
  end %>
166
167
 
167
168
  For views of subclasses of ListController, you can directly use the +crud_table+ helper method, where you do not have to pass the <tt>@people</tt> list explicitly and actions are added automatically.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 6.0.0
1
+ 7.1.0
@@ -1,8 +1,12 @@
1
1
  $container_width: 1000px;
2
2
  $theme_color: #2580a2;
3
3
 
4
- body, div, p, td, th {
5
- font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
4
+ body,
5
+ div,
6
+ p,
7
+ td,
8
+ th {
9
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
6
10
  font-size: 14px;
7
11
  line-height: 1.42857;
8
12
  }
@@ -101,7 +105,8 @@ table.table {
101
105
  }
102
106
 
103
107
  /* div rendered if no entries available for list */
104
- div.table {}
108
+ div.table {
109
+ }
105
110
 
106
111
  table.table th {
107
112
  background-color: $theme_color;
@@ -119,20 +124,21 @@ table.table td {
119
124
  padding: 4px 4px;
120
125
  }
121
126
 
122
- .table-striped thead tr:nth-child(odd), .table thead tr:nth-child(even) {
123
- background-color: #D0D0D0;
127
+ .table-striped thead tr:nth-child(odd),
128
+ .table thead tr:nth-child(even) {
129
+ background-color: #d0d0d0;
124
130
  }
125
131
 
126
132
  .table-striped tr:nth-child(odd) {
127
- background-color: #F8F8F8;
133
+ background-color: #f8f8f8;
128
134
  }
129
135
 
130
136
  .table-striped tr:nth-child(even) {
131
- background-color: #F0F0F0;
137
+ background-color: #f0f0f0;
132
138
  }
133
139
 
134
140
  .table-hover tr:hover {
135
- background-color: #FFFFE0;
141
+ background-color: #ffffe0;
136
142
  }
137
143
 
138
144
  td {
@@ -153,7 +159,7 @@ a:hover {
153
159
  }
154
160
 
155
161
  a:visited {
156
- color: #2580a2;
162
+ color: #2580a2;
157
163
  }
158
164
 
159
165
  a img {
@@ -213,11 +219,21 @@ a.icon img {
213
219
  vertical-align: top;
214
220
  }
215
221
 
216
- .icon-plus { background-image: image-url('actions/add.png'); }
217
- .icon-remove { background-image: image-url('actions/delete.png'); }
218
- .icon-pencil { background-image: image-url('actions/edit.png'); }
219
- .icon-list { background-image: image-url('actions/list.png'); }
220
- .icon-zoom-in { background-image: image-url('actions/show.png'); }
222
+ .icon-plus {
223
+ background-image: image-url("actions/add.png");
224
+ }
225
+ .icon-trash {
226
+ background-image: image-url("actions/delete.png");
227
+ }
228
+ .icon-pencil {
229
+ background-image: image-url("actions/edit.png");
230
+ }
231
+ .icon-list {
232
+ background-image: image-url("actions/list.png");
233
+ }
234
+ .icon-zoom-in {
235
+ background-image: image-url("actions/show.png");
236
+ }
221
237
 
222
238
  .form-group {
223
239
  clear: both;
@@ -231,34 +247,39 @@ a.icon img {
231
247
  padding-top: 3px;
232
248
  }
233
249
 
234
- input, textarea, select {
250
+ input,
251
+ textarea,
252
+ select {
235
253
  font-family: Verdana, Geneva, Helvetica, Arial, sans-serif;
236
254
  font-size: 14px;
237
255
  }
238
256
 
239
- input[type=text], input[type=password], input[type=email] {
257
+ input[type="text"],
258
+ input[type="password"],
259
+ input[type="email"] {
240
260
  width: 300px;
241
261
  }
242
262
 
243
- input[type=number] {
263
+ input[type="number"] {
244
264
  width: 100px;
245
265
  }
246
266
 
247
- textarea, select[multiple] {
267
+ textarea,
268
+ select[multiple] {
248
269
  width: 300px;
249
270
  height: 80px;
250
271
  }
251
272
 
252
- [role=search] [type=search] {
273
+ [role="search"] [type="search"] {
253
274
  width: 220px;
254
275
  }
255
276
 
256
277
  .has-error .control-label {
257
- color: #D88;
278
+ color: #d88;
258
279
  }
259
280
 
260
281
  .has-error .form-control {
261
- border-color: #D88;
282
+ border-color: #d88;
262
283
  }
263
284
 
264
285
  .input-group-append {
@@ -284,7 +305,7 @@ textarea, select[multiple] {
284
305
  }
285
306
 
286
307
  .alert-danger {
287
- border: solid 2px #D88;
308
+ border: solid 2px #d88;
288
309
  background-color: #fec;
289
310
  }
290
311
 
@@ -292,11 +313,11 @@ textarea, select[multiple] {
292
313
  float: right;
293
314
  }
294
315
 
295
- .float-right {
316
+ .float-end {
296
317
  float: right;
297
318
  }
298
319
 
299
- .float-left {
320
+ .float-start {
300
321
  float: left;
301
322
  }
302
323
 
@@ -40,6 +40,11 @@ class CrudController < ListController
40
40
  assign_attributes if params[model_identifier]
41
41
  end
42
42
 
43
+ # GET /entries/1/edit
44
+ #
45
+ # Display a form to edit an exisiting entry of this model.
46
+ def edit; end
47
+
43
48
  # POST /entries
44
49
  # POST /entries.json
45
50
  #
@@ -52,22 +57,17 @@ class CrudController < ListController
52
57
  # in the given block will take precedence over the one defined here.
53
58
  #
54
59
  # Specify a :location option if you wish to do a custom redirect.
55
- def create(options = {}, &block)
60
+ def create(**options, &block)
56
61
  model_class.transaction do
57
62
  assign_attributes
58
63
  created = with_callbacks(:create, :save) { entry.save }
59
64
  respond(created,
60
- options.merge(status: :created, render_on_failure: :new),
65
+ **options.merge(status: :created, render_on_failure: :new),
61
66
  &block)
62
67
  raise ActiveRecord::Rollback unless created
63
68
  end
64
69
  end
65
70
 
66
- # GET /entries/1/edit
67
- #
68
- # Display a form to edit an exisiting entry of this model.
69
- def edit; end
70
-
71
71
  # PUT /entries/1
72
72
  # PUT /entries/1.json
73
73
  #
@@ -80,12 +80,12 @@ class CrudController < ListController
80
80
  # in the given block will take precedence over the one defined here.
81
81
  #
82
82
  # Specify a :location option if you wish to do a custom redirect.
83
- def update(options = {}, &block)
83
+ def update(**options, &block)
84
84
  model_class.transaction do
85
85
  assign_attributes
86
86
  updated = with_callbacks(:update, :save) { entry.save }
87
87
  respond(updated,
88
- options.merge(status: :ok, render_on_failure: :edit),
88
+ **options.merge(status: :ok, render_on_failure: :edit),
89
89
  &block)
90
90
  raise ActiveRecord::Rollback unless updated
91
91
  end
@@ -103,11 +103,11 @@ class CrudController < ListController
103
103
  # in the given block will take precedence over the one defined here.
104
104
  #
105
105
  # Specify a :location option if you wish to do a custom redirect.
106
- def destroy(options = {}, &block)
106
+ def destroy(**options, &block)
107
107
  model_class.transaction do
108
108
  destroyed = run_callbacks(:destroy) { entry.destroy }
109
109
  respond(destroyed,
110
- options.merge(status: :no_content),
110
+ **options.merge(status: :no_content),
111
111
  &block)
112
112
  raise ActiveRecord::Rollback unless destroyed
113
113
  end
@@ -152,14 +152,14 @@ class CrudController < ListController
152
152
  path_args(entry)
153
153
  end
154
154
 
155
- def respond(success, options)
155
+ def respond(success, **options)
156
156
  respond_to do |format|
157
157
  yield(format, success) if block_given?
158
158
  if success
159
- format.html { redirect_on_success(options) }
159
+ format.html { redirect_on_success(**options) }
160
160
  format.json { render_success_json(options[:status]) }
161
161
  else
162
- format.html { render_or_redirect_on_failure(options) }
162
+ format.html { render_or_redirect_on_failure(**options) }
163
163
  format.json { render_failure_json }
164
164
  end
165
165
  end
@@ -167,16 +167,16 @@ class CrudController < ListController
167
167
 
168
168
  # If the option :render_on_failure is given, render the corresponding
169
169
  # template, otherwise redirect.
170
- def render_or_redirect_on_failure(options)
170
+ def render_or_redirect_on_failure(**options)
171
171
  if options[:render_on_failure]
172
172
  render options[:render_on_failure]
173
173
  else
174
- redirect_on_failure(options)
174
+ redirect_on_failure(**options)
175
175
  end
176
176
  end
177
177
 
178
178
  # Perform a redirect after a successfull operation and set a flash notice.
179
- def redirect_on_success(options = {})
179
+ def redirect_on_success(**options)
180
180
  location = options[:location] ||
181
181
  (entry.destroyed? ? index_path : show_path)
182
182
  flash[:notice] ||= flash_message(:success)
@@ -184,7 +184,7 @@ class CrudController < ListController
184
184
  end
185
185
 
186
186
  # Perform a redirect after a failed operation and set a flash alert.
187
- def redirect_on_failure(options = {})
187
+ def redirect_on_failure(**options)
188
188
  location = options[:location] ||
189
189
  request.env['HTTP_REFERER'].presence ||
190
190
  index_path
@@ -221,7 +221,7 @@ class CrudController < ListController
221
221
  # A label for the current entry, including the model name.
222
222
  def full_entry_label
223
223
  # rubocop:disable Rails/OutputSafety
224
- "#{models_label(false)} <i>#{ERB::Util.h(entry)}</i>".html_safe
224
+ "#{models_label(plural: false)} <i>#{ERB::Util.h(entry)}</i>".html_safe
225
225
  # rubocop:enable Rails/OutputSafety
226
226
  end
227
227
 
@@ -13,8 +13,6 @@ module DryCrud
13
13
  included do
14
14
  helper_method :model_class, :models_label, :path_args
15
15
 
16
- private
17
-
18
16
  delegate :model_class, :models_label, :model_identifier, to: 'self.class'
19
17
  end
20
18
 
@@ -33,7 +31,7 @@ module DryCrud
33
31
 
34
32
  # Get the instance variable named after the +model_class+.
35
33
  # If the collection variable is required, pass true as the second argument.
36
- def model_ivar_get(plural = false)
34
+ def model_ivar_get(plural: false)
37
35
  name = ivar_name(model_class)
38
36
  name = name.pluralize if plural
39
37
  name = :"@#{name}"
@@ -72,7 +70,7 @@ module DryCrud
72
70
  end
73
71
 
74
72
  # A human readable plural name of the model.
75
- def models_label(plural = true)
73
+ def models_label(plural: true)
76
74
  opts = { count: (plural ? 3 : 1) }
77
75
  opts[:default] = model_class.model_name.human.titleize
78
76
  opts[:default] = opts[:default].pluralize if plural
@@ -15,13 +15,13 @@ module DryCrud
15
15
 
16
16
  # Helper method to run +before_render+ callbacks and render the action.
17
17
  # If a callback renders or redirects, the action is not rendered.
18
- def render(*args, &block)
19
- options = _normalize_render(*args, &block)
18
+ def render(...)
19
+ options = _normalize_render(...)
20
20
  callback = "render_#{options[:template]}"
21
21
 
22
22
  run_callbacks(callback) if respond_to?(:"_#{callback}_callbacks", true)
23
23
 
24
- super(*args, &block) unless performed?
24
+ super(...) unless performed?
25
25
  end
26
26
 
27
27
  private
@@ -32,7 +32,7 @@ class ListController < ApplicationController
32
32
  # Helper method to access the entries to be displayed in the current index
33
33
  # page in an uniform way.
34
34
  def entries
35
- model_ivar_get(true) || model_ivar_set(list_entries)
35
+ model_ivar_get(plural: true) || model_ivar_set(list_entries)
36
36
  end
37
37
 
38
38
  # The base relation used to filter the entries.
@@ -14,7 +14,7 @@ module ActionsHelper
14
14
 
15
15
  # Outputs an icon for an action with an optional label.
16
16
  def action_icon(icon, label = nil)
17
- html = content_tag(:span, '', class: "icon icon-#{icon}")
17
+ html = tag.i('', class: "bi-#{icon}")
18
18
  html << ' ' << label if label
19
19
  html
20
20
  end
@@ -30,7 +30,7 @@ module ActionsHelper
30
30
  # Uses the current +entry+ if no path is given.
31
31
  def edit_action_link(path = nil)
32
32
  path ||= path_args(entry)
33
- path = path.is_a?(String) ? path : edit_polymorphic_path(path)
33
+ path = edit_polymorphic_path(path) unless path.is_a?(String)
34
34
  action_link(ti('link.edit'), 'pencil', path)
35
35
  end
36
36
 
@@ -38,16 +38,16 @@ module ActionsHelper
38
38
  # Uses the current +entry+ if no path is given.
39
39
  def destroy_action_link(path = nil)
40
40
  path ||= path_args(entry)
41
- action_link(ti('link.delete'), 'remove', path,
42
- data: { confirm: ti(:confirm_delete),
43
- method: :delete })
41
+ action_link(ti('link.delete'), 'trash', path,
42
+ data: { 'turbo-confirm': ti(:confirm_delete),
43
+ 'turbo-method': :delete })
44
44
  end
45
45
 
46
46
  # Standard list action to the given path.
47
47
  # Uses the current +model_class+ if no path is given.
48
48
  def index_action_link(path = nil, url_options = { returning: true })
49
49
  path ||= path_args(model_class)
50
- path = path.is_a?(String) ? path : polymorphic_path(path, url_options)
50
+ path = polymorphic_path(path, url_options) unless path.is_a?(String)
51
51
  action_link(ti('link.list'), 'list', path)
52
52
  end
53
53
 
@@ -55,7 +55,7 @@ module ActionsHelper
55
55
  # Uses the current +model_class+ if no path is given.
56
56
  def add_action_link(path = nil, url_options = {})
57
57
  path ||= path_args(model_class)
58
- path = path.is_a?(String) ? path : new_polymorphic_path(path, url_options)
58
+ path = new_polymorphic_path(path, url_options) unless path.is_a?(String)
59
59
  action_link(ti('link.add'), 'plus', path)
60
60
  end
61
61
 
@@ -21,7 +21,7 @@ module DryCrud
21
21
  attr_reader :template
22
22
 
23
23
  delegate :association, :column_type, :column_property, :captionize,
24
- :ti, :ta, :link_to, :content_tag, :safe_join, :capture,
24
+ :ti, :ta, :link_to, :tag, :safe_join, :capture,
25
25
  :add_css_class, :assoc_and_id_attr,
26
26
  to: :template
27
27
 
@@ -29,9 +29,8 @@ module DryCrud
29
29
 
30
30
  # Render multiple input controls together with a label for the given
31
31
  # attributes.
32
- def labeled_input_fields(*attrs)
33
- options = attrs.extract_options!
34
- safe_join(attrs) { |a| labeled_input_field(a, options.dup) }
32
+ def labeled_input_fields(*attrs, **options)
33
+ safe_join(attrs) { |a| labeled_input_field(a, **options.dup) }
35
34
  end
36
35
 
37
36
  # Render a corresponding input control and label for the given attribute.
@@ -45,8 +44,8 @@ module DryCrud
45
44
  # * <tt>:field_method</tt> - Different method to create the input field.
46
45
  #
47
46
  # Use additional html_options for the input element.
48
- def labeled_input_field(attr, html_options = {})
49
- control_class.new(self, attr, html_options).render_labeled
47
+ def labeled_input_field(attr, **html_options)
48
+ control_class.new(self, attr, **html_options).render_labeled
50
49
  end
51
50
 
52
51
  # Render a corresponding input control for the given attribute.
@@ -59,20 +58,20 @@ module DryCrud
59
58
  # * <tt>:field_method</tt> - Different method to create the input field.
60
59
  #
61
60
  # Use additional html_options for the input element.
62
- def input_field(attr, html_options = {})
63
- control_class.new(self, attr, html_options).render_content
61
+ def input_field(attr, **html_options)
62
+ control_class.new(self, attr, **html_options).render_content
64
63
  end
65
64
 
66
65
  # Render a standard string field with column contraints.
67
- def string_field(attr, html_options = {})
66
+ def string_field(attr, **html_options)
68
67
  html_options[:maxlength] ||= column_property(@object, attr, :limit)
69
- text_field(attr, html_options)
68
+ text_field(attr, **html_options)
70
69
  end
71
70
 
72
71
  # Render a boolean field.
73
- def boolean_field(attr, html_options = {})
74
- content_tag(:div, class: 'checkbox') do
75
- content_tag(:label) do
72
+ def boolean_field(attr, **html_options)
73
+ tag.div(class: 'checkbox') do
74
+ tag.label do
76
75
  detail = html_options.delete(:detail) || '&nbsp;'.html_safe
77
76
  safe_join([check_box(attr, html_options), ' ', detail])
78
77
  end
@@ -82,33 +81,33 @@ module DryCrud
82
81
  # Add form-control class to all input fields.
83
82
  %w[text_field password_field email_field
84
83
  number_field date_field time_field datetime_field].each do |method|
85
- define_method(method) do |attr, html_options = {}|
84
+ define_method(method) do |attr, **html_options|
86
85
  add_css_class(html_options, 'form-control')
87
86
  super(attr, html_options)
88
87
  end
89
88
  end
90
89
 
91
- def integer_field(attr, html_options = {})
90
+ def integer_field(attr, **html_options)
92
91
  html_options[:step] ||= 1
93
- number_field(attr, html_options)
92
+ number_field(attr, **html_options)
94
93
  end
95
94
 
96
- def float_field(attr, html_options = {})
95
+ def float_field(attr, **html_options)
97
96
  html_options[:step] ||= 'any'
98
- number_field(attr, html_options)
97
+ number_field(attr, **html_options)
99
98
  end
100
99
 
101
- def decimal_field(attr, html_options = {})
100
+ def decimal_field(attr, **html_options)
102
101
  html_options[:step] ||=
103
102
  (10**-column_property(object, attr, :scale)).to_f
104
- number_field(attr, html_options)
103
+ number_field(attr, **html_options)
105
104
  end
106
105
 
107
106
  # Customize the standard text area to have 5 rows by default.
108
- def text_area(attr, html_options = {})
107
+ def text_area(attr, **html_options)
109
108
  add_css_class(html_options, 'form-control')
110
109
  html_options[:rows] ||= 5
111
- super(attr, html_options)
110
+ super(attr, **html_options)
112
111
  end
113
112
 
114
113
  # Render a select element for a :belongs_to association defined by attr.
@@ -116,13 +115,13 @@ module DryCrud
116
115
  # To pass a custom element list, specify the list with the :list key or
117
116
  # define an instance variable with the pluralized name of the
118
117
  # association.
119
- def belongs_to_field(attr, html_options = {})
120
- list = association_entries(attr, html_options).to_a
118
+ def belongs_to_field(attr, **html_options)
119
+ list = association_entries(attr, **html_options).to_a
121
120
  if list.present?
122
121
  add_css_class(html_options, 'form-control')
123
122
  collection_select(attr, list, :id, :to_s,
124
- select_options(attr, html_options),
125
- html_options)
123
+ select_options(attr, **html_options),
124
+ **html_options)
126
125
  else
127
126
  # rubocop:disable Rails/OutputSafety
128
127
  none = ta(:none_available, association(@object, attr)).html_safe
@@ -131,7 +130,7 @@ module DryCrud
131
130
  end
132
131
  end
133
132
 
134
- # rubocop:disable PredicateName
133
+ # rubocop:disable Naming/PredicateName
135
134
 
136
135
  # Render a multi select element for a :has_many or
137
136
  # :has_and_belongs_to_many association defined by attr.
@@ -139,12 +138,12 @@ module DryCrud
139
138
  # To pass a custom element list, specify the list with the :list key or
140
139
  # define an instance variable with the pluralized name of the
141
140
  # association.
142
- def has_many_field(attr, html_options = {})
141
+ def has_many_field(attr, **html_options)
143
142
  html_options[:multiple] = true
144
143
  add_css_class(html_options, 'multiselect')
145
- belongs_to_field(attr, html_options)
144
+ belongs_to_field(attr, **html_options)
146
145
  end
147
- # rubocop:enable PredicateName
146
+ # rubocop:enable Naming/PredicateName
148
147
 
149
148
  ### VARIOUS FORM ELEMENTS
150
149
 
@@ -157,25 +156,24 @@ module DryCrud
157
156
 
158
157
  # Renders the given content with an addon.
159
158
  def with_addon(content, addon)
160
- content_tag(:div, class: 'input-group') do
161
- html = content_tag(:span, addon, class: 'input-group-text')
162
- content + content_tag(:div, html, class: 'input-group-append')
159
+ tag.div(class: 'input-group') do
160
+ content + tag.span(addon, class: 'input-group-text')
163
161
  end
164
162
  end
165
163
 
166
164
  # Renders a static text where otherwise form inputs appear.
167
165
  def static_text(text)
168
- content_tag(:p, text, class: 'form-control-static')
166
+ tag.p(text, class: 'form-control-static')
169
167
  end
170
168
 
171
169
  # Generates a help block for fields
172
170
  def help_block(text)
173
- content_tag(:p, text, class: 'help-block')
171
+ tag.p(text, class: 'help-block')
174
172
  end
175
173
 
176
174
  # Render a submit button and a cancel link for this form.
177
175
  def standard_actions(submit_label = ti('button.save'), cancel_url = nil)
178
- content_tag(:div, class: 'col-md-offset-2 col-md-8') do
176
+ tag.div(class: 'col-md-offset-2 col-md-8') do
179
177
  safe_join([submit_button(submit_label),
180
178
  cancel_link(cancel_url)],
181
179
  ' ')
@@ -195,7 +193,7 @@ module DryCrud
195
193
 
196
194
  # Depending if the given attribute must be present, return
197
195
  # only an initial selection prompt or a blank option, respectively.
198
- def select_options(attr, options = {})
196
+ def select_options(attr, **options)
199
197
  prompt = options.delete(:prompt)
200
198
  blank = options.delete(:include_blank)
201
199
  if options[:multiple]
@@ -239,7 +237,7 @@ module DryCrud
239
237
  options = content
240
238
  content = capture(&block)
241
239
  end
242
- control = control_class.new(self, attr, options)
240
+ control = control_class.new(self, attr, **options)
243
241
  control.render_labeled(content)
244
242
  end
245
243
 
@@ -269,17 +267,16 @@ module DryCrud
269
267
  def labeled_field_method?(name)
270
268
  prefix = 'labeled_'
271
269
  if name.to_s.start_with?(prefix)
272
- field_method = name.to_s[prefix.size..-1]
270
+ field_method = name.to_s[prefix.size..]
273
271
  field_method if respond_to?(field_method)
274
272
  end
275
273
  end
276
274
 
277
275
  # Renders the corresponding field together with a label, required mark
278
276
  # and an optional help block.
279
- def build_labeled_field(field_method, *args)
280
- options = args.extract_options!
277
+ def build_labeled_field(field_method, *args, **options)
281
278
  options[:field_method] = field_method
282
- control_class.new(self, *(args << options)).render_labeled
279
+ control_class.new(self, *args, **options).render_labeled
283
280
  end
284
281
 
285
282
  # Returns the list of association entries, either from options[:list] or
@@ -287,7 +284,7 @@ module DryCrud
287
284
  # Otherwise, if the association defines a #options_list or #list scope,
288
285
  # this is used to load the entries.
289
286
  # As a last resort, all entries from the association class are returned.
290
- def association_entries(attr, options)
287
+ def association_entries(attr, **options)
291
288
  list = options.delete(:list)
292
289
  unless list
293
290
  assoc = association(@object, attr)