dry_crud 2.1.1 → 2.1.2
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.
- checksums.yaml +9 -9
- data/VERSION +1 -1
- data/app/assets/stylesheets/sample.scss +1 -1
- data/app/controllers/crud_controller.rb +1 -1
- data/app/controllers/dry_crud/generic_model.rb +45 -45
- data/app/controllers/dry_crud/nestable.rb +1 -1
- data/app/controllers/dry_crud/render_callbacks.rb +2 -0
- data/app/controllers/dry_crud/responder.rb +3 -0
- data/app/controllers/list_controller.rb +1 -1
- data/app/helpers/dry_crud/form/builder.rb +286 -261
- data/app/helpers/dry_crud/form/control.rb +156 -153
- data/app/helpers/dry_crud/table/actions.rb +69 -67
- data/app/helpers/dry_crud/table/builder.rb +96 -95
- data/app/helpers/dry_crud/table/col.rb +17 -16
- data/app/helpers/dry_crud/table/sorting.rb +48 -46
- data/app/helpers/format_helper.rb +2 -2
- data/app/helpers/table_helper.rb +2 -2
- data/lib/generators/dry_crud/file_generator.rb +2 -2
- data/lib/generators/dry_crud/templates/spec/controllers/crud_test_models_controller_spec.rb +4 -6
- data/lib/generators/dry_crud/templates/spec/helpers/dry_crud/form/builder_spec.rb +11 -11
- data/lib/generators/dry_crud/templates/spec/helpers/form_helper_spec.rb +21 -21
- data/lib/generators/dry_crud/templates/spec/helpers/format_helper_spec.rb +21 -17
- data/lib/generators/dry_crud/templates/spec/support/crud_controller_examples.rb +8 -8
- data/lib/generators/dry_crud/templates/spec/support/crud_controller_test_helper.rb +11 -1
- data/lib/generators/dry_crud/templates/test/controllers/crud_test_models_controller_test.rb +6 -6
- data/lib/generators/dry_crud/templates/test/helpers/custom_assertions_test.rb +1 -0
- data/lib/generators/dry_crud/templates/test/helpers/dry_crud/form/builder_test.rb +250 -245
- data/lib/generators/dry_crud/templates/test/helpers/dry_crud/table/builder_test.rb +141 -128
- data/lib/generators/dry_crud/templates/test/helpers/form_helper_test.rb +54 -54
- data/lib/generators/dry_crud/templates/test/helpers/format_helper_test.rb +4 -4
- data/lib/generators/dry_crud/templates/test/helpers/table_helper_test.rb +1 -1
- data/lib/generators/dry_crud/templates/test/support/crud_controller_test_helper.rb +3 -2
- data/lib/generators/dry_crud/templates/test/support/crud_test_helper.rb +8 -8
- data/lib/generators/dry_crud/templates/test/support/crud_test_model.rb +0 -2
- data/lib/generators/dry_crud/templates/test/support/crud_test_models_controller.rb +7 -7
- data/lib/generators/dry_crud/templates/test/support/custom_assertions.rb +3 -3
- metadata +6 -6
@@ -1,115 +1,116 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
module DryCrud
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
3
|
+
module DryCrud
|
4
|
+
module Table
|
5
|
+
# A simple helper to easily define tables listing several rows of the same
|
6
|
+
# data type.
|
7
|
+
#
|
8
|
+
# Example Usage:
|
9
|
+
# DryCrud::Table::Builder.table(entries, template) do |t|
|
10
|
+
# t.col('My Header', class: 'css') {|e| link_to 'Show', e }
|
11
|
+
# t.attrs :name, :city
|
12
|
+
# end
|
13
|
+
class Builder
|
14
|
+
|
15
|
+
include Sorting
|
16
|
+
include Actions
|
17
|
+
|
18
|
+
attr_reader :entries, :cols, :options, :template
|
19
|
+
|
20
|
+
delegate :content_tag, :format_attr, :column_type, :association, :dom_id,
|
21
|
+
:captionize, :add_css_class, :content_tag_nested,
|
22
|
+
to: :template
|
23
|
+
|
24
|
+
def initialize(entries, template, options = {})
|
25
|
+
@entries = entries
|
26
|
+
@template = template
|
27
|
+
@options = options
|
28
|
+
@cols = []
|
29
|
+
end
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
31
|
+
# Convenience method to directly generate a table. Renders a row for each
|
32
|
+
# entry in entries. Takes a block that gets the table object as parameter
|
33
|
+
# for configuration. Returns the generated html for the table.
|
34
|
+
def self.table(entries, template, options = {})
|
35
|
+
t = new(entries, template, options)
|
36
|
+
yield t
|
37
|
+
t.to_html
|
38
|
+
end
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
# Define a column for the table with the given header, the html_options
|
41
|
+
# used for each td and a block rendering the contents of a cell for the
|
42
|
+
# current entry. The columns appear in the order they are defined.
|
43
|
+
def col(header = '', html_options = {}, &block)
|
44
|
+
@cols << Col.new(header, html_options, @template, block)
|
45
|
+
end
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
47
|
+
# Convenience method to add one or more attribute columns.
|
48
|
+
# The attribute name will become the header, the cells will contain
|
49
|
+
# the formatted attribute value for the current entry.
|
50
|
+
def attrs(*attrs)
|
51
|
+
attrs.each do |a|
|
52
|
+
attr(a)
|
53
|
+
end
|
52
54
|
end
|
53
|
-
end
|
54
55
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
56
|
+
# Define a column for the given attribute and an optional header.
|
57
|
+
# If no header is given, the attribute name is used. The cell will
|
58
|
+
# contain the formatted attribute value for the current entry.
|
59
|
+
def attr(a, header = nil, html_options = {}, &block)
|
60
|
+
header ||= attr_header(a)
|
61
|
+
block ||= ->(e) { format_attr(e, a) }
|
62
|
+
add_css_class(html_options, align_class(a))
|
63
|
+
col(header, html_options, &block)
|
64
|
+
end
|
64
65
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
66
|
+
# Renders the table as HTML.
|
67
|
+
def to_html
|
68
|
+
content_tag :table, options do
|
69
|
+
content_tag(:thead, html_header) +
|
70
|
+
content_tag_nested(:tbody, entries) { |e| html_row(e) }
|
71
|
+
end
|
70
72
|
end
|
71
|
-
end
|
72
73
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
74
|
+
# Returns css classes used for alignment of the cell data.
|
75
|
+
# Based on the column type of the attribute.
|
76
|
+
def align_class(attr)
|
77
|
+
entry = entries.present? ? entry_class.new : nil
|
78
|
+
case column_type(entry, attr)
|
79
|
+
when :integer, :float, :decimal
|
80
|
+
'right' unless association(entry, attr, :belongs_to)
|
81
|
+
when :boolean
|
82
|
+
'center'
|
83
|
+
end
|
82
84
|
end
|
83
|
-
end
|
84
85
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
86
|
+
# Creates a header string for the given attr.
|
87
|
+
def attr_header(attr)
|
88
|
+
captionize(attr, entry_class)
|
89
|
+
end
|
89
90
|
|
90
|
-
|
91
|
+
private
|
91
92
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
93
|
+
# Renders the header row of the table.
|
94
|
+
def html_header
|
95
|
+
content_tag_nested(:tr, cols) { |c| c.html_header }
|
96
|
+
end
|
96
97
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
98
|
+
# Renders a table row for the given entry.
|
99
|
+
def html_row(entry)
|
100
|
+
attrs = {}
|
101
|
+
attrs[:id] = dom_id(entry) if entry.respond_to?(:to_key)
|
102
|
+
content_tag_nested(:tr, cols, attrs) { |c| c.html_cell(entry) }
|
103
|
+
end
|
103
104
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
105
|
+
# Determines the class of the table entries.
|
106
|
+
# All entries should be of the same type.
|
107
|
+
def entry_class
|
108
|
+
if entries.respond_to?(:klass)
|
109
|
+
entries.klass
|
110
|
+
else
|
111
|
+
entries.first.class
|
112
|
+
end
|
111
113
|
end
|
112
114
|
end
|
113
|
-
|
114
115
|
end
|
115
116
|
end
|
@@ -1,25 +1,26 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
module DryCrud
|
4
|
-
|
5
|
-
|
3
|
+
module DryCrud
|
4
|
+
module Table
|
5
|
+
# Helper class to store column information.
|
6
|
+
class Col < Struct.new(:header, :html_options, :template, :block) #:nodoc:
|
6
7
|
|
7
|
-
|
8
|
+
delegate :content_tag, :capture, to: :template
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
# Runs the Col block for the given entry.
|
11
|
+
def content(entry)
|
12
|
+
entry.nil? ? '' : capture(entry, &block)
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
# Renders the header cell of the Col.
|
16
|
+
def html_header
|
17
|
+
content_tag(:th, header, html_options)
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
# Renders a table cell for the given entry.
|
21
|
+
def html_cell(entry)
|
22
|
+
content_tag(:td, content(entry), html_options)
|
23
|
+
end
|
22
24
|
end
|
23
|
-
|
24
25
|
end
|
25
26
|
end
|
@@ -1,61 +1,63 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
module DryCrud
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
label
|
12
|
-
|
13
|
-
|
3
|
+
module DryCrud
|
4
|
+
module Table
|
5
|
+
# Provides headers with sort links. Expects a method :sortable?(attr)
|
6
|
+
# in the template/controller to tell if an attribute is sortable or not.
|
7
|
+
# Extracted into an own module for convenience.
|
8
|
+
module Sorting
|
9
|
+
# Create a header with sort links and a mark for the current sort
|
10
|
+
# direction.
|
11
|
+
def sort_header(attr, label = nil)
|
12
|
+
label ||= attr_header(attr)
|
13
|
+
template.link_to(label, sort_params(attr)) + current_mark(attr)
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
# Same as :attrs, except that it renders a sort link in the header
|
17
|
+
# if an attr is sortable.
|
18
|
+
def sortable_attrs(*attrs)
|
19
|
+
attrs.each { |a| sortable_attr(a) }
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
# Renders a sort link header, otherwise similar to :attr.
|
23
|
+
def sortable_attr(a, header = nil, &block)
|
24
|
+
if template.sortable?(a)
|
25
|
+
attr(a, sort_header(a, header), &block)
|
26
|
+
else
|
27
|
+
attr(a, header, &block)
|
28
|
+
end
|
27
29
|
end
|
28
|
-
end
|
29
30
|
|
30
|
-
|
31
|
+
private
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
# Request params for the sort link.
|
34
|
+
def sort_params(attr)
|
35
|
+
params.merge(sort: attr, sort_dir: sort_dir(attr))
|
36
|
+
end
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
# The sort mark, if any, for the given attribute.
|
39
|
+
def current_mark(attr)
|
40
|
+
if current_sort?(attr)
|
41
|
+
(sort_dir(attr) == 'asc' ? ' ↑' : ' ↓').html_safe
|
42
|
+
else
|
43
|
+
''
|
44
|
+
end
|
43
45
|
end
|
44
|
-
end
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
# Returns true if the given attribute is the current sort column.
|
48
|
+
def current_sort?(attr)
|
49
|
+
params[:sort] == attr.to_s
|
50
|
+
end
|
50
51
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
52
|
+
# The sort direction to use in the sort link for the given attribute.
|
53
|
+
def sort_dir(attr)
|
54
|
+
current_sort?(attr) && params[:sort_dir] == 'asc' ? 'desc' : 'asc'
|
55
|
+
end
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
|
57
|
+
# Delegate to template.
|
58
|
+
def params
|
59
|
+
template.params
|
60
|
+
end
|
59
61
|
end
|
60
62
|
end
|
61
63
|
end
|
@@ -38,7 +38,7 @@ module FormatHelper
|
|
38
38
|
# Renders a simple unordered list, which will
|
39
39
|
# simply render all passed items or yield them
|
40
40
|
# to your block.
|
41
|
-
def simple_list(items, ul_options = {}
|
41
|
+
def simple_list(items, ul_options = {})
|
42
42
|
content_tag_nested(:ul, items, ul_options) do |item|
|
43
43
|
content_tag(:li, block_given? ? yield(item) : f(item))
|
44
44
|
end
|
@@ -157,7 +157,7 @@ module FormatHelper
|
|
157
157
|
|
158
158
|
# Returns true if no link should be created when formatting the given
|
159
159
|
# association.
|
160
|
-
def assoc_link?(
|
160
|
+
def assoc_link?(_assoc, val)
|
161
161
|
respond_to?("#{val.class.model_name.singular_route_key}_path".to_sym)
|
162
162
|
end
|
163
163
|
|
data/app/helpers/table_helper.rb
CHANGED
@@ -15,7 +15,7 @@ module TableHelper
|
|
15
15
|
# appended to the attribute columns.
|
16
16
|
# If entries is empty, an appropriate message is rendered.
|
17
17
|
# An options hash may be given as the last argument.
|
18
|
-
def plain_table(entries, *attrs
|
18
|
+
def plain_table(entries, *attrs)
|
19
19
|
options = attrs.extract_options!
|
20
20
|
add_css_class(options, 'table table-striped table-hover')
|
21
21
|
builder = options.delete(:builder) || DryCrud::Table::Builder
|
@@ -73,7 +73,7 @@ module TableHelper
|
|
73
73
|
|
74
74
|
private
|
75
75
|
|
76
|
-
def explode_attrs_with_options(attrs
|
76
|
+
def explode_attrs_with_options(attrs)
|
77
77
|
options = attrs.extract_options!
|
78
78
|
if !block_given? && attrs.blank?
|
79
79
|
attrs = default_crud_attrs
|
@@ -10,7 +10,7 @@ module DryCrud
|
|
10
10
|
|
11
11
|
argument :filename, type: :string, desc: 'Name or part of the filename to copy. Must match exactly one file.'
|
12
12
|
|
13
|
-
def
|
13
|
+
def copy_matching_file
|
14
14
|
files = matching_files
|
15
15
|
case files.size
|
16
16
|
when 1
|
@@ -29,7 +29,7 @@ module DryCrud
|
|
29
29
|
|
30
30
|
def matching_files
|
31
31
|
all_template_files.collect do |root, files|
|
32
|
-
files.select do |f|
|
32
|
+
files.select do |f|
|
33
33
|
included = f.include?(filename)
|
34
34
|
@root_folder = root if included
|
35
35
|
included
|
@@ -195,7 +195,7 @@ describe CrudTestModelsController do
|
|
195
195
|
context '.js', format: :js, combine: 'ijs' do
|
196
196
|
it_should_respond
|
197
197
|
it_should_assign_entries
|
198
|
-
|
198
|
+
it { response.body.should == 'index js' }
|
199
199
|
end
|
200
200
|
end
|
201
201
|
|
@@ -318,6 +318,7 @@ describe CrudTestModelsController do
|
|
318
318
|
it_should_persist_entry(false)
|
319
319
|
it_should_not_have_flash(:notice)
|
320
320
|
it_should_not_have_flash(:alert)
|
321
|
+
it_should_render_error_json
|
321
322
|
|
322
323
|
it 'should not assign companions' do
|
323
324
|
assigns(:companions).should be_nil
|
@@ -327,8 +328,6 @@ describe CrudTestModelsController do
|
|
327
328
|
controller.called_callbacks.should ==
|
328
329
|
[:before_create, :before_save]
|
329
330
|
end
|
330
|
-
|
331
|
-
its(:body) { should match(/errors/) }
|
332
331
|
end
|
333
332
|
end
|
334
333
|
end
|
@@ -376,12 +375,11 @@ describe CrudTestModelsController do
|
|
376
375
|
context '.json', format: :json, combine: 'ujivp' do
|
377
376
|
it_should_respond(422)
|
378
377
|
it_should_not_have_flash(:notice)
|
378
|
+
it_should_render_error_json
|
379
379
|
|
380
380
|
it 'should have called the correct callbacks' do
|
381
381
|
controller.called_callbacks.should == [:before_update, :before_save]
|
382
382
|
end
|
383
|
-
|
384
|
-
its(:body) { should match(/errors/) }
|
385
383
|
end
|
386
384
|
end
|
387
385
|
|
@@ -414,7 +412,7 @@ describe CrudTestModelsController do
|
|
414
412
|
context '.json', format: :json, combine: 'djf' do
|
415
413
|
it_should_respond(422)
|
416
414
|
it_should_not_have_flash(:notice)
|
417
|
-
|
415
|
+
it_should_render_error_json
|
418
416
|
end
|
419
417
|
|
420
418
|
context 'callback', perform_request: false do
|