dry_crud 3.0.0 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.rdoc +1 -1
- data/VERSION +1 -1
- data/app/controllers/crud_controller.rb +10 -8
- data/app/controllers/dry_crud/generic_model.rb +6 -4
- data/app/controllers/dry_crud/nestable.rb +9 -11
- data/app/controllers/dry_crud/rememberable.rb +5 -1
- data/app/controllers/dry_crud/render_callbacks.rb +40 -19
- data/app/controllers/dry_crud/searchable.rb +40 -31
- data/app/controllers/dry_crud/sortable.rb +36 -26
- data/app/controllers/list_controller.rb +2 -2
- data/app/helpers/dry_crud/form/builder.rb +21 -13
- data/app/helpers/dry_crud/form/control.rb +8 -9
- data/app/helpers/dry_crud/table/actions.rb +6 -1
- data/app/helpers/dry_crud/table/builder.rb +4 -2
- data/app/helpers/dry_crud/table/col.rb +12 -1
- data/app/helpers/dry_crud/table/sorting.rb +7 -1
- data/app/helpers/form_helper.rb +7 -7
- data/app/helpers/format_helper.rb +3 -3
- data/app/helpers/i18n_helper.rb +3 -3
- data/app/helpers/utility_helper.rb +4 -1
- data/lib/dry_crud.rb +1 -2
- data/lib/dry_crud/engine.rb +5 -7
- data/lib/generators/dry_crud/dry_crud_generator.rb +3 -4
- data/lib/generators/dry_crud/dry_crud_generator_base.rb +6 -8
- data/lib/generators/dry_crud/file_generator.rb +1 -3
- data/lib/generators/dry_crud/templates/spec/controllers/crud_test_models_controller_spec.rb +8 -18
- data/lib/generators/dry_crud/templates/spec/helpers/form_helper_spec.rb +1 -1
- data/lib/generators/dry_crud/templates/spec/helpers/utility_helper_spec.rb +4 -4
- data/lib/generators/dry_crud/templates/spec/support/crud_controller_examples.rb +7 -17
- data/lib/generators/dry_crud/templates/spec/support/crud_controller_test_helper.rb +13 -29
- data/lib/generators/dry_crud/templates/test/controllers/crud_test_models_controller_test.rb +25 -44
- data/lib/generators/dry_crud/templates/test/helpers/custom_assertions_test.rb +0 -1
- data/lib/generators/dry_crud/templates/test/helpers/dry_crud/form/builder_test.rb +3 -4
- data/lib/generators/dry_crud/templates/test/helpers/dry_crud/table/builder_test.rb +0 -2
- data/lib/generators/dry_crud/templates/test/helpers/form_helper_test.rb +2 -1
- data/lib/generators/dry_crud/templates/test/helpers/format_helper_test.rb +1 -1
- data/lib/generators/dry_crud/templates/test/helpers/table_helper_test.rb +8 -17
- data/lib/generators/dry_crud/templates/test/helpers/utility_helper_test.rb +3 -0
- data/lib/generators/dry_crud/templates/test/support/crud_controller_test_helper.rb +27 -30
- data/lib/generators/dry_crud/templates/test/support/crud_test_helper.rb +11 -13
- data/lib/generators/dry_crud/templates/test/support/crud_test_model.rb +7 -3
- data/lib/generators/dry_crud/templates/test/support/crud_test_models_controller.rb +5 -9
- data/lib/generators/dry_crud/templates/test/support/custom_assertions.rb +1 -1
- metadata +10 -11
@@ -11,9 +11,9 @@
|
|
11
11
|
class ListController < ApplicationController
|
12
12
|
|
13
13
|
include DryCrud::GenericModel
|
14
|
-
|
15
|
-
include DryCrud::Rememberable
|
14
|
+
prepend DryCrud::Nestable
|
16
15
|
include DryCrud::RenderCallbacks
|
16
|
+
include DryCrud::Rememberable
|
17
17
|
|
18
18
|
define_render_callbacks :index
|
19
19
|
|
@@ -75,7 +75,9 @@ module DryCrud
|
|
75
75
|
def boolean_field(attr, html_options = {})
|
76
76
|
content_tag(:div, class: 'checkbox') do
|
77
77
|
content_tag(:label) do
|
78
|
+
# rubocop:disable Rails/OutputSafety
|
78
79
|
detail = html_options.delete(:detail) || ' '.html_safe
|
80
|
+
# rubocop:enable Rails/OutputSafety
|
79
81
|
safe_join([check_box(attr, html_options), ' ', detail])
|
80
82
|
end
|
81
83
|
end
|
@@ -97,9 +99,9 @@ module DryCrud
|
|
97
99
|
super(attr, html_options)
|
98
100
|
end
|
99
101
|
|
100
|
-
|
101
|
-
|
102
|
-
|
102
|
+
alias integer_field number_field
|
103
|
+
alias float_field number_field
|
104
|
+
alias decimal_field number_field
|
103
105
|
|
104
106
|
# Render a select element for a :belongs_to association defined by attr.
|
105
107
|
# Use additional html_options for the select element.
|
@@ -114,8 +116,10 @@ module DryCrud
|
|
114
116
|
select_options(attr, html_options),
|
115
117
|
html_options)
|
116
118
|
else
|
117
|
-
|
118
|
-
|
119
|
+
# rubocop:disable Rails/OutputSafety
|
120
|
+
none = ta(:none_available, association(@object, attr)).html_safe
|
121
|
+
# rubocop:enable Rails/OutputSafety
|
122
|
+
static_text(none)
|
119
123
|
end
|
120
124
|
end
|
121
125
|
|
@@ -208,8 +212,8 @@ module DryCrud
|
|
208
212
|
@object.class.validators_on(attr_id)
|
209
213
|
validators.any? do |v|
|
210
214
|
v.kind == :presence &&
|
211
|
-
|
212
|
-
|
215
|
+
!v.options.key?(:if) &&
|
216
|
+
!v.options.key?(:unless)
|
213
217
|
end
|
214
218
|
end
|
215
219
|
|
@@ -278,8 +282,9 @@ module DryCrud
|
|
278
282
|
list = options.delete(:list)
|
279
283
|
unless list
|
280
284
|
assoc = association(@object, attr)
|
281
|
-
|
282
|
-
|
285
|
+
ivar = :"@#{assoc.name.to_s.pluralize}"
|
286
|
+
list = @template.send(:instance_variable_defined?, ivar) &&
|
287
|
+
@template.send(:instance_variable_get, ivar)
|
283
288
|
list ||= load_association_entries(assoc)
|
284
289
|
end
|
285
290
|
list
|
@@ -288,7 +293,8 @@ module DryCrud
|
|
288
293
|
# Automatically load the entries for the given association.
|
289
294
|
def load_association_entries(assoc)
|
290
295
|
klass = assoc.klass
|
291
|
-
list = klass.all
|
296
|
+
list = klass.all
|
297
|
+
list = list.merge(assoc.scope) if assoc.scope
|
292
298
|
# Use special scopes if they are defined
|
293
299
|
if klass.respond_to?(:options_list)
|
294
300
|
list.options_list
|
@@ -303,9 +309,11 @@ module DryCrud
|
|
303
309
|
# 1. Use :cancel_url_new or :cancel_url_edit option, if present
|
304
310
|
# 2. Use :cancel_url option, if present
|
305
311
|
def cancel_url
|
306
|
-
|
307
|
-
|
308
|
-
|
312
|
+
if @object.new_record?
|
313
|
+
options[:cancel_url_new] || options[:cancel_url]
|
314
|
+
else
|
315
|
+
options[:cancel_url_edit] || options[:cancel_url]
|
316
|
+
end
|
309
317
|
end
|
310
318
|
|
311
319
|
end
|
@@ -14,15 +14,15 @@ module DryCrud
|
|
14
14
|
to: :builder
|
15
15
|
|
16
16
|
# Html displayed to mark an input as required.
|
17
|
-
REQUIRED_MARK = '*'
|
17
|
+
REQUIRED_MARK = '*'.freeze
|
18
18
|
|
19
19
|
# Number of default input field span columns depending
|
20
20
|
# on the #field_method.
|
21
21
|
INPUT_SPANS = Hash.new(8)
|
22
22
|
INPUT_SPANS[:number_field] =
|
23
23
|
INPUT_SPANS[:integer_field] =
|
24
|
-
|
25
|
-
|
24
|
+
INPUT_SPANS[:float_field] =
|
25
|
+
INPUT_SPANS[:decimal_field] = 2
|
26
26
|
INPUT_SPANS[:date_field] =
|
27
27
|
INPUT_SPANS[:time_field] = 3
|
28
28
|
|
@@ -76,7 +76,7 @@ module DryCrud
|
|
76
76
|
|
77
77
|
content_tag(:div, class: "form-group#{errors}") do
|
78
78
|
builder.label(attr, caption, class: 'col-md-2 control-label') +
|
79
|
-
|
79
|
+
content_tag(:div, content, class: "col-md-#{span}")
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
@@ -133,11 +133,8 @@ module DryCrud
|
|
133
133
|
# association.
|
134
134
|
def errors?
|
135
135
|
attr_plain, attr_id = builder.assoc_and_id_attr(attr)
|
136
|
-
|
137
|
-
|
138
|
-
object.errors.has_key?(attr_plain.to_sym) ||
|
139
|
-
object.errors.has_key?(attr_id.to_sym)
|
140
|
-
# rubocop:enable DeprecatedHashMethods
|
136
|
+
object.errors.key?(attr_plain.to_sym) ||
|
137
|
+
object.errors.key?(attr_id.to_sym)
|
141
138
|
end
|
142
139
|
|
143
140
|
# Defines the field method to use based on the attribute
|
@@ -178,6 +175,8 @@ module DryCrud
|
|
178
175
|
false
|
179
176
|
end
|
180
177
|
end
|
178
|
+
|
181
179
|
end
|
180
|
+
|
182
181
|
end
|
183
182
|
end
|
@@ -2,11 +2,13 @@
|
|
2
2
|
|
3
3
|
module DryCrud
|
4
4
|
module Table
|
5
|
+
|
5
6
|
# Adds action columns to the table builder.
|
6
7
|
# Predefined actions are available for show, edit and destroy.
|
7
8
|
# Additionally, a special col type to define cells linked to the show page
|
8
9
|
# of the row entry is provided.
|
9
10
|
module Actions
|
11
|
+
|
10
12
|
extend ActiveSupport::Concern
|
11
13
|
|
12
14
|
included do
|
@@ -61,7 +63,8 @@ module DryCrud
|
|
61
63
|
path,
|
62
64
|
html_options.merge(
|
63
65
|
data: { confirm: ti(:confirm_delete),
|
64
|
-
method: :delete }
|
66
|
+
method: :delete }
|
67
|
+
))
|
65
68
|
end
|
66
69
|
end
|
67
70
|
end
|
@@ -85,6 +88,8 @@ module DryCrud
|
|
85
88
|
def action_path(e)
|
86
89
|
block_given? ? yield(e) : path_args(e)
|
87
90
|
end
|
91
|
+
|
88
92
|
end
|
93
|
+
|
89
94
|
end
|
90
95
|
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
module DryCrud
|
4
4
|
module Table
|
5
|
+
|
5
6
|
# A simple helper to easily define tables listing several rows of the same
|
6
7
|
# data type.
|
7
8
|
#
|
@@ -67,7 +68,7 @@ module DryCrud
|
|
67
68
|
def to_html
|
68
69
|
content_tag :table, options do
|
69
70
|
content_tag(:thead, html_header) +
|
70
|
-
|
71
|
+
content_tag_nested(:tbody, entries) { |e| html_row(e) }
|
71
72
|
end
|
72
73
|
end
|
73
74
|
|
@@ -92,7 +93,7 @@ module DryCrud
|
|
92
93
|
|
93
94
|
# Renders the header row of the table.
|
94
95
|
def html_header
|
95
|
-
content_tag_nested(:tr, cols
|
96
|
+
content_tag_nested(:tr, cols, &:html_header)
|
96
97
|
end
|
97
98
|
|
98
99
|
# Renders a table row for the given entry.
|
@@ -111,6 +112,7 @@ module DryCrud
|
|
111
112
|
entries.first.class
|
112
113
|
end
|
113
114
|
end
|
115
|
+
|
114
116
|
end
|
115
117
|
end
|
116
118
|
end
|
@@ -2,11 +2,21 @@
|
|
2
2
|
|
3
3
|
module DryCrud
|
4
4
|
module Table
|
5
|
+
|
5
6
|
# Helper class to store column information.
|
6
|
-
class Col
|
7
|
+
class Col #:nodoc:
|
7
8
|
|
8
9
|
delegate :content_tag, :capture, to: :template
|
9
10
|
|
11
|
+
attr_reader :header, :html_options, :template, :block
|
12
|
+
|
13
|
+
def initialize(header, html_options, template, block)
|
14
|
+
@header = header
|
15
|
+
@html_options = html_options
|
16
|
+
@template = template
|
17
|
+
@block = block
|
18
|
+
end
|
19
|
+
|
10
20
|
# Runs the Col block for the given entry.
|
11
21
|
def content(entry)
|
12
22
|
entry.nil? ? '' : capture(entry, &block)
|
@@ -21,6 +31,7 @@ module DryCrud
|
|
21
31
|
def html_cell(entry)
|
22
32
|
content_tag(:td, content(entry), html_options)
|
23
33
|
end
|
34
|
+
|
24
35
|
end
|
25
36
|
end
|
26
37
|
end
|
@@ -2,10 +2,12 @@
|
|
2
2
|
|
3
3
|
module DryCrud
|
4
4
|
module Table
|
5
|
+
|
5
6
|
# Provides headers with sort links. Expects a method :sortable?(attr)
|
6
7
|
# in the template/controller to tell if an attribute is sortable or not.
|
7
8
|
# Extracted into an own module for convenience.
|
8
9
|
module Sorting
|
10
|
+
|
9
11
|
# Create a header with sort links and a mark for the current sort
|
10
12
|
# direction.
|
11
13
|
def sort_header(attr, label = nil)
|
@@ -32,13 +34,16 @@ module DryCrud
|
|
32
34
|
|
33
35
|
# Request params for the sort link.
|
34
36
|
def sort_params(attr)
|
35
|
-
params.
|
37
|
+
result = params.respond_to?(:to_unsafe_h) ? params.to_unsafe_h : params
|
38
|
+
result.merge(sort: attr, sort_dir: sort_dir(attr), only_path: true)
|
36
39
|
end
|
37
40
|
|
38
41
|
# The sort mark, if any, for the given attribute.
|
39
42
|
def current_mark(attr)
|
40
43
|
if current_sort?(attr)
|
44
|
+
# rubocop:disable Rails/OutputSafety
|
41
45
|
(sort_dir(attr) == 'asc' ? ' ↑' : ' ↓').html_safe
|
46
|
+
# rubocop:enable Rails/OutputSafety
|
42
47
|
else
|
43
48
|
''
|
44
49
|
end
|
@@ -58,6 +63,7 @@ module DryCrud
|
|
58
63
|
def params
|
59
64
|
template.params
|
60
65
|
end
|
66
|
+
|
61
67
|
end
|
62
68
|
end
|
63
69
|
end
|
data/app/helpers/form_helper.rb
CHANGED
@@ -27,16 +27,16 @@ module FormHelper
|
|
27
27
|
# if present. An options hash may be given as the last argument.
|
28
28
|
def standard_form(object, *attrs, &block)
|
29
29
|
plain_form(object, attrs.extract_options!) do |form|
|
30
|
-
content = form.error_messages
|
30
|
+
content = [form.error_messages]
|
31
31
|
|
32
|
-
if block_given?
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
32
|
+
content << if block_given?
|
33
|
+
capture(form, &block)
|
34
|
+
else
|
35
|
+
form.labeled_input_fields(*attrs)
|
36
|
+
end
|
37
37
|
|
38
38
|
content << form.standard_actions
|
39
|
-
content
|
39
|
+
safe_join(content)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -33,8 +33,8 @@ module FormatHelper
|
|
33
33
|
# Otherwise, calls format_type.
|
34
34
|
def format_attr(obj, attr)
|
35
35
|
format_with_helper(obj, attr) ||
|
36
|
-
|
37
|
-
|
36
|
+
format_association(obj, attr) ||
|
37
|
+
format_type(obj, attr)
|
38
38
|
end
|
39
39
|
|
40
40
|
# Renders a simple unordered list, which will
|
@@ -82,7 +82,7 @@ module FormatHelper
|
|
82
82
|
# Checks whether a format_{class}_{attr} or format_{attr} helper method is
|
83
83
|
# defined and calls it if is.
|
84
84
|
def format_with_helper(obj, attr)
|
85
|
-
class_name = obj.class.name.underscore.
|
85
|
+
class_name = obj.class.name.underscore.tr('/', '_')
|
86
86
|
format_type_attr_method = :"format_#{class_name}_#{attr}"
|
87
87
|
format_attr_method = :"format_#{attr}"
|
88
88
|
|
data/app/helpers/i18n_helper.rb
CHANGED
@@ -15,13 +15,13 @@ module I18nHelper
|
|
15
15
|
# - ...
|
16
16
|
# - global.{key}
|
17
17
|
def translate_inheritable(key, variables = {})
|
18
|
-
partial = @virtual_path ? @virtual_path.gsub(/.*\/_?/, '') : nil
|
18
|
+
partial = defined?(@virtual_path) ? @virtual_path.gsub(/.*\/_?/, '') : nil
|
19
19
|
defaults = inheritable_translation_defaults(key, partial)
|
20
20
|
variables[:default] ||= defaults
|
21
21
|
t(defaults.shift, variables)
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
alias ti translate_inheritable
|
25
25
|
|
26
26
|
# Translates the passed key for an active record association. This helper is
|
27
27
|
# used for rendering association dependent keys in forms like :no_entry,
|
@@ -40,7 +40,7 @@ module I18nHelper
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
|
43
|
+
alias ta translate_association
|
44
44
|
|
45
45
|
private
|
46
46
|
|
@@ -1,9 +1,12 @@
|
|
1
1
|
# encoding: UTF-8
|
2
|
+
require 'English'
|
2
3
|
|
3
4
|
# View helpers for basic functions used in various other helpers.
|
4
5
|
module UtilityHelper
|
5
6
|
|
6
|
-
|
7
|
+
# rubocop:disable Rails/OutputSafety
|
8
|
+
EMPTY_STRING = ' '.html_safe # non-breaking space asserts better css.
|
9
|
+
# rubocop:enable Rails/OutputSafety
|
7
10
|
|
8
11
|
# Render a content tag with the collected contents rendered
|
9
12
|
# by &block for each item in collection.
|
data/lib/dry_crud.rb
CHANGED
data/lib/dry_crud/engine.rb
CHANGED
@@ -1,18 +1,16 @@
|
|
1
1
|
module DryCrud
|
2
2
|
class Engine < Rails::Engine
|
3
|
-
|
4
|
-
|
5
|
-
initializer "dry_crud.field_error_proc" do |app|
|
3
|
+
initializer 'dry_crud.field_error_proc' do |_app|
|
6
4
|
# Fields with errors are directly styled in DryCrud::FormBuilder.
|
7
5
|
# Rails should just output the plain html tag.
|
8
|
-
ActionView::Base.field_error_proc = proc { |html_tag,
|
9
|
-
|
6
|
+
ActionView::Base.field_error_proc = proc { |html_tag, _instance| html_tag }
|
7
|
+
|
10
8
|
# Load dry_crud engine helpers first so that the application may override them.
|
11
9
|
paths = ApplicationController.helpers_path
|
12
|
-
if dry_crud_helpers = paths.detect {|p| p =~ /dry_crud(-\d+\.\d+\.\d+)?#{File::SEPARATOR}app#{File::SEPARATOR}helpers\z/ }
|
10
|
+
if dry_crud_helpers = paths.detect { |p| p =~ /dry_crud(-\d+\.\d+\.\d+)?#{File::SEPARATOR}app#{File::SEPARATOR}helpers\z/ }
|
13
11
|
paths.delete(dry_crud_helpers)
|
14
12
|
paths.prepend(dry_crud_helpers)
|
15
13
|
end
|
16
14
|
end
|
17
15
|
end
|
18
|
-
end
|
16
|
+
end
|
@@ -8,7 +8,6 @@ end
|
|
8
8
|
|
9
9
|
# Copies all dry_crud files to the rails application.
|
10
10
|
class DryCrudGenerator < DryCrudGeneratorBase
|
11
|
-
|
12
11
|
desc 'Copy all dry_crud files to the application.'
|
13
12
|
|
14
13
|
class_options %w(templates -t) => 'erb'
|
@@ -29,8 +28,8 @@ class DryCrudGenerator < DryCrudGeneratorBase
|
|
29
28
|
|
30
29
|
def should_copy?(file_source)
|
31
30
|
!file_source.end_with?(exclude_template) &&
|
32
|
-
|
33
|
-
|
31
|
+
!file_source.start_with?(exclude_test_dir) &&
|
32
|
+
file_source != 'INSTALL'
|
34
33
|
end
|
35
34
|
|
36
35
|
def copy_crud_test_model
|
@@ -45,7 +44,7 @@ class DryCrudGenerator < DryCrudGeneratorBase
|
|
45
44
|
end
|
46
45
|
|
47
46
|
def exclude_template
|
48
|
-
options[:templates].
|
47
|
+
options[:templates].casecmp('haml').zero? ? '.erb' : '.haml'
|
49
48
|
end
|
50
49
|
|
51
50
|
def exclude_test_dir
|
@@ -3,18 +3,17 @@
|
|
3
3
|
require 'rails/generators'
|
4
4
|
|
5
5
|
class DryCrudGeneratorBase < Rails::Generators::Base
|
6
|
-
|
7
6
|
def self.template_root
|
8
|
-
|
7
|
+
File.join(File.dirname(__FILE__), 'templates')
|
9
8
|
end
|
10
9
|
|
11
10
|
def self.gem_root
|
12
|
-
|
11
|
+
File.join(File.dirname(__FILE__), '..', '..', '..')
|
13
12
|
end
|
14
13
|
|
15
14
|
def self.source_paths
|
16
|
-
[
|
17
|
-
|
15
|
+
[gem_root,
|
16
|
+
template_root]
|
18
17
|
end
|
19
18
|
|
20
19
|
private
|
@@ -42,7 +41,7 @@ class DryCrudGeneratorBase < Rails::Generators::Base
|
|
42
41
|
end
|
43
42
|
end
|
44
43
|
|
45
|
-
def should_copy?(
|
44
|
+
def should_copy?(_file_source)
|
46
45
|
true
|
47
46
|
end
|
48
47
|
|
@@ -53,5 +52,4 @@ class DryCrudGeneratorBase < Rails::Generators::Base
|
|
53
52
|
template(file_source)
|
54
53
|
end
|
55
54
|
end
|
56
|
-
|
57
|
-
end
|
55
|
+
end
|