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.
- checksums.yaml +4 -4
- data/MIT-LICENSE +2 -2
- data/README.rdoc +7 -6
- data/VERSION +1 -1
- data/app/assets/stylesheets/sample.scss +45 -24
- data/app/controllers/crud_controller.rb +19 -19
- data/app/controllers/dry_crud/generic_model.rb +2 -4
- data/app/controllers/dry_crud/render_callbacks.rb +3 -3
- data/app/controllers/list_controller.rb +1 -1
- data/app/helpers/actions_helper.rb +7 -7
- data/app/helpers/dry_crud/form/builder.rb +40 -43
- data/app/helpers/dry_crud/form/control.rb +8 -11
- data/app/helpers/dry_crud/table/actions.rb +12 -12
- data/app/helpers/dry_crud/table/builder.rb +10 -10
- data/app/helpers/dry_crud/table/col.rb +4 -4
- data/app/helpers/form_helper.rb +6 -8
- data/app/helpers/format_helper.rb +7 -7
- data/app/helpers/i18n_helper.rb +5 -5
- data/app/helpers/table_helper.rb +15 -16
- data/app/helpers/utility_helper.rb +3 -3
- data/app/views/crud/new.html.erb +1 -1
- data/app/views/crud/new.html.haml +1 -1
- data/app/views/layouts/application.html.erb +8 -6
- data/app/views/layouts/application.html.haml +6 -5
- data/app/views/list/_search.html.erb +1 -3
- data/app/views/list/_search.html.haml +1 -2
- data/app/views/shared/_error_messages.html.erb +2 -2
- data/lib/generators/dry_crud/dry_crud_generator.rb +1 -1
- data/lib/generators/dry_crud/templates/spec/controllers/crud_test_models_controller_spec.rb +4 -4
- data/lib/generators/dry_crud/templates/spec/helpers/dry_crud/form/builder_spec.rb +3 -3
- data/lib/generators/dry_crud/templates/spec/helpers/dry_crud/table/builder_spec.rb +1 -1
- data/lib/generators/dry_crud/templates/spec/helpers/form_helper_spec.rb +6 -5
- data/lib/generators/dry_crud/templates/spec/helpers/format_helper_spec.rb +2 -2
- data/lib/generators/dry_crud/templates/spec/helpers/table_helper_spec.rb +6 -6
- data/lib/generators/dry_crud/templates/spec/helpers/utility_helper_spec.rb +2 -2
- data/lib/generators/dry_crud/templates/spec/support/crud_controller_examples.rb +4 -6
- data/lib/generators/dry_crud/templates/spec/support/crud_controller_test_helper.rb +3 -3
- data/lib/generators/dry_crud/templates/test/controllers/crud_test_models_controller_test.rb +1 -1
- data/lib/generators/dry_crud/templates/test/helpers/custom_assertions_test.rb +5 -5
- data/lib/generators/dry_crud/templates/test/helpers/dry_crud/form/builder_test.rb +3 -3
- data/lib/generators/dry_crud/templates/test/helpers/form_helper_test.rb +8 -8
- data/lib/generators/dry_crud/templates/test/helpers/table_helper_test.rb +7 -7
- data/lib/generators/dry_crud/templates/test/helpers/utility_helper_test.rb +2 -2
- data/lib/generators/dry_crud/templates/test/support/crud_test_helper.rb +6 -6
- data/lib/generators/dry_crud/templates/test/support/crud_test_model.rb +2 -3
- data/lib/generators/dry_crud/templates/test/support/crud_test_models_controller.rb +4 -6
- data/lib/generators/dry_crud/templates/test/support/custom_assertions.rb +6 -6
- metadata +9 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf13269261b9cbae5f96418d05f9032805c3a50e1f1e7c02b79d71bfbf6c89c1
|
4
|
+
data.tar.gz: e28764d18296115dcae6119a97ed282d1d4da809585791333c0e6c328634d140
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a767e47df9be1a264bafa9af864278546e14fcfdf5bf728686c01bdf76d52823a73a215177a136a8c696c15898a82da899b88a2fc3252977d88c16a9da811436
|
7
|
+
data.tar.gz: d899147d340aae9dc0e75a64f718b3ada4debdd84a5d77970d2b6284cb9690f2f43877fe77319c900cb524a6da57a79be5c155098114d298cc040c09b6e3353b
|
data/MIT-LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c) 2010-
|
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
|
-
{
|
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.
|
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/
|
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
|
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
|
-
|
1
|
+
7.1.0
|
@@ -1,8 +1,12 @@
|
|
1
1
|
$container_width: 1000px;
|
2
2
|
$theme_color: #2580a2;
|
3
3
|
|
4
|
-
body,
|
5
|
-
|
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),
|
123
|
-
|
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: #
|
133
|
+
background-color: #f8f8f8;
|
128
134
|
}
|
129
135
|
|
130
136
|
.table-striped tr:nth-child(even) {
|
131
|
-
background-color: #
|
137
|
+
background-color: #f0f0f0;
|
132
138
|
}
|
133
139
|
|
134
140
|
.table-hover tr:hover {
|
135
|
-
background-color: #
|
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:
|
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 {
|
217
|
-
|
218
|
-
|
219
|
-
.icon-
|
220
|
-
|
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,
|
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],
|
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,
|
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: #
|
278
|
+
color: #d88;
|
258
279
|
}
|
259
280
|
|
260
281
|
.has-error .form-control {
|
261
|
-
border-color: #
|
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 #
|
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-
|
316
|
+
.float-end {
|
296
317
|
float: right;
|
297
318
|
}
|
298
319
|
|
299
|
-
.float-
|
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
|
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
|
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
|
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
|
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
|
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(
|
19
|
-
options = _normalize_render(
|
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(
|
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 =
|
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)
|
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'), '
|
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)
|
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)
|
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, :
|
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
|
-
|
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
|
-
|
75
|
-
|
72
|
+
def boolean_field(attr, **html_options)
|
73
|
+
tag.div(class: 'checkbox') do
|
74
|
+
tag.label do
|
76
75
|
detail = html_options.delete(:detail) || ' '.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
|
-
|
161
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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, *
|
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)
|