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.
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