edgarj 0.01.12

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