active_scaffold-sequel 0.3.0

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 (318) hide show
  1. data/CHANGELOG +179 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README +36 -0
  4. data/app/assets/images/active_scaffold/add.gif +0 -0
  5. data/app/assets/images/active_scaffold/arrow_down.gif +0 -0
  6. data/app/assets/images/active_scaffold/arrow_up.gif +0 -0
  7. data/app/assets/images/active_scaffold/close.gif +0 -0
  8. data/app/assets/images/active_scaffold/close_touch.png +0 -0
  9. data/app/assets/images/active_scaffold/config.png +0 -0
  10. data/app/assets/images/active_scaffold/cross.png +0 -0
  11. data/app/assets/images/active_scaffold/gears.png +0 -0
  12. data/app/assets/images/active_scaffold/indicator-small.gif +0 -0
  13. data/app/assets/images/active_scaffold/indicator.gif +0 -0
  14. data/app/assets/images/active_scaffold/magnifier.png +0 -0
  15. data/app/assets/javascripts/active_scaffold.js.erb +19 -0
  16. data/app/assets/javascripts/jquery/active_scaffold.js +1057 -0
  17. data/app/assets/javascripts/jquery/date_picker_bridge.js.erb +24 -0
  18. data/app/assets/javascripts/jquery/draggable_lists.js +27 -0
  19. data/app/assets/javascripts/jquery/jquery.editinplace.js +743 -0
  20. data/app/assets/javascripts/jquery/tiny_mce_bridge.js +7 -0
  21. data/app/assets/javascripts/prototype/active_scaffold.js +1052 -0
  22. data/app/assets/javascripts/prototype/dhtml_history.js +870 -0
  23. data/app/assets/javascripts/prototype/form_enhancements.js +117 -0
  24. data/app/assets/javascripts/prototype/rico_corner.js +370 -0
  25. data/app/assets/javascripts/prototype/tiny_mce_bridge.js +7 -0
  26. data/app/assets/stylesheets/active_scaffold-ie.css +35 -0
  27. data/app/assets/stylesheets/active_scaffold.css.scss +14 -0
  28. data/app/assets/stylesheets/active_scaffold_colors.css.scss +395 -0
  29. data/app/assets/stylesheets/active_scaffold_extensions.css.erb +2 -0
  30. data/app/assets/stylesheets/active_scaffold_images.css.scss +43 -0
  31. data/app/assets/stylesheets/active_scaffold_layout.css +912 -0
  32. data/app/assets/stylesheets/blue-theme.css +74 -0
  33. data/config/locales/de.yml +114 -0
  34. data/config/locales/en.yml +118 -0
  35. data/config/locales/es.yml +120 -0
  36. data/config/locales/fr.yml +121 -0
  37. data/config/locales/hu.yml +74 -0
  38. data/config/locales/ja.yml +73 -0
  39. data/config/locales/ru.yml +123 -0
  40. data/frontends/default/views/_action_group.html.erb +24 -0
  41. data/frontends/default/views/_add_existing_form.html.erb +30 -0
  42. data/frontends/default/views/_base_form.html.erb +51 -0
  43. data/frontends/default/views/_create_form.html.erb +8 -0
  44. data/frontends/default/views/_create_form_on_list.html.erb +6 -0
  45. data/frontends/default/views/_field_search.html.erb +32 -0
  46. data/frontends/default/views/_form.html.erb +24 -0
  47. data/frontends/default/views/_form_association.html.erb +15 -0
  48. data/frontends/default/views/_form_association_footer.html.erb +47 -0
  49. data/frontends/default/views/_form_attribute.html.erb +20 -0
  50. data/frontends/default/views/_form_hidden_attribute.html.erb +2 -0
  51. data/frontends/default/views/_form_messages.html.erb +5 -0
  52. data/frontends/default/views/_horizontal_subform.html.erb +28 -0
  53. data/frontends/default/views/_horizontal_subform_footer.html.erb +0 -0
  54. data/frontends/default/views/_horizontal_subform_header.html.erb +11 -0
  55. data/frontends/default/views/_horizontal_subform_record.html.erb +38 -0
  56. data/frontends/default/views/_human_conditions.html.erb +1 -0
  57. data/frontends/default/views/_list.html.erb +18 -0
  58. data/frontends/default/views/_list_actions.html.erb +15 -0
  59. data/frontends/default/views/_list_calculations.html.erb +16 -0
  60. data/frontends/default/views/_list_column_headings.html.erb +12 -0
  61. data/frontends/default/views/_list_header.html.erb +10 -0
  62. data/frontends/default/views/_list_inline_adapter.html.erb +10 -0
  63. data/frontends/default/views/_list_messages.html.erb +30 -0
  64. data/frontends/default/views/_list_pagination.html.erb +11 -0
  65. data/frontends/default/views/_list_pagination_links.html.erb +9 -0
  66. data/frontends/default/views/_list_record.html.erb +14 -0
  67. data/frontends/default/views/_list_record_columns.html.erb +8 -0
  68. data/frontends/default/views/_list_with_header.html.erb +36 -0
  69. data/frontends/default/views/_messages.html.erb +10 -0
  70. data/frontends/default/views/_render_field.js.erb +20 -0
  71. data/frontends/default/views/_row.html.erb +6 -0
  72. data/frontends/default/views/_search.html.erb +34 -0
  73. data/frontends/default/views/_search_attribute.html.erb +10 -0
  74. data/frontends/default/views/_show.html.erb +8 -0
  75. data/frontends/default/views/_show_columns.html.erb +15 -0
  76. data/frontends/default/views/_update_actions.html.erb +9 -0
  77. data/frontends/default/views/_update_form.html.erb +6 -0
  78. data/frontends/default/views/_vertical_subform.html.erb +12 -0
  79. data/frontends/default/views/_vertical_subform_record.html.erb +38 -0
  80. data/frontends/default/views/action_confirmation.html.erb +13 -0
  81. data/frontends/default/views/add_existing.js.erb +18 -0
  82. data/frontends/default/views/add_existing_form.html.erb +5 -0
  83. data/frontends/default/views/create.html.erb +5 -0
  84. data/frontends/default/views/delete.html.erb +13 -0
  85. data/frontends/default/views/destroy.js.erb +24 -0
  86. data/frontends/default/views/edit_associated.js.erb +12 -0
  87. data/frontends/default/views/field_search.html.erb +5 -0
  88. data/frontends/default/views/form_messages.js.erb +1 -0
  89. data/frontends/default/views/list.html.erb +1 -0
  90. data/frontends/default/views/on_action_update.js.erb +13 -0
  91. data/frontends/default/views/on_create.js.erb +47 -0
  92. data/frontends/default/views/on_mark_all.js.erb +12 -0
  93. data/frontends/default/views/on_update.js.erb +31 -0
  94. data/frontends/default/views/refresh_list.js.erb +1 -0
  95. data/frontends/default/views/render_field.js.erb +1 -0
  96. data/frontends/default/views/search.html.erb +5 -0
  97. data/frontends/default/views/show.html.erb +5 -0
  98. data/frontends/default/views/update.html.erb +8 -0
  99. data/frontends/default/views/update_column.js.erb +16 -0
  100. data/frontends/default/views/update_row.js.erb +1 -0
  101. data/lib/active_scaffold/actions/common_search.rb +25 -0
  102. data/lib/active_scaffold/actions/core.rb +197 -0
  103. data/lib/active_scaffold/actions/create.rb +148 -0
  104. data/lib/active_scaffold/actions/delete.rb +76 -0
  105. data/lib/active_scaffold/actions/field_search.rb +82 -0
  106. data/lib/active_scaffold/actions/list.rb +196 -0
  107. data/lib/active_scaffold/actions/mark.rb +75 -0
  108. data/lib/active_scaffold/actions/nested.rb +245 -0
  109. data/lib/active_scaffold/actions/search.rb +48 -0
  110. data/lib/active_scaffold/actions/show.rb +61 -0
  111. data/lib/active_scaffold/actions/subform.rb +23 -0
  112. data/lib/active_scaffold/actions/update.rb +150 -0
  113. data/lib/active_scaffold/active_record_permissions.rb +136 -0
  114. data/lib/active_scaffold/attribute_params.rb +208 -0
  115. data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +39 -0
  116. data/lib/active_scaffold/bridges/ancestry.rb +5 -0
  117. data/lib/active_scaffold/bridges/calendar_date_select/as_cds_bridge.rb +67 -0
  118. data/lib/active_scaffold/bridges/calendar_date_select.rb +24 -0
  119. data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +107 -0
  120. data/lib/active_scaffold/bridges/cancan.rb +15 -0
  121. data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge.rb +31 -0
  122. data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge_helpers.rb +10 -0
  123. data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +45 -0
  124. data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +17 -0
  125. data/lib/active_scaffold/bridges/carrierwave.rb +12 -0
  126. data/lib/active_scaffold/bridges/country_helper/country_helper_bridge.rb +358 -0
  127. data/lib/active_scaffold/bridges/country_helper.rb +9 -0
  128. data/lib/active_scaffold/bridges/date_picker/ext.rb +45 -0
  129. data/lib/active_scaffold/bridges/date_picker/helper.rb +180 -0
  130. data/lib/active_scaffold/bridges/date_picker.rb +23 -0
  131. data/lib/active_scaffold/bridges/dragonfly/dragonfly_bridge.rb +34 -0
  132. data/lib/active_scaffold/bridges/dragonfly/dragonfly_bridge_helpers.rb +10 -0
  133. data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +27 -0
  134. data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +16 -0
  135. data/lib/active_scaffold/bridges/dragonfly.rb +9 -0
  136. data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +48 -0
  137. data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +57 -0
  138. data/lib/active_scaffold/bridges/file_column/form_ui.rb +34 -0
  139. data/lib/active_scaffold/bridges/file_column/list_ui.rb +26 -0
  140. data/lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb +43 -0
  141. data/lib/active_scaffold/bridges/file_column/test/mock_model.rb +9 -0
  142. data/lib/active_scaffold/bridges/file_column/test/test_helper.rb +15 -0
  143. data/lib/active_scaffold/bridges/file_column.rb +11 -0
  144. data/lib/active_scaffold/bridges/paperclip/form_ui.rb +27 -0
  145. data/lib/active_scaffold/bridges/paperclip/list_ui.rb +16 -0
  146. data/lib/active_scaffold/bridges/paperclip/paperclip_bridge.rb +36 -0
  147. data/lib/active_scaffold/bridges/paperclip/paperclip_bridge_helpers.rb +24 -0
  148. data/lib/active_scaffold/bridges/paperclip.rb +12 -0
  149. data/lib/active_scaffold/bridges/record_select/helpers.rb +86 -0
  150. data/lib/active_scaffold/bridges/record_select.rb +11 -0
  151. data/lib/active_scaffold/bridges/semantic_attributes/column.rb +20 -0
  152. data/lib/active_scaffold/bridges/semantic_attributes.rb +5 -0
  153. data/lib/active_scaffold/bridges/shared/date_bridge.rb +209 -0
  154. data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +46 -0
  155. data/lib/active_scaffold/bridges/tiny_mce.rb +17 -0
  156. data/lib/active_scaffold/bridges.rb +61 -0
  157. data/lib/active_scaffold/config/base.rb +71 -0
  158. data/lib/active_scaffold/config/core.rb +219 -0
  159. data/lib/active_scaffold/config/create.rb +44 -0
  160. data/lib/active_scaffold/config/delete.rb +33 -0
  161. data/lib/active_scaffold/config/field_search.rb +76 -0
  162. data/lib/active_scaffold/config/form.rb +48 -0
  163. data/lib/active_scaffold/config/list.rb +196 -0
  164. data/lib/active_scaffold/config/mark.rb +35 -0
  165. data/lib/active_scaffold/config/nested.rb +42 -0
  166. data/lib/active_scaffold/config/search.rb +73 -0
  167. data/lib/active_scaffold/config/show.rb +32 -0
  168. data/lib/active_scaffold/config/subform.rb +35 -0
  169. data/lib/active_scaffold/config/update.rb +41 -0
  170. data/lib/active_scaffold/configurable.rb +29 -0
  171. data/lib/active_scaffold/constraints.rb +170 -0
  172. data/lib/active_scaffold/data_structures/action_columns.rb +140 -0
  173. data/lib/active_scaffold/data_structures/action_link.rb +179 -0
  174. data/lib/active_scaffold/data_structures/action_links.rb +185 -0
  175. data/lib/active_scaffold/data_structures/actions.rb +45 -0
  176. data/lib/active_scaffold/data_structures/bridge.rb +22 -0
  177. data/lib/active_scaffold/data_structures/column.rb +389 -0
  178. data/lib/active_scaffold/data_structures/columns.rb +75 -0
  179. data/lib/active_scaffold/data_structures/error_message.rb +24 -0
  180. data/lib/active_scaffold/data_structures/nested_info.rb +130 -0
  181. data/lib/active_scaffold/data_structures/set.rb +57 -0
  182. data/lib/active_scaffold/data_structures/sorting.rb +172 -0
  183. data/lib/active_scaffold/engine.rb +4 -0
  184. data/lib/active_scaffold/extensions/action_controller_rendering.rb +22 -0
  185. data/lib/active_scaffold/extensions/action_view_rendering.rb +115 -0
  186. data/lib/active_scaffold/extensions/active_record_offset.rb +12 -0
  187. data/lib/active_scaffold/extensions/array.rb +7 -0
  188. data/lib/active_scaffold/extensions/cache_association.rb +16 -0
  189. data/lib/active_scaffold/extensions/localize.rb +10 -0
  190. data/lib/active_scaffold/extensions/name_option_for_datetime.rb +12 -0
  191. data/lib/active_scaffold/extensions/nil_id_in_url_params.rb +7 -0
  192. data/lib/active_scaffold/extensions/paginator_extensions.rb +26 -0
  193. data/lib/active_scaffold/extensions/routing_mapper.rb +48 -0
  194. data/lib/active_scaffold/extensions/to_label.rb +8 -0
  195. data/lib/active_scaffold/extensions/unsaved_associated.rb +60 -0
  196. data/lib/active_scaffold/extensions/unsaved_record.rb +20 -0
  197. data/lib/active_scaffold/extensions/usa_state.rb +46 -0
  198. data/lib/active_scaffold/finder.rb +372 -0
  199. data/lib/active_scaffold/helpers/association_helpers.rb +48 -0
  200. data/lib/active_scaffold/helpers/controller_helpers.rb +88 -0
  201. data/lib/active_scaffold/helpers/form_column_helpers.rb +321 -0
  202. data/lib/active_scaffold/helpers/human_condition_helpers.rb +62 -0
  203. data/lib/active_scaffold/helpers/id_helpers.rb +127 -0
  204. data/lib/active_scaffold/helpers/list_column_helpers.rb +340 -0
  205. data/lib/active_scaffold/helpers/pagination_helpers.rb +55 -0
  206. data/lib/active_scaffold/helpers/search_column_helpers.rb +267 -0
  207. data/lib/active_scaffold/helpers/show_column_helpers.rb +50 -0
  208. data/lib/active_scaffold/helpers/view_helpers.rb +342 -0
  209. data/lib/active_scaffold/marked_model.rb +38 -0
  210. data/lib/active_scaffold/paginator.rb +136 -0
  211. data/lib/active_scaffold/responds_to_parent.rb +70 -0
  212. data/lib/active_scaffold/version.rb +9 -0
  213. data/lib/active_scaffold.rb +368 -0
  214. data/lib/active_scaffold_env.rb +11 -0
  215. data/lib/generators/active_scaffold/USAGE +29 -0
  216. data/lib/generators/active_scaffold/active_scaffold_generator.rb +20 -0
  217. data/lib/generators/active_scaffold_controller/USAGE +19 -0
  218. data/lib/generators/active_scaffold_controller/active_scaffold_controller_generator.rb +29 -0
  219. data/lib/generators/active_scaffold_controller/templates/controller.rb +4 -0
  220. data/lib/generators/active_scaffold_controller/templates/helper.rb +2 -0
  221. data/public/blank.html +33 -0
  222. data/shoulda_macros/macros.rb +136 -0
  223. data/test/bridges/active_scaffold_dependent_protect_test.rb +34 -0
  224. data/test/bridges/bridge_test.rb +90 -0
  225. data/test/bridges/company.rb +81 -0
  226. data/test/bridges/paperclip_test.rb +68 -0
  227. data/test/bridges/tiny_mce_test.rb +27 -0
  228. data/test/bridges/unobtrusive_date_picker_test.rb +49 -0
  229. data/test/bridges/validation_reflection_test.rb +57 -0
  230. data/test/config/base_test.rb +15 -0
  231. data/test/config/core_test.rb +58 -0
  232. data/test/config/create_test.rb +58 -0
  233. data/test/config/delete_test.rb +33 -0
  234. data/test/config/field_search_test.rb +47 -0
  235. data/test/config/list_test.rb +129 -0
  236. data/test/config/nested_test.rb +62 -0
  237. data/test/config/search_test.rb +60 -0
  238. data/test/config/show_test.rb +43 -0
  239. data/test/config/subform_test.rb +17 -0
  240. data/test/config/update_test.rb +40 -0
  241. data/test/const_mocker.rb +36 -0
  242. data/test/data_structures/action_columns_test.rb +113 -0
  243. data/test/data_structures/action_link_test.rb +78 -0
  244. data/test/data_structures/action_links_test.rb +78 -0
  245. data/test/data_structures/actions_test.rb +25 -0
  246. data/test/data_structures/association_column_test.rb +42 -0
  247. data/test/data_structures/column_test.rb +185 -0
  248. data/test/data_structures/columns_test.rb +69 -0
  249. data/test/data_structures/error_message_test.rb +28 -0
  250. data/test/data_structures/set_test.rb +86 -0
  251. data/test/data_structures/sorting_test.rb +126 -0
  252. data/test/data_structures/standard_column_test.rb +24 -0
  253. data/test/data_structures/virtual_column_test.rb +23 -0
  254. data/test/extensions/active_record_test.rb +45 -0
  255. data/test/extensions/array_test.rb +12 -0
  256. data/test/helpers/form_column_helpers_test.rb +31 -0
  257. data/test/helpers/list_column_helpers_test.rb +42 -0
  258. data/test/helpers/pagination_helpers_test.rb +59 -0
  259. data/test/misc/active_record_permissions_test.rb +154 -0
  260. data/test/misc/attribute_params_test.rb +146 -0
  261. data/test/misc/configurable_test.rb +96 -0
  262. data/test/misc/constraints_test.rb +193 -0
  263. data/test/misc/finder_test.rb +92 -0
  264. data/test/misc/lang_test.rb +11 -0
  265. data/test/mock_app/app/controllers/application_controller.rb +10 -0
  266. data/test/mock_app/app/helpers/application_helper.rb +3 -0
  267. data/test/mock_app/config/boot.rb +110 -0
  268. data/test/mock_app/config/database.yml +16 -0
  269. data/test/mock_app/config/environment.rb +43 -0
  270. data/test/mock_app/config/environments/development.rb +17 -0
  271. data/test/mock_app/config/environments/production.rb +28 -0
  272. data/test/mock_app/config/environments/test.rb +28 -0
  273. data/test/mock_app/config/initializers/backtrace_silencers.rb +7 -0
  274. data/test/mock_app/config/initializers/inflections.rb +10 -0
  275. data/test/mock_app/config/initializers/mime_types.rb +5 -0
  276. data/test/mock_app/config/initializers/new_rails_defaults.rb +19 -0
  277. data/test/mock_app/config/initializers/session_store.rb +15 -0
  278. data/test/mock_app/config/locales/en.yml +5 -0
  279. data/test/mock_app/config/routes.rb +43 -0
  280. data/test/mock_app/db/test.sqlite3 +1 -0
  281. data/test/mock_app/public/blank.html +33 -0
  282. data/test/mock_app/public/images/active_scaffold/DO_NOT_EDIT +2 -0
  283. data/test/mock_app/public/images/active_scaffold/default/add.gif +0 -0
  284. data/test/mock_app/public/images/active_scaffold/default/arrow_down.gif +0 -0
  285. data/test/mock_app/public/images/active_scaffold/default/arrow_up.gif +0 -0
  286. data/test/mock_app/public/images/active_scaffold/default/close.gif +0 -0
  287. data/test/mock_app/public/images/active_scaffold/default/cross.png +0 -0
  288. data/test/mock_app/public/images/active_scaffold/default/indicator-small.gif +0 -0
  289. data/test/mock_app/public/images/active_scaffold/default/indicator.gif +0 -0
  290. data/test/mock_app/public/images/active_scaffold/default/magnifier.png +0 -0
  291. data/test/mock_app/public/javascripts/active_scaffold/DO_NOT_EDIT +2 -0
  292. data/test/mock_app/public/javascripts/active_scaffold/default/active_scaffold.js +532 -0
  293. data/test/mock_app/public/javascripts/active_scaffold/default/dhtml_history.js +867 -0
  294. data/test/mock_app/public/javascripts/active_scaffold/default/form_enhancements.js +117 -0
  295. data/test/mock_app/public/javascripts/active_scaffold/default/rico_corner.js +370 -0
  296. data/test/mock_app/public/stylesheets/active_scaffold/DO_NOT_EDIT +2 -0
  297. data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet-ie.css +35 -0
  298. data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet.css +848 -0
  299. data/test/model_stub.rb +55 -0
  300. data/test/run_all.rb +8 -0
  301. data/test/test_helper.rb +39 -0
  302. data/vendor/assets/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  303. data/vendor/assets/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  304. data/vendor/assets/images/ui-bg_flat_10_000000_40x100.png +0 -0
  305. data/vendor/assets/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  306. data/vendor/assets/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  307. data/vendor/assets/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  308. data/vendor/assets/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  309. data/vendor/assets/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  310. data/vendor/assets/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  311. data/vendor/assets/images/ui-icons_222222_256x240.png +0 -0
  312. data/vendor/assets/images/ui-icons_228ef1_256x240.png +0 -0
  313. data/vendor/assets/images/ui-icons_ef8c08_256x240.png +0 -0
  314. data/vendor/assets/images/ui-icons_ffd27a_256x240.png +0 -0
  315. data/vendor/assets/images/ui-icons_ffffff_256x240.png +0 -0
  316. data/vendor/assets/javascripts/jquery-ui-timepicker-addon.js +1276 -0
  317. data/vendor/assets/stylesheets/jquery-ui.css +568 -0
  318. metadata +502 -0
@@ -0,0 +1,73 @@
1
+ module ActiveScaffold::Config
2
+ class Search < Base
3
+ self.crud_type = :read
4
+
5
+ def initialize(core_config)
6
+ super
7
+ @text_search = self.class.text_search
8
+ @live = self.class.live?
9
+ @split_terms = self.class.split_terms
10
+
11
+ # start with the ActionLink defined globally
12
+ @link = self.class.link.clone
13
+ @action_group = self.class.action_group.clone if self.class.action_group
14
+ end
15
+
16
+
17
+ # global level configuration
18
+ # --------------------------
19
+ # the ActionLink for this action
20
+ cattr_accessor :link
21
+ @@link = ActiveScaffold::DataStructures::ActionLink.new('show_search', :label => :search, :type => :collection, :security_method => :search_authorized?, :ignore_method => :search_ignore?)
22
+
23
+ # A flag for how the search should do full-text searching in the database:
24
+ # * :full: LIKE %?%
25
+ # * :start: LIKE ?%
26
+ # * :end: LIKE %?
27
+ # * false: LIKE ?
28
+ # Default is :full
29
+ cattr_accessor :text_search
30
+ @@text_search = :full
31
+
32
+ # whether submits the search as you type
33
+ cattr_writer :live
34
+ def self.live?
35
+ @@live
36
+ end
37
+
38
+ # instance-level configuration
39
+ # ----------------------------
40
+
41
+ # provides access to the list of columns specifically meant for the Search to use
42
+ def columns
43
+ # we want to delay initializing to the @core.columns set for as long as possible. Too soon and .search_sql will not be available to .searchable?
44
+ unless @columns
45
+ self.columns = @core.columns.collect{|c| c.name if @core.columns._inheritable.include?(c.name) and c.searchable? and c.column and c.column[:type] == :string}.compact
46
+ end
47
+ @columns
48
+ end
49
+
50
+ public :columns=
51
+
52
+ # A flag for how the search should do full-text searching in the database:
53
+ # * :full: LIKE %?%
54
+ # * :start: LIKE ?%
55
+ # * :end: LIKE %?
56
+ # * false: LIKE ?
57
+ # Default is :full
58
+ attr_accessor :text_search
59
+
60
+ @@split_terms = " "
61
+ cattr_accessor :split_terms
62
+ attr_accessor :split_terms
63
+
64
+ # the ActionLink for this action
65
+ attr_accessor :link
66
+
67
+ # whether submits the search as you type
68
+ attr_writer :live
69
+ def live?
70
+ @live
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,32 @@
1
+ module ActiveScaffold::Config
2
+ class Show < Base
3
+ self.crud_type = :read
4
+
5
+ def initialize(core_config)
6
+ super
7
+ # start with the ActionLink defined globally
8
+ @link = self.class.link.clone
9
+ @action_group = self.class.action_group.clone if self.class.action_group
10
+ end
11
+
12
+ # global level configuration
13
+ # --------------------------
14
+ cattr_accessor :link
15
+ @@link = ActiveScaffold::DataStructures::ActionLink.new('show', :label => :show, :type => :member, :security_method => :show_authorized?)
16
+ # instance-level configuration
17
+ # ----------------------------
18
+
19
+ # the ActionLink for this action
20
+ attr_accessor :link
21
+ # the label for this action. used for the header.
22
+ attr_writer :label
23
+
24
+ # provides access to the list of columns specifically meant for this action to use
25
+ def columns
26
+ self.columns = @core.columns._inheritable unless @columns # lazy evaluation
27
+ @columns
28
+ end
29
+
30
+ public :columns=
31
+ end
32
+ end
@@ -0,0 +1,35 @@
1
+ module ActiveScaffold::Config
2
+ class Subform < Base
3
+ def initialize(core_config)
4
+ super
5
+ @layout = self.class.layout # default layout
6
+ end
7
+
8
+ # global level configuration
9
+ # --------------------------
10
+
11
+ cattr_accessor :layout
12
+ @@layout = :horizontal
13
+
14
+ # instance-level configuration
15
+ # ----------------------------
16
+
17
+ attr_accessor :layout
18
+
19
+ # provides access to the list of columns specifically meant for the Sub-Form to use
20
+ def columns
21
+ # we want to delay initializing to the @core.update.columns set for as long as possible. but we have to eventually clone, or else have a configuration "leak"
22
+ unless @columns
23
+ if @core.actions.include? :update
24
+ @columns = @core.update.columns.clone
25
+ else
26
+ self.columns = @core.columns._inheritable
27
+ end
28
+ end
29
+
30
+ @columns
31
+ end
32
+
33
+ public :columns=
34
+ end
35
+ end
@@ -0,0 +1,41 @@
1
+ module ActiveScaffold::Config
2
+ class Update < ActiveScaffold::Config::Form
3
+ self.crud_type = :update
4
+ def initialize(core_config)
5
+ super
6
+ self.nested_links = self.class.nested_links
7
+ self.refresh_list = self.class.refresh_list
8
+ end
9
+
10
+ # global level configuration
11
+ # --------------------------
12
+ # the ActionLink for this action
13
+ def self.link
14
+ @@link
15
+ end
16
+ def self.link=(val)
17
+ @@link = val
18
+ end
19
+ @@link = ActiveScaffold::DataStructures::ActionLink.new('edit', :label => :edit, :type => :member, :security_method => :update_authorized?)
20
+
21
+ # whether we should refresh list after update or not
22
+ cattr_accessor :refresh_list
23
+ @@refresh_list = false
24
+
25
+ # instance-level configuration
26
+ # ----------------------------
27
+
28
+ attr_accessor :nested_links
29
+ cattr_accessor :nested_links
30
+ @@nested_links = false
31
+
32
+ attr_writer :hide_nested_column
33
+ def hide_nested_column
34
+ @hide_nested_column.nil? ? true : @hide_nested_column
35
+ end
36
+
37
+ # whether we should refresh list after update or not
38
+ attr_accessor :refresh_list
39
+
40
+ end
41
+ end
@@ -0,0 +1,29 @@
1
+ module ActiveScaffold
2
+ # Exposes a +configure+ method that accepts a block and runs all contents of the block in two contexts, as opposed to the normal one. First, everything gets evaluated as part of the object including Configurable. Then, as a failover, missing methods and variables are evaluated in the original binding of the block.
3
+ #
4
+ # Note that this only works with "barewords". Constants, instance variables, and class variables are not currently supported in both contexts.
5
+ #
6
+ # May add the given functionality at both the class and instance level. For the former, use +extend+, and for the latter, use +include+.
7
+ module Configurable
8
+ def configure(&configuration_block)
9
+ return unless configuration_block
10
+ @configuration_binding = configuration_block.binding
11
+ ret = instance_exec self, &configuration_block
12
+ @configuration_binding = nil
13
+ return ret
14
+ end
15
+
16
+ # this method will surely need tweaking. for example, i'm not sure if it should call super before or after it tries to eval with the binding.
17
+ def method_missing(name, *args)
18
+ begin
19
+ super
20
+ rescue NoMethodError, NameError
21
+ if @configuration_binding.nil?
22
+ raise $!
23
+ else
24
+ eval("self", @configuration_binding).send(name, *args)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,170 @@
1
+ module ActiveScaffold
2
+ module Constraints
3
+
4
+ protected
5
+
6
+ # Returns the current constraints
7
+ def active_scaffold_constraints
8
+ @active_scaffold_constraints ||= active_scaffold_session_storage[:constraints] || {}
9
+ end
10
+
11
+ def set_active_scaffold_constraints
12
+ associations_by_params = {}
13
+ active_scaffold_config.model.association_reflections.each do |name,association|
14
+ associations_by_params[association[:class_name].foreign_key] = association[:name]
15
+ end
16
+ params.each do |key, value|
17
+ active_scaffold_constraints[associations_by_params[key]] = value if associations_by_params.include? key
18
+ end
19
+ end
20
+
21
+ # For each enabled action, adds the constrained columns to the ActionColumns object (if it exists).
22
+ # This lets the ActionColumns object skip constrained columns.
23
+ #
24
+ # If the constraint value is a Hash, then we assume the constraint is a multi-level association constraint (the reverse of a has_many :through) and we do NOT register the constraint column.
25
+ def register_constraints_with_action_columns(association_constrained_fields = [], exclude_actions = [])
26
+ constrained_fields = active_scaffold_constraints.reject{|k, v| v.is_a? Hash}.keys.collect{|k| k.to_sym}
27
+ constrained_fields = constrained_fields | association_constrained_fields
28
+ if self.class.uses_active_scaffold?
29
+ # we actually want to do this whether constrained_fields exist or not, so that we can reset the array when they don't
30
+ active_scaffold_config.actions.each do |action_name|
31
+ next if exclude_actions.include?(action_name)
32
+ action = active_scaffold_config.send(action_name)
33
+ next unless action.respond_to? :columns
34
+ action.columns.constraint_columns = constrained_fields
35
+ end
36
+ end
37
+ end
38
+
39
+ # Returns search conditions based on the current scaffold constraints.
40
+ #
41
+ # Supports constraints based on either a column name (in which case it checks for an association
42
+ # or just uses the search_sql) or a database field name.
43
+ #
44
+ # All of this work is primarily to support nested scaffolds in a manner generally useful for other
45
+ # embedded scaffolds.
46
+ def conditions_from_constraints
47
+ conditions = nil
48
+ active_scaffold_constraints.each do |k, v|
49
+ column = active_scaffold_config.columns[k]
50
+ constraint_condition = if column
51
+ # Assume this is a multi-level association constraint.
52
+ # example:
53
+ # data model: Park -> Den -> Bear
54
+ # constraint: :den => {:park => 5}
55
+ if v.is_a? Hash
56
+ far_association_klass = column.association.associated_class.association_reflection(v.keys.first).associated_class
57
+ field = far_association_klass.primary_key
58
+ table = far_association_klass.table_name
59
+
60
+ active_scaffold_includes.concat([{k => v.keys.first}]) # e.g. {:den => :park}
61
+ constraint_condition_for("#{table}__#{field}".to_sym, v.values.first)
62
+
63
+ # association column constraint
64
+ elsif column.association
65
+ if column.association[:type] == :many_to_many
66
+ active_scaffold_habtm_joins.concat column.includes
67
+ else
68
+ active_scaffold_includes.concat column.includes
69
+ end
70
+ condition_from_association_constraint(column.association, v)
71
+
72
+ # regular column constraints
73
+ elsif column.searchable?
74
+ active_scaffold_includes.concat column.includes
75
+ constraint_condition_for(column.search_sql, v)
76
+ end
77
+ # unknown-to-activescaffold-but-real-database-column constraint
78
+ elsif active_scaffold_config.model.columns.include? k
79
+ constraint_condition_for(k, v)
80
+ else
81
+ raise ActiveScaffold::MalformedConstraint, constraint_error(active_scaffold_config.model, k), caller
82
+ end
83
+
84
+ conditions = merge_conditions(conditions, constraint_condition)
85
+ end
86
+
87
+ conditions
88
+ end
89
+
90
+ # We do NOT want to use .search_sql. If anything, search_sql will refer
91
+ # to a human-searchable value on the associated record.
92
+ def condition_from_association_constraint(association, value)
93
+ # when the reverse association is a :belongs_to, the id for the associated object only exists as
94
+ # the primary_key on the other table. so for :has_one and :has_many (when the reverse is :belongs_to),
95
+ # we have to use the other model's primary_key.
96
+ #
97
+ # please see the relevant tests for concrete examples.
98
+ field = if [:one_to_one, :one_to_many].include?(association[:type])
99
+ association.associated_class.primary_key
100
+ elsif [:many_to_many].include?(association[:type])
101
+ association[:class_name].foreign_key
102
+ else
103
+ association[:name].to_s.foreign_key
104
+ end
105
+
106
+ table = case association[:type]
107
+ when :many_to_many
108
+ association[:join_table]
109
+
110
+ when :many_to_one
111
+ active_scaffold_config.model.table_name
112
+
113
+ else
114
+ association.associated_class.table_name
115
+ end
116
+
117
+ # XXX no idea what this is supposed to do, in my setup are all association.options[:primary_key] nils
118
+ # if association.options[:primary_key]
119
+ # value = association.klass.find(value).send(association.options[:primary_key])
120
+ # end
121
+
122
+ constraint_condition_for("#{table}__#{field}".to_sym, value)
123
+ end
124
+
125
+ def constraint_error(klass, column_name)
126
+ "Malformed constraint `#{klass}##{column_name}'. If it's a legitimate column, and you are using a nested scaffold, please specify or double-check the reverse association name."
127
+ end
128
+
129
+ # Applies constraints to the given record.
130
+ #
131
+ # Searches through the known columns for association columns. If the given constraint is an association,
132
+ # it assumes that the constraint value is an id. It then does a association.klass.find with the value
133
+ # and adds the associated object to the record.
134
+ #
135
+ # For some operations ActiveRecord will automatically update the database. That's not always ok.
136
+ # If it *is* ok (e.g. you're in a transaction), then set :allow_autosave to true.
137
+ def apply_constraints_to_record(record, options = {})
138
+ options[:allow_autosave] = false if options[:allow_autosave].nil?
139
+
140
+ active_scaffold_constraints.each do |k, v|
141
+ column = active_scaffold_config.columns[k]
142
+ if column and column.association
143
+ if column.plural_association?
144
+ record.send("add_#{k.to_s.singularize}", column.association.associated_class.filter(v))
145
+ else # regular singular association
146
+ record.send("#{k}=", column.association.associated_class.filter(v))
147
+
148
+ # setting the belongs_to side of a has_one isn't safe. if the has_one was already
149
+ # specified, rails won't automatically clear out the previous associated record.
150
+ #
151
+ # note that we can't take the extra step to correct this unless we're permitted to
152
+ # run operations where activerecord auto-saves the object.
153
+ reverse = column.association.associated_class.association_reflection(column.association.reciprocal)
154
+ if reverse[:type] == :one_to_one and options[:allow_autosave]
155
+ record.send(k).send("#{column.association.reciprocal}=", record)
156
+ end
157
+ end
158
+ else
159
+ record.send("#{k}=", v)
160
+ end
161
+ end
162
+ end
163
+
164
+ private
165
+
166
+ def constraint_condition_for(sql, value)
167
+ {sql => value}
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,140 @@
1
+ module ActiveScaffold::DataStructures
2
+ # A set of columns. These structures can be nested for organization.
3
+ class ActionColumns < ActiveScaffold::DataStructures::Set
4
+ include ActiveScaffold::Configurable
5
+
6
+ # this lets us refer back to the action responsible for this link, if it exists.
7
+ # the immediate need here is to get the crud_type so we can dynamically filter columns from the set.
8
+ attr_accessor :action
9
+
10
+ # labels are useful for the Create/Update forms, when we display columns in a grouped fashion and want to name them separately
11
+ attr_writer :label
12
+ def label
13
+ as_(@label) if @label
14
+ end
15
+ def css_class
16
+ @label.to_s.underscore
17
+ end
18
+
19
+ # Whether this column set is collapsed by default in contexts where collapsing is supported
20
+ attr_accessor :collapsed
21
+
22
+ # nests a subgroup in the column set
23
+ def add_subgroup(label, &proc)
24
+ columns = ActiveScaffold::DataStructures::ActionColumns.new
25
+ columns.label = label
26
+ columns.action = self.action
27
+ columns.configure &proc
28
+ self.exclude columns.collect_columns
29
+ self.add columns
30
+ end
31
+
32
+ def include?(item)
33
+ @set.each do |c|
34
+ return true if !c.is_a? Symbol and c.include? item
35
+ return true if c == item.to_sym
36
+ end
37
+ return false
38
+ end
39
+
40
+ def names
41
+ self.collect(&:name)
42
+ end
43
+
44
+ def names_without_auth_check
45
+ Array(@set)
46
+ end
47
+
48
+ protected
49
+
50
+ def collect_columns
51
+ @set.collect {|col| col.is_a?(ActiveScaffold::DataStructures::ActionColumns) ? col.collect_columns : col}
52
+ end
53
+
54
+ # called during clone or dup. makes the clone/dup deeper.
55
+ def initialize_copy(from)
56
+ @set = from.instance_variable_get('@set').clone
57
+ end
58
+
59
+ # A package of stuff to add after the configuration block. This is an attempt at making a certain level of functionality inaccessible during configuration, to reduce possible breakage from misuse.
60
+ # The bulk of the package is a means of connecting the referential column set (ActionColumns) with the actual column objects (Columns). This lets us iterate over the set and yield real column objects.
61
+ module AfterConfiguration
62
+ # Redefine the each method to yield actual Column objects.
63
+ # It will skip constrained and unauthorized columns.
64
+ #
65
+ # Options:
66
+ # * :flatten - whether to recursively iterate on nested sets. default is false.
67
+ # * :for - the record (or class) being iterated over. used for column-level security. default is the class.
68
+ def each(options = {}, &proc)
69
+ options[:for] ||= @columns.active_record_class
70
+ self.unauthorized_columns = []
71
+ @set.each do |item|
72
+ unless item.is_a? ActiveScaffold::DataStructures::ActionColumns
73
+ item = (@columns[item] || ActiveScaffold::DataStructures::Column.new(item.to_sym, @columns.active_record_class))
74
+ next if self.skip_column?(item, options)
75
+ end
76
+ if item.is_a? ActiveScaffold::DataStructures::ActionColumns and options.has_key?(:flatten) and options[:flatten]
77
+ item.each(options, &proc)
78
+ else
79
+ yield item
80
+ end
81
+ end
82
+ end
83
+
84
+ def collect_visible(options = {}, &proc)
85
+ columns = []
86
+ options[:for] ||= @columns.active_record_class
87
+ self.unauthorized_columns = []
88
+ @set.each do |item|
89
+ unless item.is_a? ActiveScaffold::DataStructures::ActionColumns
90
+ item = (@columns[item] || ActiveScaffold::DataStructures::Column.new(item.to_sym, @columns.active_record_class))
91
+ next if self.skip_column?(item, options)
92
+ end
93
+ if item.is_a? ActiveScaffold::DataStructures::ActionColumns and options.has_key?(:flatten) and options[:flatten]
94
+ columns = columns + item.collect(options, &proc)
95
+ else
96
+ columns << item
97
+ end
98
+ end
99
+ columns
100
+ end
101
+
102
+ def skip_column?(column, options)
103
+ result = false
104
+ # skip if this matches a constrained column
105
+ result = true if constraint_columns.include?(column.name)
106
+ # skip if this matches the field_name of a constrained column
107
+ result = true if column.field_name and constraint_columns.include?(column.field_name)
108
+ # skip this field if it's not authorized
109
+ unless options[:for].authorized_for?(:action => options[:action], :crud_type => options[:crud_type] || self.action.crud_type, :column => column.name)
110
+ self.unauthorized_columns << column.name
111
+ result = true
112
+ end
113
+ return result
114
+ end
115
+
116
+ # registers a set of column objects (recursively, for all nested ActionColumns)
117
+ def set_columns(columns)
118
+ @columns = columns
119
+ # iterate over @set instead of self to avoid dealing with security queries
120
+ @set.each do |item|
121
+ item.set_columns(columns) if item.respond_to? :set_columns
122
+ end
123
+ end
124
+
125
+ attr_writer :constraint_columns
126
+ def constraint_columns
127
+ @constraint_columns ||= []
128
+ end
129
+
130
+ attr_writer :unauthorized_columns
131
+ def unauthorized_columns
132
+ @unauthorized_columns ||= []
133
+ end
134
+
135
+ def length
136
+ ((@set - self.constraint_columns) - self.unauthorized_columns).length
137
+ end
138
+ end
139
+ end
140
+ end