table-for 3.7.0 → 4.0.0.rc1
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 +4 -4
- data/.gitignore +2 -1
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +148 -110
- data/app/views/table_for/_table_for.html.erb +74 -47
- data/lib/table_for/base.rb +23 -20
- data/lib/table_for/version.rb +1 -1
- data/lib/table_for/view_additions.rb +1 -1
- data/lib/table_for.rb +9 -8
- data/spec/integration/table_for_spec.rb +26 -15
- data/spec/spec_helper.rb +14 -4
- data/spec/table_for/base_spec.rb +16 -26
- data/spec/table_for/view_additions_spec.rb +8 -8
- data/table-for.gemspec +2 -2
- metadata +17 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e5bed81d1e22d5fdf3b12ca65ad622183a29be000a0640e04839daf8b05f01f2
|
|
4
|
+
data.tar.gz: 8eedfdbe148548812fd11506a8b7d7e539357558a4f07d9862a7df5b952b047f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 37e7eda28341ee122acac91dcba49a6c2b3871e7568d65fe20dff95b92316abfb27f3b98f070f74f8020b002a2632382b870f41689f33011e9943df5a7ae9042
|
|
7
|
+
data.tar.gz: 73c19c3b50a34b241ab0221e8e5ad479cf1a4bce52d954ccf1897ab2e88bfc33bbd2440b3c95a4703a3307ca8a62a83ff52bd91e274b0defb0d3673d9d6e7f71
|
data/.gitignore
CHANGED
data/.rspec
ADDED
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.3.0
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,137 +1,175 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
table-for (
|
|
4
|
+
table-for (4.0.0.rc1)
|
|
5
|
+
blocks (>= 4.0.0)
|
|
5
6
|
rails (>= 3.0.0)
|
|
6
|
-
with_template (~> 0.2.0)
|
|
7
7
|
|
|
8
8
|
GEM
|
|
9
9
|
remote: http://rubygems.org/
|
|
10
10
|
specs:
|
|
11
|
-
|
|
12
|
-
actionpack (=
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
activesupport (=
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
11
|
+
actioncable (5.2.8.1)
|
|
12
|
+
actionpack (= 5.2.8.1)
|
|
13
|
+
nio4r (~> 2.0)
|
|
14
|
+
websocket-driver (>= 0.6.1)
|
|
15
|
+
actionmailer (5.2.8.1)
|
|
16
|
+
actionpack (= 5.2.8.1)
|
|
17
|
+
actionview (= 5.2.8.1)
|
|
18
|
+
activejob (= 5.2.8.1)
|
|
19
|
+
mail (~> 2.5, >= 2.5.4)
|
|
20
|
+
rails-dom-testing (~> 2.0)
|
|
21
|
+
actionpack (5.2.8.1)
|
|
22
|
+
actionview (= 5.2.8.1)
|
|
23
|
+
activesupport (= 5.2.8.1)
|
|
24
|
+
rack (~> 2.0, >= 2.0.8)
|
|
25
|
+
rack-test (>= 0.6.3)
|
|
26
|
+
rails-dom-testing (~> 2.0)
|
|
27
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
|
28
|
+
actionview (5.2.8.1)
|
|
29
|
+
activesupport (= 5.2.8.1)
|
|
30
|
+
builder (~> 3.1)
|
|
31
|
+
erubi (~> 1.4)
|
|
32
|
+
rails-dom-testing (~> 2.0)
|
|
33
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
|
34
|
+
activejob (5.2.8.1)
|
|
35
|
+
activesupport (= 5.2.8.1)
|
|
36
|
+
globalid (>= 0.3.6)
|
|
37
|
+
activemodel (5.2.8.1)
|
|
38
|
+
activesupport (= 5.2.8.1)
|
|
39
|
+
activerecord (5.2.8.1)
|
|
40
|
+
activemodel (= 5.2.8.1)
|
|
41
|
+
activesupport (= 5.2.8.1)
|
|
42
|
+
arel (>= 9.0)
|
|
43
|
+
activestorage (5.2.8.1)
|
|
44
|
+
actionpack (= 5.2.8.1)
|
|
45
|
+
activerecord (= 5.2.8.1)
|
|
46
|
+
marcel (~> 1.0.0)
|
|
47
|
+
activesupport (5.2.8.1)
|
|
48
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
49
|
+
i18n (>= 0.7, < 2)
|
|
50
|
+
minitest (~> 5.1)
|
|
51
|
+
tzinfo (~> 1.1)
|
|
52
|
+
arel (9.0.0)
|
|
53
|
+
blocks (4.0.1)
|
|
42
54
|
rails (>= 3.0.0)
|
|
43
|
-
builder (3.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
builder (3.2.4)
|
|
56
|
+
concurrent-ruby (1.2.3)
|
|
57
|
+
crass (1.0.6)
|
|
58
|
+
date (3.3.4)
|
|
59
|
+
diff-lcs (1.3)
|
|
60
|
+
erubi (1.12.0)
|
|
61
|
+
globalid (1.1.0)
|
|
62
|
+
activesupport (>= 5.0)
|
|
63
|
+
i18n (1.14.4)
|
|
64
|
+
concurrent-ruby (~> 1.0)
|
|
65
|
+
loofah (2.22.0)
|
|
66
|
+
crass (~> 1.0.2)
|
|
67
|
+
nokogiri (>= 1.12.0)
|
|
68
|
+
mail (2.8.1)
|
|
69
|
+
mini_mime (>= 0.1.1)
|
|
70
|
+
net-imap
|
|
71
|
+
net-pop
|
|
72
|
+
net-smtp
|
|
73
|
+
marcel (1.0.4)
|
|
56
74
|
metaclass (0.0.1)
|
|
57
|
-
|
|
58
|
-
|
|
75
|
+
method_source (1.0.0)
|
|
76
|
+
mini_mime (1.1.5)
|
|
77
|
+
mini_portile2 (2.8.5)
|
|
78
|
+
minitest (5.22.3)
|
|
59
79
|
mocha (0.10.3)
|
|
60
80
|
metaclass (~> 0.0.1)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
actionpack (=
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
net-imap (0.4.10)
|
|
82
|
+
date
|
|
83
|
+
net-protocol
|
|
84
|
+
net-pop (0.1.2)
|
|
85
|
+
net-protocol
|
|
86
|
+
net-protocol (0.2.2)
|
|
87
|
+
timeout
|
|
88
|
+
net-smtp (0.4.0.1)
|
|
89
|
+
net-protocol
|
|
90
|
+
nio4r (2.7.1)
|
|
91
|
+
nokogiri (1.16.3)
|
|
92
|
+
mini_portile2 (~> 2.8.2)
|
|
93
|
+
racc (~> 1.4)
|
|
94
|
+
racc (1.7.3)
|
|
95
|
+
rack (2.2.9)
|
|
96
|
+
rack-test (2.1.0)
|
|
97
|
+
rack (>= 1.3)
|
|
98
|
+
rails (5.2.8.1)
|
|
99
|
+
actioncable (= 5.2.8.1)
|
|
100
|
+
actionmailer (= 5.2.8.1)
|
|
101
|
+
actionpack (= 5.2.8.1)
|
|
102
|
+
actionview (= 5.2.8.1)
|
|
103
|
+
activejob (= 5.2.8.1)
|
|
104
|
+
activemodel (= 5.2.8.1)
|
|
105
|
+
activerecord (= 5.2.8.1)
|
|
106
|
+
activestorage (= 5.2.8.1)
|
|
107
|
+
activesupport (= 5.2.8.1)
|
|
108
|
+
bundler (>= 1.3.0)
|
|
109
|
+
railties (= 5.2.8.1)
|
|
110
|
+
sprockets-rails (>= 2.0.0)
|
|
111
|
+
rails-dom-testing (2.2.0)
|
|
112
|
+
activesupport (>= 5.0.0)
|
|
113
|
+
minitest
|
|
114
|
+
nokogiri (>= 1.6)
|
|
115
|
+
rails-html-sanitizer (1.6.0)
|
|
116
|
+
loofah (~> 2.21)
|
|
117
|
+
nokogiri (~> 1.14)
|
|
118
|
+
railties (5.2.8.1)
|
|
119
|
+
actionpack (= 5.2.8.1)
|
|
120
|
+
activesupport (= 5.2.8.1)
|
|
121
|
+
method_source
|
|
84
122
|
rake (>= 0.8.7)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
rspec-core (3.4.1)
|
|
91
|
-
rspec-support (~> 3.4.0)
|
|
92
|
-
rspec-expectations (3.4.0)
|
|
123
|
+
thor (>= 0.19.0, < 2.0)
|
|
124
|
+
rake (13.1.0)
|
|
125
|
+
rspec-core (3.8.2)
|
|
126
|
+
rspec-support (~> 3.8.0)
|
|
127
|
+
rspec-expectations (3.8.4)
|
|
93
128
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
94
|
-
rspec-support (~> 3.
|
|
95
|
-
rspec-mocks (3.
|
|
129
|
+
rspec-support (~> 3.8.0)
|
|
130
|
+
rspec-mocks (3.8.1)
|
|
96
131
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
97
|
-
rspec-support (~> 3.
|
|
98
|
-
rspec-rails (3.
|
|
99
|
-
actionpack (>= 3.0
|
|
100
|
-
activesupport (>= 3.0
|
|
101
|
-
railties (>= 3.0
|
|
102
|
-
rspec-core (~> 3.
|
|
103
|
-
rspec-expectations (~> 3.
|
|
104
|
-
rspec-mocks (~> 3.
|
|
105
|
-
rspec-support (~> 3.
|
|
106
|
-
rspec-support (3.
|
|
107
|
-
sprockets (
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
132
|
+
rspec-support (~> 3.8.0)
|
|
133
|
+
rspec-rails (3.8.2)
|
|
134
|
+
actionpack (>= 3.0)
|
|
135
|
+
activesupport (>= 3.0)
|
|
136
|
+
railties (>= 3.0)
|
|
137
|
+
rspec-core (~> 3.8.0)
|
|
138
|
+
rspec-expectations (~> 3.8.0)
|
|
139
|
+
rspec-mocks (~> 3.8.0)
|
|
140
|
+
rspec-support (~> 3.8.0)
|
|
141
|
+
rspec-support (3.8.2)
|
|
142
|
+
sprockets (4.2.1)
|
|
143
|
+
concurrent-ruby (~> 1.0)
|
|
144
|
+
rack (>= 2.2.4, < 4)
|
|
145
|
+
sprockets-rails (3.4.2)
|
|
146
|
+
actionpack (>= 5.2)
|
|
147
|
+
activesupport (>= 5.2)
|
|
148
|
+
sprockets (>= 3.0.0)
|
|
149
|
+
sqlite3 (1.7.3)
|
|
150
|
+
mini_portile2 (~> 2.8.0)
|
|
113
151
|
supermodel (0.1.4)
|
|
114
152
|
activemodel (>= 3.0.0.beta)
|
|
115
|
-
thor (
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
rails (>= 3.0.0)
|
|
153
|
+
thor (1.3.1)
|
|
154
|
+
thread_safe (0.3.6)
|
|
155
|
+
timeout (0.4.1)
|
|
156
|
+
tzinfo (1.2.11)
|
|
157
|
+
thread_safe (~> 0.1)
|
|
158
|
+
websocket-driver (0.7.6)
|
|
159
|
+
websocket-extensions (>= 0.1.0)
|
|
160
|
+
websocket-extensions (0.1.5)
|
|
161
|
+
with_model (2.1.2)
|
|
162
|
+
activerecord (>= 4.2, < 6.0)
|
|
126
163
|
xml-simple (1.1.1)
|
|
127
164
|
|
|
128
165
|
PLATFORMS
|
|
129
166
|
ruby
|
|
130
167
|
|
|
131
168
|
DEPENDENCIES
|
|
169
|
+
blocks
|
|
132
170
|
mocha (= 0.10.3)
|
|
133
171
|
nokogiri
|
|
134
|
-
rspec-rails (
|
|
172
|
+
rspec-rails (~> 3.8)
|
|
135
173
|
sqlite3
|
|
136
174
|
supermodel
|
|
137
175
|
table-for!
|
|
@@ -139,4 +177,4 @@ DEPENDENCIES
|
|
|
139
177
|
xml-simple (= 1.1.1)
|
|
140
178
|
|
|
141
179
|
BUNDLED WITH
|
|
142
|
-
|
|
180
|
+
2.5.5
|
|
@@ -1,77 +1,104 @@
|
|
|
1
|
-
<% table.define :table
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
<% table.define :table,
|
|
2
|
+
wrapper: :content_tag,
|
|
3
|
+
wrapper_html_option: :table_html,
|
|
4
|
+
wrapper_tag: :table do %>
|
|
5
|
+
<%= table.render :header %>
|
|
6
|
+
<%= table.render :body %>
|
|
7
|
+
<%= table.render :footer %>
|
|
7
8
|
<% end %>
|
|
8
9
|
|
|
9
|
-
<% table.define :header
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
<%
|
|
10
|
+
<% table.define :header,
|
|
11
|
+
wrap_all: :thead_tag,
|
|
12
|
+
wrapper: :header_row do |options| %>
|
|
13
|
+
<% table.columns.each do |column| %>
|
|
14
|
+
<%#
|
|
15
|
+
Passing column twice has the effect of both passing column as the first argument to
|
|
16
|
+
the definition of :header_column and also merging its options into the generated
|
|
17
|
+
Blocks::RuntimeContext
|
|
18
|
+
%>
|
|
19
|
+
<%= table.render :header_column, column, column %>
|
|
20
|
+
<% end %>
|
|
13
21
|
<% end %>
|
|
14
22
|
|
|
15
|
-
<% table.define :
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
<% table.define :thead_tag,
|
|
24
|
+
with: :content_tag,
|
|
25
|
+
html_option: :thead_html,
|
|
26
|
+
tag: thead_tag if thead_tag %>
|
|
27
|
+
|
|
28
|
+
<% table.define :header_row,
|
|
29
|
+
with: :content_tag,
|
|
30
|
+
html_option: :header_row_html,
|
|
31
|
+
tag: :tr %>
|
|
20
32
|
|
|
21
33
|
<% table.define :header_column do |column, options| %>
|
|
22
34
|
<%= content_tag :th, table.header_column_html(column, options) do %>
|
|
23
|
-
<%= table.render "#{column.name}_header", column
|
|
35
|
+
<%= table.render "#{column.name}_header", column %>
|
|
24
36
|
<% end %>
|
|
25
37
|
<% end %>
|
|
26
38
|
|
|
27
39
|
<%# Define a header block for each column, named using that column's name with the word "_header" appended to it %>
|
|
28
|
-
<% table.
|
|
29
|
-
|
|
40
|
+
<% table.columns.each do |column| %>
|
|
41
|
+
<% table.define "#{column.name}_header" do |options| %>
|
|
42
|
+
<%= table.header_cell_content(column, options) %>
|
|
43
|
+
<% end %>
|
|
30
44
|
<% end %>
|
|
31
45
|
|
|
32
46
|
<% table.define :body do |options| %>
|
|
33
|
-
<%= table.
|
|
47
|
+
<%= table.content_tag options[:tbody_tag], options[:tbody_html] do %>
|
|
34
48
|
<%= table.render :data_row, :collection => records %>
|
|
35
49
|
<% end %>
|
|
36
50
|
<% end %>
|
|
37
51
|
|
|
38
|
-
<% table.define :data_row do |
|
|
52
|
+
<% table.define :data_row do |options| %>
|
|
53
|
+
<% record = options[:object] %>
|
|
39
54
|
<% table.set_current_record_and_index(record, options[:current_index]) %>
|
|
40
55
|
<%= content_tag :tr, table.call_each_hash_value_with_params(options[:data_row_html], record) do %>
|
|
41
|
-
|
|
56
|
+
<% table.columns.each do |column| %>
|
|
57
|
+
<%= table.render column.name,
|
|
58
|
+
record,
|
|
59
|
+
column,
|
|
60
|
+
defaults: {
|
|
61
|
+
wrapper: :data_column
|
|
62
|
+
} %>
|
|
63
|
+
<% end %>
|
|
42
64
|
<% end %>
|
|
43
65
|
<% end %>
|
|
44
66
|
|
|
45
|
-
<% table.define :data_column
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
column) do
|
|
50
|
-
table.render(column.name, record, column, column.options)
|
|
51
|
-
end %>
|
|
52
|
-
<% end %>
|
|
67
|
+
<% table.define :data_column,
|
|
68
|
+
with: :content_tag,
|
|
69
|
+
html_option: :data_column_html,
|
|
70
|
+
tag: :td %>
|
|
53
71
|
|
|
54
72
|
<%# Define a block for each column, named using that column's name %>
|
|
55
|
-
<% table.
|
|
56
|
-
|
|
57
|
-
|
|
73
|
+
<% table.columns.each do |column| %>
|
|
74
|
+
<% table.define column.name, :link_html => {} do |record, column, options| -%>
|
|
75
|
+
<%= table.cell_content(record, column, options) -%>
|
|
76
|
+
<% end -%>
|
|
77
|
+
<% end %>
|
|
58
78
|
|
|
59
|
-
<% table.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
79
|
+
<% if table.block_defined?(:footer_content) %>
|
|
80
|
+
<% table.define :footer,
|
|
81
|
+
wrap_all: :tfoot_tag,
|
|
82
|
+
outer_wrapper: :footer_row,
|
|
83
|
+
wrapper: :footer_column,
|
|
84
|
+
with: :footer_content
|
|
85
|
+
%>
|
|
64
86
|
|
|
65
|
-
<% table.define :
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
<% end if table.defined?(:footer_content) %>
|
|
87
|
+
<% table.define :tfoot_tag,
|
|
88
|
+
with: :content_tag,
|
|
89
|
+
html_option: :tfoot_html,
|
|
90
|
+
tag: tfoot_tag if tfoot_tag %>
|
|
70
91
|
|
|
71
|
-
<% table.define :
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
92
|
+
<% table.define :footer_row,
|
|
93
|
+
with: :content_tag,
|
|
94
|
+
html_option: :footer_row_html,
|
|
95
|
+
tag: :tr %>
|
|
96
|
+
|
|
97
|
+
<% table.define :footer_column,
|
|
98
|
+
with: :content_tag,
|
|
99
|
+
html_option: :footer_column_html,
|
|
100
|
+
tag: :td,
|
|
101
|
+
html: { colspan: table.columns.length } %>
|
|
102
|
+
<% end %>
|
|
76
103
|
|
|
77
104
|
<%= table.render :table %>
|
data/lib/table_for/base.rb
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
require 'with_template'
|
|
2
1
|
require 'blocks'
|
|
3
2
|
|
|
4
3
|
module TableFor
|
|
5
|
-
class Base <
|
|
6
|
-
alias columns queued_blocks
|
|
7
|
-
|
|
4
|
+
class Base < Blocks::Builder
|
|
8
5
|
attr_accessor :current_record
|
|
9
6
|
alias_method :current_row, :current_record
|
|
10
7
|
|
|
11
8
|
attr_accessor :current_index
|
|
12
9
|
alias_method :current_row_index, :current_index
|
|
13
10
|
|
|
11
|
+
attr_accessor :columns
|
|
14
12
|
|
|
15
13
|
def initialize(view, options={})
|
|
16
|
-
|
|
14
|
+
self.columns = []
|
|
15
|
+
super(view, options)
|
|
17
16
|
end
|
|
18
17
|
|
|
19
18
|
def header(name, options={}, &block)
|
|
@@ -26,20 +25,20 @@ module TableFor
|
|
|
26
25
|
|
|
27
26
|
def column(*args, &block)
|
|
28
27
|
options = args.extract_options!
|
|
29
|
-
|
|
28
|
+
columns << define(*args, options, &block).clone
|
|
30
29
|
if options[:link_url] ||
|
|
31
30
|
options[:link_action] ||
|
|
32
31
|
options[:link_method] ||
|
|
33
32
|
options[:link_confirm] ||
|
|
34
33
|
options[:link]
|
|
35
|
-
|
|
36
|
-
options = options.merge(column
|
|
34
|
+
surround(columns.last.name) do |content_block, record, column, options|
|
|
35
|
+
# options = options.merge(column)
|
|
37
36
|
url = if options[:link_url]
|
|
38
37
|
call_with_params(options[:link_url], record)
|
|
39
38
|
else
|
|
40
39
|
[
|
|
41
40
|
options[:link_action],
|
|
42
|
-
options[:link_namespace]
|
|
41
|
+
options[:link_namespace],
|
|
43
42
|
record
|
|
44
43
|
].flatten.compact
|
|
45
44
|
end
|
|
@@ -58,7 +57,7 @@ module TableFor
|
|
|
58
57
|
if options[:sortable]
|
|
59
58
|
order = options[:order] ? options[:order].to_s : column.name.to_s
|
|
60
59
|
|
|
61
|
-
sort_modes = options[:sort_modes].presence ||
|
|
60
|
+
sort_modes = options[:sort_modes].presence || options_set.default_options[:sort_modes]
|
|
62
61
|
current_sort_mode = (view.params[:order] != order || view.params[:sort_mode].blank?) ? nil : view.params[:sort_mode]
|
|
63
62
|
current_sort_mode = sort_modes[sort_modes.index(current_sort_mode.to_sym)] rescue nil if current_sort_mode
|
|
64
63
|
sort_class = "sorting#{"_#{current_sort_mode}" if current_sort_mode}"
|
|
@@ -68,7 +67,7 @@ module TableFor
|
|
|
68
67
|
header_column_html
|
|
69
68
|
end
|
|
70
69
|
|
|
71
|
-
def header_cell_content(column, options
|
|
70
|
+
def header_cell_content(column, options)
|
|
72
71
|
unless options[:header] == false
|
|
73
72
|
header_sort_link(column, options) do
|
|
74
73
|
if options[:header]
|
|
@@ -76,7 +75,7 @@ module TableFor
|
|
|
76
75
|
elsif column.anonymous
|
|
77
76
|
nil
|
|
78
77
|
else
|
|
79
|
-
I18n.t("#{translation_lookup_prefix}.#{column.name.to_s.underscore}", :default => column.name.to_s.titleize)
|
|
78
|
+
I18n.t("#{translation_lookup_prefix(options)}.#{column.name.to_s.underscore}", :default => column.name.to_s.titleize)
|
|
80
79
|
end
|
|
81
80
|
end
|
|
82
81
|
end
|
|
@@ -105,7 +104,7 @@ module TableFor
|
|
|
105
104
|
if options[:sortable] && (options[:header] || !column.anonymous)
|
|
106
105
|
order = options[:order] ? options[:order].to_s : column.name.to_s
|
|
107
106
|
|
|
108
|
-
sort_modes = options[:sort_modes].presence ||
|
|
107
|
+
sort_modes = options[:sort_modes].presence || options_set.default_options[:sort_modes]
|
|
109
108
|
current_sort_mode = (view.params[:order] != order || view.params[:sort_mode].blank?) ? nil : view.params[:sort_mode]
|
|
110
109
|
next_sort_mode_index = sort_modes.index(current_sort_mode.to_sym) + 1 rescue 0
|
|
111
110
|
if next_sort_mode_index == sort_modes.length
|
|
@@ -128,14 +127,18 @@ module TableFor
|
|
|
128
127
|
end
|
|
129
128
|
end
|
|
130
129
|
|
|
130
|
+
def call_each_hash_value_with_params(*)
|
|
131
|
+
super
|
|
132
|
+
end
|
|
133
|
+
|
|
131
134
|
private
|
|
132
|
-
def translation_lookup_prefix
|
|
133
|
-
if
|
|
134
|
-
"activerecord.attributes.#{
|
|
135
|
-
elsif
|
|
136
|
-
"activerecord.attributes.#{
|
|
137
|
-
elsif
|
|
138
|
-
"tables.columns.#{
|
|
135
|
+
def translation_lookup_prefix(options)
|
|
136
|
+
if options[:records].respond_to?(:model)
|
|
137
|
+
"activerecord.attributes.#{options[:records].model.to_s.underscore}"
|
|
138
|
+
elsif options[:records].all? {|record| record.is_a?(ActiveRecord::Base) && record.class == options[:records].first.class }
|
|
139
|
+
"activerecord.attributes.#{options[:records].first.class.to_s.underscore}"
|
|
140
|
+
elsif options[:records].all? {|record| record.class == options[:records].first.class }
|
|
141
|
+
"tables.columns.#{options[:records].first.class.to_s.underscore}"
|
|
139
142
|
else
|
|
140
143
|
"tables.columns"
|
|
141
144
|
end
|
data/lib/table_for/version.rb
CHANGED
|
@@ -2,7 +2,7 @@ module TableFor
|
|
|
2
2
|
module ViewAdditions
|
|
3
3
|
module ClassMethods
|
|
4
4
|
def table_for(records, options={}, &block)
|
|
5
|
-
TableFor::Base.new(self, options.merge(:
|
|
5
|
+
TableFor::Base.new(self, TableFor.config.merge(options.merge(builder_variable: :table, records: records))).render(partial: "table_for/table_for", &block)
|
|
6
6
|
end
|
|
7
7
|
end
|
|
8
8
|
end
|
data/lib/table_for.rb
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
require "
|
|
2
|
-
require "with_template"
|
|
1
|
+
require "blocks"
|
|
3
2
|
require "table_for/engine"
|
|
4
3
|
|
|
5
4
|
module TableFor
|
|
@@ -7,12 +6,14 @@ module TableFor
|
|
|
7
6
|
autoload :ViewAdditions, "table_for/view_additions"
|
|
8
7
|
|
|
9
8
|
mattr_accessor :config
|
|
10
|
-
@@config =
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
@@config = {
|
|
10
|
+
defaults: {
|
|
11
|
+
thead_tag: :thead,
|
|
12
|
+
tbody_tag: :tbody,
|
|
13
|
+
tfoot_tag: :tfoot,
|
|
14
|
+
sort_modes: [:asc, :desc]
|
|
15
|
+
}
|
|
16
|
+
}
|
|
16
17
|
|
|
17
18
|
# Default way to setup TableFor
|
|
18
19
|
def self.setup
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
|
+
require 'byebug'
|
|
2
3
|
|
|
3
|
-
describe "
|
|
4
|
-
with_model :
|
|
4
|
+
describe "table-for" do
|
|
5
|
+
with_model :User do
|
|
5
6
|
table do |t|
|
|
6
|
-
t.
|
|
7
|
-
t.string
|
|
8
|
-
t.string
|
|
9
|
-
t.string "last_name"
|
|
7
|
+
t.string :email
|
|
8
|
+
t.string :first_name
|
|
9
|
+
t.string :last_name
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
|
|
@@ -17,12 +17,13 @@ describe "table_for" do
|
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
before
|
|
21
|
-
User.create!
|
|
22
|
-
User.create!
|
|
23
|
-
User.create!
|
|
20
|
+
before do
|
|
21
|
+
User.create! :email => "andrew.hunter@livingsocial.com", :first_name => "Andrew", :last_name => "Hunter"
|
|
22
|
+
User.create! :email => "todd.fisher@livingsocial.com", :first_name => "Todd", :last_name => "Fisher"
|
|
23
|
+
User.create! :email => "jon.phillips@livingsocial.com", :first_name => "Jon", :last_name => "Phillips"
|
|
24
24
|
@users = User.all
|
|
25
25
|
@view = ActionView::Base.new("app/views")
|
|
26
|
+
|
|
26
27
|
@view.class.send(:define_method, :user_path) do |user|
|
|
27
28
|
"/users/#{user.id}"
|
|
28
29
|
end
|
|
@@ -58,7 +59,7 @@ describe "table_for" do
|
|
|
58
59
|
table.column :last_name
|
|
59
60
|
end
|
|
60
61
|
|
|
61
|
-
buffer.strip.should eql "My new table definition"
|
|
62
|
+
buffer.strip.should eql "<table>My new table definition</table>"
|
|
62
63
|
end
|
|
63
64
|
|
|
64
65
|
it "should be able to specify html attributes" do
|
|
@@ -72,7 +73,7 @@ describe "table_for" do
|
|
|
72
73
|
it "should be able to replace the thead block" do
|
|
73
74
|
buffer = @view.table_for @users[0,1] do |table|
|
|
74
75
|
table.define :header do
|
|
75
|
-
"<
|
|
76
|
+
"<th>My new header definition</th>".html_safe
|
|
76
77
|
end
|
|
77
78
|
table.column :first_name
|
|
78
79
|
end
|
|
@@ -232,7 +233,7 @@ describe "table_for" do
|
|
|
232
233
|
it "should be able to override the definition for a particular column header block" do
|
|
233
234
|
buffer = @view.table_for @users[0,1] do |table|
|
|
234
235
|
table.column :email, :header => "Email Address"
|
|
235
|
-
table.define :email_header do |
|
|
236
|
+
table.define :email_header do |options|
|
|
236
237
|
"My Own Header (Replaced #{options[:header]})"
|
|
237
238
|
end
|
|
238
239
|
end
|
|
@@ -248,7 +249,7 @@ describe "table_for" do
|
|
|
248
249
|
it "should be able to override the definition for a particular column header block using the table_for 'header' method" do
|
|
249
250
|
buffer = @view.table_for @users[0,1] do |table|
|
|
250
251
|
table.column :email, :header => "Email Address"
|
|
251
|
-
table.header :email do |
|
|
252
|
+
table.header :email do |options|
|
|
252
253
|
"My Own Header (Replaced #{options[:header]})"
|
|
253
254
|
end
|
|
254
255
|
end
|
|
@@ -458,7 +459,7 @@ describe "table_for" do
|
|
|
458
459
|
describe "data_column block" do
|
|
459
460
|
it "should be able to replace the data_column block" do
|
|
460
461
|
buffer = @view.table_for @users[0, 1] do |table|
|
|
461
|
-
table.define :data_column do |
|
|
462
|
+
table.define :data_column do |content_block, user, column, options|
|
|
462
463
|
"<td>#{column.name.to_s.titleize} value is #{user.send(column.name)}</td>".html_safe
|
|
463
464
|
end
|
|
464
465
|
table.column :email
|
|
@@ -545,6 +546,11 @@ describe "table_for" do
|
|
|
545
546
|
describe "column data contents block" do
|
|
546
547
|
context "when passing a link param" do
|
|
547
548
|
it "render a link surrounding a table cell's content when it is true" do
|
|
549
|
+
# a little bit of hackery here as different versions of Rails start changing how url_for
|
|
550
|
+
# and routing works, so harder to simulate here
|
|
551
|
+
@view.class.define_method(:url_for) do |args|
|
|
552
|
+
user_path(args.first)
|
|
553
|
+
end
|
|
548
554
|
buffer = @view.table_for @users do |table|
|
|
549
555
|
table.column :email, link: true
|
|
550
556
|
end
|
|
@@ -576,6 +582,11 @@ describe "table_for" do
|
|
|
576
582
|
@view.class.send(:define_method, :profile_user_path) do |user|
|
|
577
583
|
"/profile/users/#{user.id}"
|
|
578
584
|
end
|
|
585
|
+
# a little bit of hackery here as different versions of Rails start changing how url_for
|
|
586
|
+
# and routing works, so harder to simulate here
|
|
587
|
+
@view.class.define_method(:url_for) do |args|
|
|
588
|
+
send("#{args.first}_user_path", args.last)
|
|
589
|
+
end
|
|
579
590
|
buffer = @view.table_for @users, link_namespace: :admin do |table|
|
|
580
591
|
table.column :email, link: true
|
|
581
592
|
table.column :id, link_namespace: :profile, link: true
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
require '
|
|
1
|
+
begin
|
|
2
|
+
require 'debugger'
|
|
3
|
+
rescue LoadError
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
begin
|
|
7
|
+
require 'byebug'
|
|
8
|
+
rescue LoadError
|
|
9
|
+
end
|
|
3
10
|
|
|
4
|
-
|
|
11
|
+
begin
|
|
12
|
+
require 'ruby-debug'
|
|
13
|
+
rescue LoadError
|
|
14
|
+
end
|
|
5
15
|
|
|
16
|
+
require 'rails/all'
|
|
6
17
|
require 'table-for'
|
|
7
18
|
require 'ostruct'
|
|
8
19
|
require 'xmlsimple'
|
|
9
|
-
require 'active_record'
|
|
10
20
|
require 'active_support/all'
|
|
11
21
|
require 'with_model'
|
|
12
22
|
|
data/spec/table_for/base_spec.rb
CHANGED
|
@@ -4,7 +4,7 @@ describe TableFor::Base do
|
|
|
4
4
|
before(:each) do
|
|
5
5
|
@view_class = Class.new
|
|
6
6
|
@view = @view_class.new
|
|
7
|
-
@view_class.send(:include, Blocks::
|
|
7
|
+
@view_class.send(:include, Blocks::ViewExtensions)
|
|
8
8
|
@base = TableFor::Base.new(@view)
|
|
9
9
|
@records = [OpenStruct.new(:id => 1)]
|
|
10
10
|
@column = stub(:name => :my_column, :anonymous => false)
|
|
@@ -14,28 +14,22 @@ describe TableFor::Base do
|
|
|
14
14
|
it "should define a block with the specified options and force header to be present" do
|
|
15
15
|
proc = Proc.new {}
|
|
16
16
|
@base.header(:first_name, :option_1 => 10, :option2 => "abcd", &proc)
|
|
17
|
-
block = @base.
|
|
18
|
-
block.should
|
|
19
|
-
block.should
|
|
20
|
-
block.block.should eql(proc)
|
|
21
|
-
block.options.should eql(:option_1 => 10, :option2 => "abcd", :header => true)
|
|
17
|
+
block = @base.block_definitions[:first_name_header]
|
|
18
|
+
block.should be_a(Blocks::BlockDefinition)
|
|
19
|
+
block.standard_options.should eql(block: proc, :option_1 => 10, :option2 => "abcd", :header => true)
|
|
22
20
|
|
|
23
21
|
@base.header(:last_name, :header => "LAST NAME", &proc)
|
|
24
|
-
block = @base.
|
|
25
|
-
block.should
|
|
26
|
-
block.should
|
|
27
|
-
block.block.should eql(proc)
|
|
28
|
-
block.options.should eql(:header => "LAST NAME")
|
|
22
|
+
block = @base.block_definitions[:last_name_header]
|
|
23
|
+
block.should be_a(Blocks::BlockDefinition)
|
|
24
|
+
block.standard_options.should eql(block: proc, header: "LAST NAME")
|
|
29
25
|
end
|
|
30
26
|
|
|
31
27
|
it "should not require options to be passed" do
|
|
32
28
|
proc = Proc.new {}
|
|
33
29
|
@base.header(:last_name, &proc)
|
|
34
|
-
block = @base.
|
|
35
|
-
block.should
|
|
36
|
-
block.should
|
|
37
|
-
block.block.should eql(proc)
|
|
38
|
-
block.options.should eql(:header => true)
|
|
30
|
+
block = @base.block_definitions[:last_name_header]
|
|
31
|
+
block.should be_a(Blocks::BlockDefinition)
|
|
32
|
+
block.standard_options.should eql(block: proc, header: true)
|
|
39
33
|
end
|
|
40
34
|
end
|
|
41
35
|
|
|
@@ -43,21 +37,17 @@ describe TableFor::Base do
|
|
|
43
37
|
it "should define a block named footer_content with the specified options" do
|
|
44
38
|
proc = Proc.new {}
|
|
45
39
|
@base.footer :option_1 => "First Option", &proc
|
|
46
|
-
block = @base.
|
|
47
|
-
block.should
|
|
48
|
-
block.should
|
|
49
|
-
block.block.should eql(proc)
|
|
50
|
-
block.options.should eql(:option_1 => "First Option")
|
|
40
|
+
block = @base.block_definitions[:footer_content]
|
|
41
|
+
block.should be_a(Blocks::BlockDefinition)
|
|
42
|
+
block.standard_options.should eql(block: proc, :option_1 => "First Option")
|
|
51
43
|
end
|
|
52
44
|
|
|
53
45
|
it "should not require options to be passed" do
|
|
54
46
|
proc = Proc.new {}
|
|
55
47
|
@base.footer(&proc)
|
|
56
|
-
block = @base.
|
|
57
|
-
block.should
|
|
58
|
-
block.should
|
|
59
|
-
block.block.should eql(proc)
|
|
60
|
-
block.options.should eql({})
|
|
48
|
+
block = @base.block_definitions[:footer_content]
|
|
49
|
+
block.should be_a(Blocks::BlockDefinition)
|
|
50
|
+
block.standard_options.should eql(block: proc)
|
|
61
51
|
end
|
|
62
52
|
end
|
|
63
53
|
|
|
@@ -6,39 +6,39 @@ describe TableFor::ViewAdditions do
|
|
|
6
6
|
@view = @view_class.new
|
|
7
7
|
@view_class.send(:include, ActionView::Helpers::TextHelper)
|
|
8
8
|
@view_class.send(:include, TableFor::ViewAdditions::ClassMethods)
|
|
9
|
-
@view_class.send(:include, Blocks::
|
|
9
|
+
@view_class.send(:include, Blocks::ViewExtensions)
|
|
10
10
|
@records = [OpenStruct.new(:id => 1)]
|
|
11
11
|
@column = stub(:name => :my_column)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
describe "#table_for" do
|
|
15
|
-
it "should call
|
|
16
|
-
TableFor::Base.expects(:new).returns(mock(:
|
|
15
|
+
it "should call render on the TableFor::Base instance" do
|
|
16
|
+
TableFor::Base.expects(:new).returns(mock(:render => ""))
|
|
17
17
|
@view.table_for(@records)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
it "should pass the view as the first parameter to TableFor::Base initialization" do
|
|
21
|
-
TableFor::Base.expects(:new).with {|view, options| view == @view}.returns(mock(:
|
|
21
|
+
TableFor::Base.expects(:new).with {|view, options| view == @view}.returns(mock(:render => ""))
|
|
22
22
|
@view.table_for(@records)
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
it "should default the template to render" do
|
|
26
|
-
TableFor::Base.any_instance.expects(:
|
|
26
|
+
TableFor::Base.any_instance.expects(:render).with(partial: "table_for/table_for").returns("")
|
|
27
27
|
@view.table_for(@records)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
it "should default the variable to 'table' to render" do
|
|
31
|
-
TableFor::Base.expects(:new).with {|view, options| options[:
|
|
31
|
+
TableFor::Base.expects(:new).with {|view, options| options[:runtime][:builder_variable] == "table"}.returns(mock(:render => ""))
|
|
32
32
|
@view.table_for(@records)
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
it "should default the records to the collection passed in" do
|
|
36
|
-
TableFor::Base.expects(:new).with {|view, options| options[:records] == @records}.returns(mock(:
|
|
36
|
+
TableFor::Base.expects(:new).with {|view, options| options[:runtime][:records] == @records}.returns(mock(:render => ""))
|
|
37
37
|
@view.table_for(@records)
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
it "should add any runtime options to the options initialized for TableFor::Base" do
|
|
41
|
-
TableFor::Base.expects(:new).with {|view, options| options[:option1] == 1 && options[:option2] == "2"}.returns(mock(:
|
|
41
|
+
TableFor::Base.expects(:new).with {|view, options| options[:option1] == 1 && options[:option2] == "2"}.returns(mock(:render => ""))
|
|
42
42
|
@view.table_for(@records, :option1 => 1, :option2 => "2")
|
|
43
43
|
end
|
|
44
44
|
end
|
data/table-for.gemspec
CHANGED
|
@@ -19,9 +19,9 @@ Gem::Specification.new do |spec|
|
|
|
19
19
|
spec.require_paths = ["lib"]
|
|
20
20
|
|
|
21
21
|
spec.add_dependency "rails", ">= 3.0.0"
|
|
22
|
-
spec.add_dependency "
|
|
22
|
+
spec.add_dependency "blocks", ">= 4.0.0"
|
|
23
23
|
|
|
24
|
-
spec.add_development_dependency "rspec-rails", "
|
|
24
|
+
spec.add_development_dependency "rspec-rails", "~> 3.8"
|
|
25
25
|
spec.add_development_dependency "mocha", "0.10.3"
|
|
26
26
|
spec.add_development_dependency "xml-simple", "1.1.1"
|
|
27
27
|
spec.add_development_dependency "supermodel"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: table-for
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 4.0.0.rc1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Hunter
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2024-03-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -25,33 +25,33 @@ dependencies:
|
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: 3.0.0
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
28
|
+
name: blocks
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- - "
|
|
31
|
+
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: 0.
|
|
33
|
+
version: 4.0.0
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
|
-
- - "
|
|
38
|
+
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: 0.
|
|
40
|
+
version: 4.0.0
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: rspec-rails
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
|
-
- - "
|
|
45
|
+
- - "~>"
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version:
|
|
47
|
+
version: '3.8'
|
|
48
48
|
type: :development
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
|
-
- - "
|
|
52
|
+
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version:
|
|
54
|
+
version: '3.8'
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: mocha
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -146,6 +146,8 @@ extra_rdoc_files: []
|
|
|
146
146
|
files:
|
|
147
147
|
- ".byebug_history"
|
|
148
148
|
- ".gitignore"
|
|
149
|
+
- ".rspec"
|
|
150
|
+
- ".ruby-version"
|
|
149
151
|
- ".travis.yml"
|
|
150
152
|
- CHANGELOG.rdoc
|
|
151
153
|
- Gemfile
|
|
@@ -171,7 +173,7 @@ homepage: http://github.com/hunterae/table-for
|
|
|
171
173
|
licenses:
|
|
172
174
|
- MIT
|
|
173
175
|
metadata: {}
|
|
174
|
-
post_install_message:
|
|
176
|
+
post_install_message:
|
|
175
177
|
rdoc_options: []
|
|
176
178
|
require_paths:
|
|
177
179
|
- lib
|
|
@@ -186,9 +188,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
186
188
|
- !ruby/object:Gem::Version
|
|
187
189
|
version: '0'
|
|
188
190
|
requirements: []
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
signing_key:
|
|
191
|
+
rubygems_version: 3.5.3
|
|
192
|
+
signing_key:
|
|
192
193
|
specification_version: 4
|
|
193
194
|
summary: table-for is a table builder for an array of objects, easily allowing overriding
|
|
194
195
|
of how any aspect of the table is generated
|