dry_crud 3.0.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.rdoc +1 -1
  3. data/VERSION +1 -1
  4. data/app/controllers/crud_controller.rb +10 -8
  5. data/app/controllers/dry_crud/generic_model.rb +6 -4
  6. data/app/controllers/dry_crud/nestable.rb +9 -11
  7. data/app/controllers/dry_crud/rememberable.rb +5 -1
  8. data/app/controllers/dry_crud/render_callbacks.rb +40 -19
  9. data/app/controllers/dry_crud/searchable.rb +40 -31
  10. data/app/controllers/dry_crud/sortable.rb +36 -26
  11. data/app/controllers/list_controller.rb +2 -2
  12. data/app/helpers/dry_crud/form/builder.rb +21 -13
  13. data/app/helpers/dry_crud/form/control.rb +8 -9
  14. data/app/helpers/dry_crud/table/actions.rb +6 -1
  15. data/app/helpers/dry_crud/table/builder.rb +4 -2
  16. data/app/helpers/dry_crud/table/col.rb +12 -1
  17. data/app/helpers/dry_crud/table/sorting.rb +7 -1
  18. data/app/helpers/form_helper.rb +7 -7
  19. data/app/helpers/format_helper.rb +3 -3
  20. data/app/helpers/i18n_helper.rb +3 -3
  21. data/app/helpers/utility_helper.rb +4 -1
  22. data/lib/dry_crud.rb +1 -2
  23. data/lib/dry_crud/engine.rb +5 -7
  24. data/lib/generators/dry_crud/dry_crud_generator.rb +3 -4
  25. data/lib/generators/dry_crud/dry_crud_generator_base.rb +6 -8
  26. data/lib/generators/dry_crud/file_generator.rb +1 -3
  27. data/lib/generators/dry_crud/templates/spec/controllers/crud_test_models_controller_spec.rb +8 -18
  28. data/lib/generators/dry_crud/templates/spec/helpers/form_helper_spec.rb +1 -1
  29. data/lib/generators/dry_crud/templates/spec/helpers/utility_helper_spec.rb +4 -4
  30. data/lib/generators/dry_crud/templates/spec/support/crud_controller_examples.rb +7 -17
  31. data/lib/generators/dry_crud/templates/spec/support/crud_controller_test_helper.rb +13 -29
  32. data/lib/generators/dry_crud/templates/test/controllers/crud_test_models_controller_test.rb +25 -44
  33. data/lib/generators/dry_crud/templates/test/helpers/custom_assertions_test.rb +0 -1
  34. data/lib/generators/dry_crud/templates/test/helpers/dry_crud/form/builder_test.rb +3 -4
  35. data/lib/generators/dry_crud/templates/test/helpers/dry_crud/table/builder_test.rb +0 -2
  36. data/lib/generators/dry_crud/templates/test/helpers/form_helper_test.rb +2 -1
  37. data/lib/generators/dry_crud/templates/test/helpers/format_helper_test.rb +1 -1
  38. data/lib/generators/dry_crud/templates/test/helpers/table_helper_test.rb +8 -17
  39. data/lib/generators/dry_crud/templates/test/helpers/utility_helper_test.rb +3 -0
  40. data/lib/generators/dry_crud/templates/test/support/crud_controller_test_helper.rb +27 -30
  41. data/lib/generators/dry_crud/templates/test/support/crud_test_helper.rb +11 -13
  42. data/lib/generators/dry_crud/templates/test/support/crud_test_model.rb +7 -3
  43. data/lib/generators/dry_crud/templates/test/support/crud_test_models_controller.rb +5 -9
  44. data/lib/generators/dry_crud/templates/test/support/custom_assertions.rb +1 -1
  45. metadata +10 -11
@@ -11,9 +11,9 @@
11
11
  class ListController < ApplicationController
12
12
 
13
13
  include DryCrud::GenericModel
14
- include DryCrud::Nestable
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) || '&nbsp;'.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
- alias_method :integer_field, :number_field
101
- alias_method :float_field, :number_field
102
- alias_method :decimal_field, :number_field
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
- static_text(
118
- ta(:none_available, association(@object, attr)).html_safe)
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
- !v.options.key?(:if) &&
212
- !v.options.key?(:unless)
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
- list = @template.send(:instance_variable_get,
282
- :"@#{assoc.name.to_s.pluralize}")
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.merge(assoc.scope)
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
- url = @object.new_record? ? options[:cancel_url_new] :
307
- options[:cancel_url_edit]
308
- url || options[:cancel_url]
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
- INPUT_SPANS[:float_field] =
25
- INPUT_SPANS[:decimal_field] = 2
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
- content_tag(:div, content, class: "col-md-#{span}")
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
- # errors aint a Hash
137
- # rubocop:disable DeprecatedHashMethods
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
- content_tag_nested(:tbody, entries) { |e| html_row(e) }
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) { |c| c.html_header }
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 < Struct.new(:header, :html_options, :template, :block) #:nodoc:
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.merge(sort: attr, sort_dir: sort_dir(attr))
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' ? ' &uarr;' : ' &darr;').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
@@ -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
- content << capture(form, &block)
34
- else
35
- content << form.labeled_input_fields(*attrs)
36
- end
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.html_safe
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
- format_association(obj, attr) ||
37
- format_type(obj, attr)
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.gsub('/', '_')
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
 
@@ -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
- alias_method :ti, :translate_inheritable
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
- alias_method :ta, :translate_association
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
- EMPTY_STRING = '&nbsp;'.html_safe # non-breaking space asserts better css.
7
+ # rubocop:disable Rails/OutputSafety
8
+ EMPTY_STRING = '&nbsp;'.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.
@@ -1,5 +1,4 @@
1
1
  require 'dry_crud/engine'
2
2
 
3
3
  module DryCrud
4
-
5
- end
4
+ end
@@ -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, instance| 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
- !file_source.start_with?(exclude_test_dir) &&
33
- file_source != 'INSTALL'
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].downcase == 'haml' ? '.erb' : '.haml'
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
- File.join(File.dirname(__FILE__), 'templates')
7
+ File.join(File.dirname(__FILE__), 'templates')
9
8
  end
10
9
 
11
10
  def self.gem_root
12
- File.join(File.dirname(__FILE__), '..', '..', '..')
11
+ File.join(File.dirname(__FILE__), '..', '..', '..')
13
12
  end
14
13
 
15
14
  def self.source_paths
16
- [self.gem_root,
17
- self.template_root]
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?(file_source)
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