edgarj 4.02.00 → 4.03.00

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fb262ae814e088c79954becacd222d8cdc4b3797
4
- data.tar.gz: 7fe707418fcedd8a51a40f15100008390ec30829
3
+ metadata.gz: a6e9e87b3ebbda6b9e3ad40f1f2f2496208c0674
4
+ data.tar.gz: 5539c9053f74354ec35ecae734bc82128c3fe05c
5
5
  SHA512:
6
- metadata.gz: 5595e58910da9ee716808607d7e28dd435d16d029feb749feb035c0192d8ba350e44a6f09b471508caba00006601506a7767117cea4dbaa1bb76fb3676681476
7
- data.tar.gz: e51083e18e3578df94d6691ab653d4ddce11eaf27d0c8601361ff6abe48d0280c36ae27107a6f7a958fb62af38b131acc4ce0e3b14ea289d358a04232e052d6d
6
+ metadata.gz: 1b8396a15cb2e18c79b6b5769f98339c89dd560f9816de54fd7b87ca7bc35e5a218a215b961bda07085f6457a4d3c4992fa828fc48fdfc8d64b813f92de8688a
7
+ data.tar.gz: 1c2c1f664e0a2a0c1ac95f4e183f8152edc86098a38de0de594877d19cadcd793b1f440c7b419d180af34bb39cf58fda732576f09925574d960c63486632f2fc
data/README.rdoc CHANGED
@@ -22,6 +22,17 @@ Edgarj 0.* for Rails 3.2
22
22
  * Rails
23
23
  * external 'User' model.
24
24
 
25
+ == Dummy App
26
+
27
+ * How to run
28
+ $ cd test/dummy
29
+ $ rake db:drop && rake db:create && rake db:migrate
30
+ $ FIXTURES_PATH=../../test/fixtures rake db:fixtures:load
31
+ $ rails server
32
+ * How to test
33
+ $ cd [RAILS_ROOT]
34
+ $ rake test
35
+
25
36
  == KNOWN BUGS
26
37
 
27
38
  * "rake scaffold" (not "rake edgarj:scaffold") generates
@@ -1,8 +1,158 @@
1
+ require 'singleton'
2
+
1
3
  module Edgarj
2
4
  module Drawer
5
+ # Column-info classes to provide the following common methods:
6
+ #
7
+ # * name
8
+ # * css_style
9
+ # * sort_key
10
+ # * column_header_label
11
+ # * column_value
12
+ #
13
+ # As wells as the following for backward compatibility:
14
+ # * type
15
+ module ColumnInfo
16
+ # ActiveRecord::ConnectionAdapters::[DRIVER]::Column wrapper
17
+ #
18
+ # NOTE: ColumnInfo::* classes instances are cached during server process
19
+ # lifetime so that dynamic object (like drawer) cannot be stored.
20
+ class Normal
21
+ # @param vc [ViewContext]
22
+ # @param model [AR]
23
+ # @param name [String]
24
+ def initialize(vc, model, name)
25
+ @vc = vc
26
+ @model = model
27
+ @name = name
28
+ @ar_column_info = model.columns_hash[name]
29
+ end
30
+
31
+ def name
32
+ @name
33
+ end
34
+
35
+ def css_style
36
+ case @ar_column_info.type
37
+ when :integer
38
+ {align: 'right'}
39
+ when :boolean
40
+ {align: 'center'}
41
+ else
42
+ {}
43
+ end
44
+ end
45
+
46
+ # return table_name + col.name for sort
47
+ def sort_key
48
+ @model.table_name + '.' + @name
49
+ end
50
+
51
+ # draw column header (with sort link)
52
+ #
53
+ # === INPUTS
54
+ # options:: options to url_for
55
+ def column_header_label(page_info, options)
56
+ label = @vc.column_label(@name)
57
+ dir = 'asc'
58
+
59
+ if page_info.order_by == sort_key
60
+ # toggle direction
61
+ if page_info.dir == 'asc' || page_info.dir.blank?
62
+ label += '▲'
63
+ dir = 'desc'
64
+ else
65
+ label += '▼'
66
+ end
67
+ end
68
+ @vc.link_to(label,
69
+ {
70
+ :action => 'page_info_save',
71
+ :id => page_info.id,
72
+ 'edgarj_page_info[order_by]' => sort_key,
73
+ 'edgarj_page_info[dir]' => dir
74
+ }.merge(options),
75
+ :remote => true,
76
+ :method => :put)
77
+ end
78
+
79
+ # draw rec.col other than 'belongs_to'
80
+ #
81
+ # === INPUTS
82
+ # rec:: AR instance
83
+ def column_value(rec, drawer)
84
+ if (enum = @vc.get_enum(rec.class, @ar_column_info))
85
+ @vc.draw_column_enum(rec, @ar_column_info, enum)
86
+ else
87
+ case @ar_column_info.type
88
+ when :datetime
89
+ @vc.datetime_fmt(rec.send(name))
90
+ when :date
91
+ @vc.date_fmt(rec.send(name))
92
+ when :integer
93
+ rec.send(name).to_s
94
+ when :boolean
95
+ rec.send(name) ? '√' : ''
96
+ else
97
+ # NOTE: rec.send(col.name) is not used since sssn.send(:data)
98
+ # becomes hash rather than actual string-data so that following
99
+ # split() fails for Hash.
100
+ if str = rec.attributes[name]
101
+ draw_trimmed_str(str)
102
+ else
103
+ ''
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ # just for backward compatibility
110
+ def type
111
+ @ar_column_info.type
112
+ end
113
+
114
+ private
115
+
116
+ # trim string when too long
117
+ def draw_trimmed_str(str)
118
+ s = str.split(//)
119
+ if s.size > Edgarj::LIST_TEXT_MAX_LEN
120
+ s = s[0..Edgarj::LIST_TEXT_MAX_LEN] << '...'
121
+ end
122
+ s.join('')
123
+ end
124
+ end
125
+
126
+ # auto-generated column-info for 'belongs_to' column
127
+ #
128
+ # parent model is assumed to have 'name' method
129
+ class BelongsTo < Normal
130
+ def initialize(vc, model, name, parent_model, belongs_to_link)
131
+ super(vc, model, name)
132
+ @parent_model = parent_model
133
+ @belongs_to_link = belongs_to_link
134
+ end
135
+
136
+ # column header for 'belongs_to' column prints label without
137
+ # any sort action unlike Normal-class behavior.
138
+ def column_header_label(page_info, options)
139
+ @vc.draw_belongs_to_label_sub(@model, name, @parent_model)
140
+ end
141
+
142
+ def column_value(rec, drawer)
143
+ @parent_rec = rec.belongs_to_AR(@ar_column_info)
144
+ if @belongs_to_link
145
+ @vc.link_to(@parent_rec.name, drawer.popup_path(self), remote: true)
146
+ else
147
+ @parent_rec ? @parent_rec.name : ''
148
+ end
149
+ end
150
+ end
151
+ end
152
+
3
153
  # 'Mediator' to draw list and form of the model on the view.
4
154
  #
5
- # This collaborate with the following sub classes:
155
+ # This collaborates with the following sub classes:
6
156
  # Edgarj::ListDrawer::Normal:: for list
7
157
  # Edgarj::FormDrawer::Base:: for data entry form
8
158
  # Edgarj::FormDrawer::Search:: for search form
@@ -138,32 +288,25 @@ module Edgarj
138
288
 
139
289
  @vc.content_tag(:table, width: '100%', class: 'list') do
140
290
  @vc.content_tag(:tr) do
141
- ''.html_safe.tap do |result|
142
- for col in columns_for(list_columns) do
143
- result << d.draw_column_header(col)
144
- end
291
+ for col in columns_for(list_columns, :list) do
292
+ @vc.concat d.draw_column_header(col)
145
293
  end
146
294
  end +
147
- ''.html_safe.tap do |trs|
295
+ @vc.capture do
148
296
  for rec in list do
149
297
  @line_color = 1 - @line_color
150
- trs << draw_row(rec) do
151
- ''.html_safe.tap do |cols|
152
- for col in columns_for(list_columns) do
153
- cols << d.draw_column(rec, col)
298
+ @vc.concat(draw_row(rec) do
299
+ @vc.capture do
300
+ for col in columns_for(list_columns, :list) do
301
+ @vc.concat d.draw_column(rec, col)
154
302
  end
155
303
  end
156
- end
304
+ end)
157
305
  end
158
306
  end
159
307
  end
160
308
  end
161
309
 
162
- # return table_name + col.name
163
- def fullname(col)
164
- @model.table_name + '.' + col.name
165
- end
166
-
167
310
  # overwrite to replace form drawer for the model
168
311
  def form_drawer_class
169
312
  Edgarj::FormDrawer::Base
@@ -192,17 +335,60 @@ module Edgarj
192
335
  end
193
336
  end
194
337
 
338
+ # cache ColumnInfo array per 'controller x kind'
339
+ class ColumnInfoCache
340
+ include Singleton
341
+
342
+ def initialize
343
+ #Rails.logger.debug('ColumnInfoCache initialized')
344
+ @cache = {}
345
+ end
346
+
347
+ # return if @cache[controller][kind] exists
348
+ def presence(controller, kind)
349
+ if @cache[controller].nil?
350
+ @cache[controller] = {}
351
+ end
352
+ @cache[controller][kind]
353
+ end
354
+
355
+ def set(controller, kind, val)
356
+ if @cache[controller].nil?
357
+ @cache[controller] = {}
358
+ end
359
+ @cache[controller][kind] = val
360
+ end
361
+
362
+ def cache
363
+ @cache
364
+ end
365
+ end
366
+
195
367
  # return array of model columns (ActiveRecord::ConnectionAdapters::X_Column type).
196
368
  #
197
369
  # === INPUTS
198
370
  # column_name_list:: column name list
199
- def columns_for(column_name_list)
200
- [].tap do |result|
201
- for col_name in column_name_list do
202
- if (col = @model.columns_hash[col_name])
203
- result << col
204
- end
205
- end
371
+ # kind:: :list, :form, or :search_form
372
+ def columns_for(column_name_list, kind = :default)
373
+ if (val = ColumnInfoCache.instance.presence(@vc.controller.class, kind))
374
+ val
375
+ else
376
+ #Rails.logger.debug("ColumnInfoCache non-cached access for (#{@vc.controller.class.name} x #{kind})")
377
+ ColumnInfoCache.instance.set(@vc.controller.class, kind,
378
+ [].tap do |result|
379
+ for col_name in column_name_list do
380
+ result <<
381
+ if col_name.is_a?(ColumnInfo::Normal)
382
+ col_name
383
+ elsif (col = @model.columns_hash[col_name])
384
+ if (parent = @model.belongs_to_AR(col))
385
+ ColumnInfo::BelongsTo.new(@vc, @model, col_name, parent, false)
386
+ else
387
+ ColumnInfo::Normal.new(@vc, @model, col_name)
388
+ end
389
+ end
390
+ end
391
+ end)
206
392
  end
207
393
  end
208
394
 
@@ -25,22 +25,18 @@ module Edgarj
25
25
 
26
26
  @vc.content_tag(:table, width: '100%', class: 'list') do
27
27
  @vc.content_tag(:tr) do
28
- ''.html_safe.tap do |result|
29
- for col in columns_for(list_columns) do
30
- result << d.draw_column_header(col, id_target: @params[:id_target])
31
- end
28
+ for col in columns_for(list_columns, :list) do
29
+ @vc.concat d.draw_column_header(col, id_target: @params[:id_target])
32
30
  end
33
31
  end +
34
- ''.html_safe.tap do |trs|
32
+ @vc.capture do
35
33
  for rec in list do
36
34
  @line_color = 1 - @line_color
37
- trs << draw_row(rec) do
38
- ''.html_safe.tap do |cols|
39
- for col in columns_for(list_columns) do
40
- cols << d.draw_column(rec, col)
41
- end
35
+ @vc.concat(draw_row(rec) do
36
+ for col in columns_for(list_columns, :list) do
37
+ @vc.concat d.draw_column(rec, col)
42
38
  end
43
- end
39
+ end)
44
40
  end
45
41
  end
46
42
  end
@@ -81,7 +81,7 @@ module Edgarj
81
81
 
82
82
  def columns
83
83
  drawer = @vc.drawer
84
- drawer.columns_for(drawer.form_columns)
84
+ drawer.columns_for(drawer.form_columns, :form)
85
85
  end
86
86
 
87
87
  # base method for derived class
@@ -215,7 +215,7 @@ module Edgarj
215
215
  # overwrite
216
216
  def columns
217
217
  drawer = @vc.drawer
218
- drawer.columns_for(drawer.search_form_columns)
218
+ drawer.columns_for(drawer.search_form_columns, :search_form)
219
219
  end
220
220
 
221
221
  # overwrite
@@ -1,6 +1,8 @@
1
1
  # coding: UTF-8
2
2
 
3
3
  module Edgarj
4
+ # ListDrawer will be obsoleted. Column will be handled by
5
+ # Edgarj::Drawer::ColumnInfo
4
6
  module ListDrawer
5
7
  # Base for popup-list and normal-list column drawer
6
8
  #
@@ -10,13 +12,10 @@ module Edgarj
10
12
 
11
13
  # * drawer - Edgarj::Drawer::Base object
12
14
  # * options
13
- #
14
- # TODO: enum_cache は止め、グローバルに1つのキャッシュを作る。
15
15
  def initialize(drawer, options = {})
16
16
  @drawer = drawer
17
17
  @options = options.dup
18
18
  @vc = drawer.vc
19
- @enum_cache = {}
20
19
  @bitset_cache = {}
21
20
  @parent_rec = nil
22
21
  @belongs_to_link = false # doesn't make link on belongs_to
@@ -24,161 +23,21 @@ module Edgarj
24
23
 
25
24
  def draw_column_header(col, options={})
26
25
  @vc.content_tag(:th) do
27
- draw_column_header_sub(col, options)
26
+ col.column_header_label(@drawer.page_info, options)
28
27
  end
29
28
  end
30
29
 
31
30
  def draw_column(rec, col)
32
- @parent_rec = rec.belongs_to_AR(col)
33
31
  @vc.content_tag(:td, td_options(rec, col)) do
34
- # edgarj_address column is prior to draw_belongs_to() because of
35
- # avoiding link_to process on the 'belongs_to' column.
36
- =begin
37
- if rec.class.edgarj_address?(col)
38
- col_name = rec.class.get_column_name(col)
39
- adrs = Edgarj::Address.find_by_id(rec.send(col_name))
40
- adrs ? draw_trimmed_str(adrs.name) : ''
41
- =end
42
- if @parent_rec then
43
- if @belongs_to_link
44
- @vc.link_to(@parent_rec.name, @drawer.popup_path(col), remote: true)
45
- else
46
- h(@parent_rec.name)
47
- end
48
- else
49
- draw_normal_column(rec, col)
50
- end
32
+ col.column_value(rec, @drawer)
51
33
  end
52
34
  end
53
35
 
54
- private
36
+ private
37
+
55
38
  # <td> options
56
39
  def td_options(rec, col)
57
- if @enum_cache[col.name]
58
- {}
59
- elsif @bitset_cache[col.name]
60
- {}
61
- elsif @parent_rec
62
- {}
63
- else
64
- if @vc.get_enum(rec.class, col)
65
- {}
66
- # elsif @vc.get_bitset(rec.class, col)
67
- # {}
68
- else
69
- case col.type
70
- when :datetime
71
- {}
72
- when :date
73
- {}
74
- when :integer
75
- {align: 'right'}
76
- when :boolean
77
- {align: 'center'}
78
- else
79
- {}
80
- end
81
- end
82
- end
83
- end
84
-
85
- # trim string when too long
86
- def draw_trimmed_str(str)
87
- s = str.split(//)
88
- if s.size > Edgarj::LIST_TEXT_MAX_LEN
89
- s = s[0..Edgarj::LIST_TEXT_MAX_LEN] << '...'
90
- end
91
- s.join('')
92
- end
93
-
94
- # draw sort link on list column header
95
- #
96
- # === INPUTS
97
- # col:: column data
98
- # options:: options to url_for
99
- def draw_sort(col, options={})
100
- label = @vc.column_label(col)
101
- dir = 'asc'
102
- if @drawer.page_info.order_by == @drawer.fullname(col)
103
- # toggle direction
104
- if @drawer.page_info.dir == 'asc' || @drawer.page_info.dir.blank?
105
- label += '▲'
106
- dir = 'desc'
107
- else
108
- label += '▼'
109
- end
110
- end
111
- @vc.link_to(label,
112
- {
113
- :controller => @drawer.params[:controller],
114
- :action => 'page_info_save',
115
- :id => @drawer.page_info.id,
116
- 'edgarj_page_info[order_by]' => @drawer.fullname(col),
117
- 'edgarj_page_info[dir]' => dir
118
- }.merge(options),
119
- :remote => true,
120
- :method => :put)
121
- end
122
-
123
- # draw list column header for both usual list and popup list
124
- def draw_column_header_sub(col, options={})
125
- parent = @drawer.model.belongs_to_AR(col)
126
- if parent then
127
- @vc.draw_belongs_to_label_sub(@drawer.model, col.name, parent)
128
- else
129
- draw_sort(col, options)
130
- end
131
- end
132
-
133
- # draw rec.col other than 'belongs_to'
134
- # 1. DateTime format is YYYY-MM-DD hh:mm:ss.
135
- # 1. if col.name == 'flags', it is assumed bitset.
136
- # 1. if col is edgarj_file, it is assumed file.
137
- #
138
- # === INPUTS
139
- # rec:: AR instance
140
- # col:: ActiveRecord::ConnectionAdapters::Column type which rec.class.columns returns
141
- def draw_normal_column(rec, col)
142
- =begin
143
- if rec.class.edgarj_file?(col)
144
- file_info = FileInfo.safe_find(rec.send(col.name))
145
- file_info ? file_info.filename : ''
146
- elsif (enum = @enum_cache[col.name])
147
- @vc.draw_column_enum(rec, col, enum)
148
- elsif (bitset = @bitset_cache[col.name])
149
- @vc.draw_column_bitset(rec, col, bitset)
150
- else
151
- =end
152
- if (enum = @vc.get_enum(rec.class, col))
153
- @enum_cache[col.name] = enum
154
- @vc.draw_column_enum(rec, col, enum)
155
- =begin
156
- elsif (bitset = @vc.get_bitset(rec.class, col))
157
- @bitset_cache[col.name] = bitset
158
- @vc.draw_column_bitset(rec, col, bitset)
159
- =end
160
- else
161
- case col.type
162
- when :datetime
163
- @vc.datetime_fmt(rec.send(col.name))
164
- when :date
165
- @vc.date_fmt(rec.send(col.name))
166
- when :integer
167
- h(rec.send(col.name))
168
- when :boolean
169
- rec.send(col.name) ? '√' : ''
170
- else
171
- # NOTE: rec.send(col.name) is not used since sssn.send(:data)
172
- # becomes hash rather than actual string-data so that following
173
- # split() fails for Hash.
174
- if str = rec.attributes[col.name]
175
- draw_trimmed_str(str)
176
- else
177
- ''
178
- end
179
- end
180
- end
181
- #end
40
+ col.css_style
182
41
  end
183
42
  end
184
43
 
@@ -19,7 +19,7 @@ params[:id_target]:: target DOM id for hidden 'belongs_to' id
19
19
  <td><%= v('search') %></td>
20
20
  <td>
21
21
  <%= f.select("col",
22
- popup_drawer.columns_for(popup_drawer.list_columns).map{|col|
22
+ popup_drawer.columns_for(popup_drawer.list_columns, :list).map{|col|
23
23
  [model.human_attribute_name(col.name), col.name]}) %>
24
24
  </td>
25
25
  <td><%= f.text_field("val") %></td>
@@ -1,3 +1,3 @@
1
1
  module Edgarj
2
- VERSION = "4.02.00"
2
+ VERSION = '4.03.00'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: edgarj
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.02.00
4
+ version: 4.03.00
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fuminori Ido
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-22 00:00:00.000000000 Z
11
+ date: 2016-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails