edgarj 0.01.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +23 -0
  4. data/Rakefile +40 -0
  5. data/app/assets/javascripts/edgarj/base.js +49 -0
  6. data/app/assets/javascripts/edgarj/menu.js +39 -0
  7. data/app/assets/javascripts/edgarj/operator_selection.js +133 -0
  8. data/app/assets/stylesheets/edgarj/base.css +304 -0
  9. data/app/assets/stylesheets/edgarj/menu.css +65 -0
  10. data/app/controllers/edgarj/authentication_mixin.rb.sample +30 -0
  11. data/app/controllers/edgarj/controller_mixin_common.rb +80 -0
  12. data/app/controllers/edgarj/controller_mixin_for_app.rb +71 -0
  13. data/app/controllers/edgarj/edgarj_controller.rb +535 -0
  14. data/app/controllers/edgarj/model_permissions_controller.rb +8 -0
  15. data/app/controllers/edgarj/permission_mixin.rb +84 -0
  16. data/app/controllers/edgarj/popup_controller.rb +128 -0
  17. data/app/controllers/edgarj/rescue_mixin.rb +37 -0
  18. data/app/controllers/edgarj/user_group_users_controller.rb +8 -0
  19. data/app/controllers/edgarj/user_groups_controller.rb +9 -0
  20. data/app/controllers/edgarj/user_groups_popup_controller.rb +8 -0
  21. data/app/helpers/edgarj/assoc_helper.rb +369 -0
  22. data/app/helpers/edgarj/common_helper.rb +37 -0
  23. data/app/helpers/edgarj/edgarj_helper.rb +20 -0
  24. data/app/helpers/edgarj/field_helper.rb +397 -0
  25. data/app/helpers/edgarj/form_drawer.rb +322 -0
  26. data/app/helpers/edgarj/list_drawer.rb +169 -0
  27. data/app/helpers/edgarj/menu_helper.rb +92 -0
  28. data/app/helpers/edgarj/model_permissions_helper.rb +9 -0
  29. data/app/helpers/edgarj/popup_helper.rb +40 -0
  30. data/app/helpers/edgarj/search_helper.rb +14 -0
  31. data/app/helpers/edgarj/sessions_helper.rb +9 -0
  32. data/app/helpers/edgarj/user_group_users_helper.rb +9 -0
  33. data/app/helpers/edgarj/user_groups_helper.rb +9 -0
  34. data/app/helpers/edgarj/user_groups_popup_helper.rb +9 -0
  35. data/app/models/edgarj/drawer/base.rb +234 -0
  36. data/app/models/edgarj/drawer/normal.rb +6 -0
  37. data/app/models/edgarj/drawer/popup.rb +47 -0
  38. data/app/models/edgarj/drawer.rb +13 -0
  39. data/app/models/edgarj/model_permission.rb +41 -0
  40. data/app/models/edgarj/page_info.rb +47 -0
  41. data/app/models/edgarj/search.rb +81 -0
  42. data/app/models/edgarj/search_form.rb +255 -0
  43. data/app/models/edgarj/search_popup.rb +44 -0
  44. data/app/models/edgarj/sssn.rb +120 -0
  45. data/app/models/edgarj/user_group.rb +67 -0
  46. data/app/models/edgarj/user_group_user.rb +18 -0
  47. data/app/models/edgarj.rb +5 -0
  48. data/app/views/edgarj/edgarj/_form.html.erb +25 -0
  49. data/app/views/edgarj/edgarj/_list.html.erb +52 -0
  50. data/app/views/edgarj/edgarj/_message_popup.html.erb +15 -0
  51. data/app/views/edgarj/edgarj/_search_form.html.erb +64 -0
  52. data/app/views/edgarj/edgarj/_search_operator.html.erb +17 -0
  53. data/app/views/edgarj/edgarj/_search_operator_selection.html.erb +12 -0
  54. data/app/views/edgarj/edgarj/clear.js.erb +1 -0
  55. data/app/views/edgarj/edgarj/create.js.erb +4 -0
  56. data/app/views/edgarj/edgarj/destroy.js.erb +2 -0
  57. data/app/views/edgarj/edgarj/index.html.erb +37 -0
  58. data/app/views/edgarj/edgarj/index.js.erb +1 -0
  59. data/app/views/edgarj/edgarj/message_popup.js.erb +3 -0
  60. data/app/views/edgarj/edgarj/page_info_save.js.erb +1 -0
  61. data/app/views/edgarj/edgarj/search.js.erb +4 -0
  62. data/app/views/edgarj/edgarj/search_clear.js.erb +1 -0
  63. data/app/views/edgarj/edgarj/show.js.erb +1 -0
  64. data/app/views/edgarj/edgarj/top.html.erb +4 -0
  65. data/app/views/edgarj/edgarj/update.js.erb +4 -0
  66. data/app/views/edgarj/popup/_index.html.erb +16 -0
  67. data/app/views/edgarj/popup/_list.html.erb +42 -0
  68. data/app/views/edgarj/popup/_message_popup.html.erb +15 -0
  69. data/app/views/edgarj/popup/_search.html.erb +42 -0
  70. data/app/views/edgarj/popup/_search_save_popup.html.erb +16 -0
  71. data/app/views/edgarj/popup/index.js.erb +5 -0
  72. data/app/views/edgarj/popup/message_popup.js.erb +3 -0
  73. data/app/views/edgarj/popup/page_info_save.js.erb +1 -0
  74. data/app/views/edgarj/popup/search.js.erb +15 -0
  75. data/app/views/edgarj/popup/view_status_save.js.erb +1 -0
  76. data/config/routes.rb +15 -0
  77. data/config/settings.yml +5 -0
  78. data/db/migrate/20131118084600_create_edgar_sssns.rb +14 -0
  79. data/db/migrate/20131123124730_create_edgar_page_infos.rb +15 -0
  80. data/db/migrate/20140116062252_create_edgar_user_groups.rb +18 -0
  81. data/db/migrate/20140116062327_create_edgar_user_group_users.rb +10 -0
  82. data/db/migrate/20140206222308_create_edgar_model_permissions.rb +14 -0
  83. data/db/migrate/20141209053055_rename_edgar_to_edgarj.rb +17 -0
  84. data/lib/core_ext/active_record.rb +123 -0
  85. data/lib/core_ext/resources.rb +71 -0
  86. data/lib/edgarj/engine.rb +64 -0
  87. data/lib/edgarj/enum_cache.rb +46 -0
  88. data/lib/edgarj/templates/rails/helper/helper.rb +10 -0
  89. data/lib/edgarj/templates/test_unit/scaffold/functional_test.rb +575 -0
  90. data/lib/edgarj/version.rb +3 -0
  91. data/lib/edgarj.rb +14 -0
  92. data/lib/generators/edgarj/popup_scaffold/USAGE +6 -0
  93. data/lib/generators/edgarj/popup_scaffold/popup_scaffold_generator.rb +35 -0
  94. data/lib/generators/edgarj/popup_scaffold/templates/controller.rb +13 -0
  95. data/lib/generators/edgarj/popup_scaffold/templates/functional_test.rb +197 -0
  96. data/lib/generators/edgarj/popup_scaffold/templates/helper.rb +9 -0
  97. data/lib/generators/edgarj/scaffold/USAGE +17 -0
  98. data/lib/generators/edgarj/scaffold/scaffold_generator.rb +40 -0
  99. data/lib/generators/edgarj/scaffold/templates/controller.rb +13 -0
  100. data/lib/tasks/edgarj_tasks.rake +32 -0
  101. data/lib/tasks/pakcage.rake +18 -0
  102. data/locale/en.yml +94 -0
  103. data/locale/ja.yml +100 -0
  104. data/test/dummy/README.rdoc +28 -0
  105. data/test/dummy/Rakefile +6 -0
  106. data/test/dummy/app/assets/javascripts/application.js +21 -0
  107. data/test/dummy/app/assets/javascripts/authors.js +2 -0
  108. data/test/dummy/app/assets/stylesheets/application.css +16 -0
  109. data/test/dummy/app/assets/stylesheets/authors.css +4 -0
  110. data/test/dummy/app/assets/stylesheets/scaffold.css +56 -0
  111. data/test/dummy/app/controllers/application_controller.rb +15 -0
  112. data/test/dummy/app/controllers/authors_controller.rb +6 -0
  113. data/test/dummy/app/controllers/authors_popup_controller.rb +6 -0
  114. data/test/dummy/app/controllers/books_controller.rb +6 -0
  115. data/test/dummy/app/controllers/dummy_auth_mixin.rb +36 -0
  116. data/test/dummy/app/decorators/models/edgarj/user_group_decorator.rb +1 -0
  117. data/test/dummy/app/helpers/application_helper.rb +3 -0
  118. data/test/dummy/app/helpers/authors_helper.rb +7 -0
  119. data/test/dummy/app/helpers/authors_popup_helper.rb +7 -0
  120. data/test/dummy/app/helpers/books_helper.rb +7 -0
  121. data/test/dummy/app/models/author.rb +32 -0
  122. data/test/dummy/app/models/book.rb +5 -0
  123. data/test/dummy/app/models/user.rb +13 -0
  124. data/test/dummy/app/views/layouts/application.html.erb +32 -0
  125. data/test/dummy/app/views/layouts/login.html.erb +20 -0
  126. data/test/dummy/bin/bundle +3 -0
  127. data/test/dummy/bin/rails +4 -0
  128. data/test/dummy/bin/rake +4 -0
  129. data/test/dummy/config/application.rb +59 -0
  130. data/test/dummy/config/boot.rb +10 -0
  131. data/test/dummy/config/database.yml +15 -0
  132. data/test/dummy/config/edgarj/menu_config.rb +28 -0
  133. data/test/dummy/config/environment.rb +5 -0
  134. data/test/dummy/config/environments/development.rb +42 -0
  135. data/test/dummy/config/environments/production.rb +79 -0
  136. data/test/dummy/config/environments/test.rb +34 -0
  137. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  138. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  139. data/test/dummy/config/initializers/inflections.rb +16 -0
  140. data/test/dummy/config/initializers/mime_types.rb +5 -0
  141. data/test/dummy/config/initializers/secret_token.rb +12 -0
  142. data/test/dummy/config/initializers/session_store.rb +3 -0
  143. data/test/dummy/config/initializers/strong_parameter.rb +3 -0
  144. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  145. data/test/dummy/config/locales/en.yml +26 -0
  146. data/test/dummy/config/routes.rb +60 -0
  147. data/test/dummy/config.ru +4 -0
  148. data/test/dummy/db/migrate/20131107120635_create_authors.rb +9 -0
  149. data/test/dummy/db/migrate/20131218011851_create_books.rb +10 -0
  150. data/test/dummy/db/migrate/20140201000000_add_user_group_id_to_authors.rb +5 -0
  151. data/test/dummy/db/migrate/20140807065420_create_users.rb +10 -0
  152. data/test/dummy/db/schema.rb +93 -0
  153. data/test/dummy/public/404.html +58 -0
  154. data/test/dummy/public/422.html +58 -0
  155. data/test/dummy/public/500.html +57 -0
  156. data/test/dummy/public/favicon.ico +0 -0
  157. data/test/dummy/script/rails +6 -0
  158. data/test/dummy/test/functional/authors_controller_test.rb +631 -0
  159. data/test/dummy/test/functional/books_controller_test.rb +516 -0
  160. data/test/dummy/test/helpers/authors_helper_test.rb +4 -0
  161. data/test/dummy/test/unit/author_test.rb +7 -0
  162. data/test/dummy/test/unit/book_test.rb +7 -0
  163. data/test/edgar_test.rb +7 -0
  164. data/test/fixtures/authors.yml +32 -0
  165. data/test/fixtures/books.yml +56 -0
  166. data/test/fixtures/edgarj/model_permissions.yml +97 -0
  167. data/test/fixtures/edgarj/page_infos.yml +84 -0
  168. data/test/fixtures/edgarj/sssns.yml +38 -0
  169. data/test/fixtures/edgarj/user_group_users.yml +114 -0
  170. data/test/fixtures/edgarj/user_groups.yml +95 -0
  171. data/test/fixtures/users.yml +49 -0
  172. data/test/functional/edgarj/edgarj_controller_test.rb +24 -0
  173. data/test/functional/edgarj/model_permissions_controller_test.rb +554 -0
  174. data/test/functional/edgarj/user_group_users_controller_test.rb +567 -0
  175. data/test/integration/navigation_test.rb +10 -0
  176. data/test/support/edgarj/controller_supporter.rb +23 -0
  177. data/test/test_helper.rb +23 -0
  178. data/test/unit/edgarj/model_permission_test.rb +27 -0
  179. data/test/unit/edgarj/page_info_test.rb +7 -0
  180. data/test/unit/edgarj/sssn_test.rb +10 -0
  181. data/test/unit/edgarj/user_group_test.rb +32 -0
  182. data/test/unit/edgarj/user_group_user_test.rb +9 -0
  183. data/test/unit/helpers/edgarj/model_permissions_helper_test.rb +6 -0
  184. data/test/unit/helpers/edgarj/user_group_users_helper_test.rb +6 -0
  185. metadata +456 -0
@@ -0,0 +1,234 @@
1
+ module Edgarj
2
+ module Drawer
3
+ # 'Mediator' to draw list and form of the model on the view.
4
+ class Base
5
+ attr_accessor :vc
6
+
7
+ # * options
8
+ # * list_drawer_options - options for Edgarj::ListDrawer::Normal
9
+ # * draw_form_options - options for draw_form_options
10
+ def initialize(view_context, params, page_info, model, options={})
11
+ @vc = view_context
12
+ @params = params
13
+ @page_info = page_info
14
+ @model = model
15
+ @options = options.dup
16
+ end
17
+
18
+ # level-1 methods which may be modified most frequently:
19
+
20
+ # define model-wide default columns for view.
21
+ #
22
+ # If you need to customize, overwrite it at derived model class.
23
+ # Example:
24
+ # def columns
25
+ # %w(id name email updated_at)
26
+ # end
27
+ #
28
+ # === SEE ALSO
29
+ # list_columns:: define list columns
30
+ # form_columns:: define form columns
31
+ # search_form_columns:: define search form columns
32
+ def columns
33
+ @model.columns.map{|c| c.name}
34
+ end
35
+
36
+ # This defines list columns.
37
+ # You can overwrite this method at each model if it is different from
38
+ # columns. Default is calling columns().
39
+ #
40
+ # === SEE ALSO
41
+ # columns:: define default columns
42
+ # form_columns:: define form columns
43
+ # search_form_columns:: define search form columns
44
+ #
45
+ def list_columns
46
+ columns
47
+ end
48
+
49
+ # This defines form columns.
50
+ # You can overwrite this method at each model if it is different from
51
+ # columns. Default is calling columns().
52
+ #
53
+ # === SEE ALSO
54
+ # columns:: define default columns
55
+ # list_columns:: define list columns
56
+ # search_form_columns:: define search form columns
57
+ #
58
+ def form_columns
59
+ columns
60
+ end
61
+
62
+ # This defines search-form columns.
63
+ # You can overwrite this method at each model if it is different from
64
+ # columns. Default is calling columns().
65
+ #
66
+ # === SEE ALSO
67
+ # columns:: define default columns
68
+ # list_columns:: define list columns
69
+ # form_columns:: define form columns
70
+ #
71
+ def search_form_columns
72
+ columns
73
+ end
74
+
75
+ # level-2 methods which may be modified occasionally:
76
+
77
+ # This defines popup path for the column on the model.
78
+ #
79
+ # Default returns parent model's popup-controller.
80
+ # For example, book.author_id -> 'authors_popup' path
81
+ #
82
+ # You can overwrite this method at each model if it is different from
83
+ # columns.
84
+ #
85
+ # @see popup_path_on_search popup path for the column on the model's search form
86
+ def popup_path(col)
87
+ parent_model = @model.belongs_to_AR(col)
88
+ raise 'Parent is nil' if !parent_model
89
+
90
+ popup_field = PopupHelper::PopupField.new_builder(@model.model_name.param_key, col.name)
91
+ @vc.main_app.url_for(
92
+ controller: parent_model.model_name.collection + '_popup',
93
+ id_target: popup_field.id_target)
94
+ end
95
+
96
+ # This defines popup path for the search column on the model.
97
+ #
98
+ # Default returns parent model's popup-controller with id_target
99
+ # on the search column.
100
+ #
101
+ # @see popup_path popup path for the column on the model itself
102
+ def popup_path_on_search(col)
103
+ parent_model = @model.belongs_to_AR(col)
104
+ raise 'Parent is nil' if !parent_model
105
+
106
+ popup_field = PopupHelper::PopupField.new_builder(Edgarj::SearchForm.model_name.param_key, col.name)
107
+ @vc.main_app.url_for(
108
+ controller: parent_model.model_name.collection + '_popup',
109
+ id_target: popup_field.id_target)
110
+ end
111
+
112
+ # draw sort link on list column header
113
+ #
114
+ # === INPUTS
115
+ # col:: column data
116
+ # options:: options to url_for
117
+ def draw_sort(col, options={})
118
+ label = @model.human_attribute_name(col.name)
119
+ dir = 'asc'
120
+ if @page_info.order_by == fullname(col)
121
+ # toggle direction
122
+ if @page_info.dir == 'asc' || @page_info.dir.blank?
123
+ label += '▲'
124
+ dir = 'desc'
125
+ else
126
+ label += '▼'
127
+ end
128
+ end
129
+ @vc.link_to(label,
130
+ {
131
+ :controller => @params[:controller],
132
+ :action => 'page_info_save',
133
+ :id => @page_info.id,
134
+ 'edgarj_page_info[order_by]' => fullname(col),
135
+ 'edgarj_page_info[dir]' => dir
136
+ }.merge(options),
137
+ :remote => true,
138
+ :method => :put)
139
+ end
140
+
141
+ # draw list column header for both usual list and popup list
142
+ def draw_list_column_header(col, options={})
143
+ parent = @model.belongs_to_AR(col)
144
+ if parent then
145
+ @vc.draw_belongs_to_label_sub(@model, col.name, parent)
146
+ else
147
+ draw_sort(col, options)
148
+ end
149
+ end
150
+
151
+ def list_drawer_class
152
+ Edgarj::ListDrawer::Normal
153
+ end
154
+
155
+ def draw_list(list)
156
+ line_color = 1
157
+ d = list_drawer_class.new(
158
+ self,
159
+ @options[:list_drawer_options] || {})
160
+
161
+ @vc.content_tag(:table, width: '100%', class: 'list') do
162
+ @vc.content_tag(:tr) do
163
+ ''.html_safe.tap do |result|
164
+ for col in columns_for(list_columns) do
165
+ result << @vc.content_tag(:th) do
166
+ draw_list_column_header(col)
167
+ end
168
+ end
169
+ end
170
+ end +
171
+ ''.html_safe.tap do |trs|
172
+ for rec in list do
173
+ line_color = 1 - line_color
174
+ d.set_path(rec)
175
+ trs << @vc.content_tag(:tr, class: "list_line#{line_color}") do
176
+ ''.html_safe.tap do |cols|
177
+ for col in columns_for(list_columns) do
178
+ cols << d.draw_column(rec, col)
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
185
+ end
186
+
187
+ # return table_name + col.name
188
+ def fullname(col)
189
+ @model.table_name + '.' + col.name
190
+ end
191
+
192
+ def form_drawer_class
193
+ Edgarj::FormDrawer::Base
194
+ end
195
+
196
+ def draw_form(record)
197
+ url_hash = {
198
+ controller: @params[:controller],
199
+ action: record.new_record? ? 'create' : 'update',
200
+ }
201
+ url_hash[:id] = record.id if record.persisted?
202
+ @vc.form_for(record,
203
+ remote: true,
204
+ url: url_hash,
205
+ html: {
206
+ id: '_edgarj_form',
207
+ method: record.new_record? ? 'post' : 'put',
208
+ multipart: true,
209
+ #target: 'edgarj_form_frame'
210
+ }) do |f|
211
+ form_drawer_class.new(self, record, f).draw() +
212
+
213
+ # to avoid submit on 1-textfield form when hit [ENTER] key
214
+ '<input type="text" name="dummy" style="visibility:hidden" size=0>'.html_safe
215
+ end +
216
+ @vc.draw_form_buttons(@options[:draw_form_options] || {})
217
+ end
218
+
219
+ # return array of model columns (ActiveRecord::ConnectionAdapters::X_Column type).
220
+ #
221
+ # === INPUTS
222
+ # column_name_list:: column name list
223
+ def columns_for(column_name_list)
224
+ [].tap do |result|
225
+ for col_name in column_name_list do
226
+ if (col = @model.columns_hash[col_name])
227
+ result << col
228
+ end
229
+ end
230
+ end
231
+ end
232
+ end
233
+ end
234
+ end
@@ -0,0 +1,6 @@
1
+ module Edgarj
2
+ module Drawer
3
+ class Normal < Base
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,47 @@
1
+ module Edgarj
2
+ module Drawer
3
+ # PopupDrawer is the same as Drawer to draw 'belongs_to' model
4
+ # to popup window.
5
+ #
6
+ # For example, AuthorPopupDrawer is to draw Author popup,
7
+ # which is called from Book page.
8
+ #
9
+ # * options
10
+ # * list_drawer_options - options for Edgarj::ListDrawer::Normal
11
+ class Popup < Base
12
+ def draw_list(list)
13
+ line_color = 1
14
+ d = Edgarj::ListDrawer::Normal.new(
15
+ self,
16
+ @options[:list_drawer_options] || {})
17
+
18
+ @vc.content_tag(:table, width: '100%', class: 'list') do
19
+ @vc.content_tag(:tr) do
20
+ ''.html_safe.tap do |result|
21
+ for col in columns_for(list_columns) do
22
+ result << @vc.content_tag(:th) do
23
+ draw_list_column_header(col, id_target: @params[:id_target])
24
+ end
25
+ end
26
+ end
27
+ end +
28
+ ''.html_safe.tap do |trs|
29
+ for rec in list do
30
+ line_color = 1 - line_color
31
+ d.set_path(rec)
32
+ trs << @vc.content_tag(:tr,
33
+ class: "list_line#{line_color} edgarj_popup_list_row",
34
+ data: {id: rec.id, name: rec.name}) do
35
+ ''.html_safe.tap do |cols|
36
+ for col in columns_for(list_columns) do
37
+ cols << d.draw_column(rec, col)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,13 @@
1
+ module Edgarj
2
+ # Drawer is a 'presentor' and it is similar to decorator (like Draper),
3
+ # but this simply connects model to view in order to have view-related
4
+ # information for the model (or, to isolate view-related information
5
+ # from the model), while decorator inherits both model and
6
+ # view.
7
+ module Drawer
8
+ end
9
+ end
10
+
11
+ require 'edgarj/drawer/base'
12
+ require 'edgarj/drawer/normal'
13
+ require 'edgarj/drawer/popup'
@@ -0,0 +1,41 @@
1
+ # Model-wide CRUD permission for role. In other words,
2
+ # CRUD permission for each model for each role is defined by this.
3
+ #
4
+ # This permission is used for two purposes:
5
+ #
6
+ # 1. page access permission
7
+ # * If this object,which relates to a model by model-attribute, exists and
8
+ # user belongs to the role (= user-group), then the controller,
9
+ # which 'model_class' method returns the model, can be accessed.
10
+ # 1. popup access permission
11
+ # * Popup access for a model-class is an read-permission for that.
12
+ #
13
+ # Example:
14
+ # 1. User 'u' belongs to 'x-role' Edgarj::UserGroup.
15
+ # 1. x-role has author model permission.
16
+ # 1. User 'u' can access AuthorController page.
17
+ # 1. If x-role has READ permission on author model, then
18
+ # user 'u' can see author-popup on any 'belongs_to' related page
19
+ # (e.g. BookController book form's author-popup).
20
+ module Edgarj
21
+ class ModelPermission < ActiveRecord::Base
22
+ self.table_name = 'edgarj_model_permissions'
23
+ belongs_to :user_group
24
+
25
+ # define bitset on 'flags' column
26
+ module FlagsBitset
27
+ CREATE = 0x01
28
+ READ = 0x02
29
+ UPDATE = 0x04
30
+ DELETE = 0x08
31
+ end
32
+ FLAGS_ALL = FlagsBitset.constants.inject(0){|sum, flag|
33
+ sum += FlagsBitset.const_get(flag)
34
+ }
35
+
36
+ # return true if *ALL* requested flags are included in flags
37
+ def permitted?(requested_flags)
38
+ (self.flags & requested_flags) == requested_flags
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,47 @@
1
+ module Edgarj
2
+ class PageInfo < ActiveRecord::Base
3
+ self.table_name = 'edgarj_page_infos'
4
+
5
+ belongs_to :sssn
6
+
7
+ def self.intern(sssn, view, search_obj)
8
+ if !sssn || !(page_info = sssn.page_infos.find_by_view(view))
9
+ page_info = sssn.page_infos.build(
10
+ view: view,
11
+ lines: 10,
12
+ order_by: '',
13
+ dir: '',
14
+ page: 1)
15
+ page_info.record = search_obj
16
+
17
+ # save it to get id since id will be used later e.g.
18
+ # @vs.link_to(... @page_info.id) in Edgarj::Drawer::Base#draw_sort
19
+ page_info.save!
20
+ end
21
+ page_info
22
+ end
23
+
24
+ # serialize model and set it to model_data
25
+ #
26
+ def record=(record)
27
+ self.record_data = Base64.encode64(Marshal.dump(record))
28
+ end
29
+
30
+ # de-serialize in model_data and return it
31
+ #
32
+ def record
33
+ if self.record_data
34
+ # FIXME: Following code fixes the error:
35
+ # - ArgumentError (undefined class/module Search)
36
+ # - ArgumentError (undefined class/module SearchForm)
37
+ #
38
+ # But some autoload may smartlier fixes this?
39
+ Search
40
+ SearchForm
41
+ Marshal.load(Base64.decode64(self.record_data))
42
+ else
43
+ nil
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,81 @@
1
+ module Edgarj
2
+ # Search condition
3
+ #
4
+ # Abstract class to SearchForm and SearchPopup to provide common method
5
+ # 'conditions'.
6
+ #
7
+ # 'Search' instance will be stored in view_status.model.
8
+ #
9
+ # \@errors will be used for error_messages_for helper in search-form.
10
+ class Search
11
+ # required at 'form_for' helper
12
+ extend ActiveModel::Naming
13
+ extend ActiveModel::Conversion
14
+ # include ActiveModel::Conversion ??
15
+ include ActiveModel::Validations
16
+
17
+ # to support 'human_attribute_name'
18
+ extend ActiveModel::Translation
19
+
20
+ # cache the map: column name -> column type
21
+ #
22
+ # SearchForm instance is serialized to be stored at session so that
23
+ # another class (=Cache) is introduced to store cache information.
24
+ class Cache
25
+ include Singleton
26
+
27
+ attr_accessor :klass_hash, :hit, :miss
28
+
29
+ def initialize
30
+ @klass_hash = {}
31
+
32
+ # for cache statistics
33
+ @hit = 0
34
+ @miss = 0
35
+ end
36
+
37
+ # report hit rate
38
+ def klass_hash_report
39
+ sprintf("%d/%d", @hit, @hit + @miss)
40
+ end
41
+ end
42
+
43
+ attr_accessor :errors, :_klass_str
44
+
45
+ def initialize(klass)
46
+ @errors = ActiveModel::Errors.new(self)
47
+ @_klass_str = klass.to_s
48
+ end
49
+
50
+ # generate search-conditions from ActiveRecord attributes
51
+ #
52
+ # === RETURN
53
+ # [condition_string, value_array]:: values for :conditions option on model
54
+ def conditions
55
+ raise "Not implemented"
56
+ end
57
+
58
+ def persisted?
59
+ false
60
+ end
61
+
62
+ private
63
+ # cache column type
64
+ def column_type(col_name)
65
+ cache = Cache.instance
66
+ cache.klass_hash[@_klass_str] ||= {}
67
+ if v = cache.klass_hash[@_klass_str][col_name.to_s]
68
+ cache.hit += 1
69
+ v
70
+ else
71
+ cache.miss += 1
72
+ col = @_klass_str.constantize.columns.find{|c|
73
+ c.name == col_name.to_s
74
+ }
75
+ if col
76
+ cache.klass_hash[@_klass_str][col_name.to_s] = col.type
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end