active_scaffold_vho 3.0.6

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 (279) hide show
  1. data/.autotest +27 -0
  2. data/.document +5 -0
  3. data/CHANGELOG +179 -0
  4. data/Gemfile +13 -0
  5. data/Gemfile.lock +20 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README +63 -0
  8. data/Rakefile +53 -0
  9. data/frontends/default/images/add.gif +0 -0
  10. data/frontends/default/images/arrow_down.gif +0 -0
  11. data/frontends/default/images/arrow_up.gif +0 -0
  12. data/frontends/default/images/close.gif +0 -0
  13. data/frontends/default/images/config.png +0 -0
  14. data/frontends/default/images/cross.png +0 -0
  15. data/frontends/default/images/gears.png +0 -0
  16. data/frontends/default/images/indicator-small.gif +0 -0
  17. data/frontends/default/images/indicator.gif +0 -0
  18. data/frontends/default/images/magnifier.png +0 -0
  19. data/frontends/default/javascripts/jquery/active_scaffold.js +957 -0
  20. data/frontends/default/javascripts/jquery/jquery.editinplace.js +743 -0
  21. data/frontends/default/javascripts/prototype/active_scaffold.js +957 -0
  22. data/frontends/default/javascripts/prototype/dhtml_history.js +867 -0
  23. data/frontends/default/javascripts/prototype/form_enhancements.js +117 -0
  24. data/frontends/default/javascripts/prototype/rico_corner.js +370 -0
  25. data/frontends/default/stylesheets/stylesheet-ie.css +35 -0
  26. data/frontends/default/stylesheets/stylesheet.css +964 -0
  27. data/frontends/default/views/_action_group.html.erb +20 -0
  28. data/frontends/default/views/_add_existing_form.html.erb +30 -0
  29. data/frontends/default/views/_base_form.html.erb +45 -0
  30. data/frontends/default/views/_create_form.html.erb +8 -0
  31. data/frontends/default/views/_create_form_on_list.html.erb +6 -0
  32. data/frontends/default/views/_field_search.html.erb +32 -0
  33. data/frontends/default/views/_form.html.erb +24 -0
  34. data/frontends/default/views/_form_association.html.erb +14 -0
  35. data/frontends/default/views/_form_association_footer.html.erb +40 -0
  36. data/frontends/default/views/_form_attribute.html.erb +15 -0
  37. data/frontends/default/views/_form_hidden_attribute.html.erb +2 -0
  38. data/frontends/default/views/_form_messages.html.erb +5 -0
  39. data/frontends/default/views/_horizontal_subform.html.erb +19 -0
  40. data/frontends/default/views/_horizontal_subform_header.html.erb +10 -0
  41. data/frontends/default/views/_horizontal_subform_record.html.erb +37 -0
  42. data/frontends/default/views/_human_conditions.html.erb +1 -0
  43. data/frontends/default/views/_list.html.erb +18 -0
  44. data/frontends/default/views/_list_actions.html.erb +15 -0
  45. data/frontends/default/views/_list_calculations.html.erb +16 -0
  46. data/frontends/default/views/_list_column_headings.html.erb +12 -0
  47. data/frontends/default/views/_list_header.html.erb +10 -0
  48. data/frontends/default/views/_list_inline_adapter.html.erb +10 -0
  49. data/frontends/default/views/_list_messages.html.erb +32 -0
  50. data/frontends/default/views/_list_pagination.html.erb +11 -0
  51. data/frontends/default/views/_list_pagination_links.html.erb +9 -0
  52. data/frontends/default/views/_list_record.html.erb +14 -0
  53. data/frontends/default/views/_list_record_columns.html.erb +8 -0
  54. data/frontends/default/views/_list_with_header.html.erb +32 -0
  55. data/frontends/default/views/_messages.html.erb +10 -0
  56. data/frontends/default/views/_render_field.js.rjs +13 -0
  57. data/frontends/default/views/_row.html.erb +12 -0
  58. data/frontends/default/views/_search.html.erb +34 -0
  59. data/frontends/default/views/_search_attribute.html.erb +10 -0
  60. data/frontends/default/views/_show.html.erb +8 -0
  61. data/frontends/default/views/_show_columns.html.erb +15 -0
  62. data/frontends/default/views/_update_actions.html.erb +9 -0
  63. data/frontends/default/views/_update_form.html.erb +6 -0
  64. data/frontends/default/views/_vertical_subform.html.erb +12 -0
  65. data/frontends/default/views/_vertical_subform_record.html.erb +38 -0
  66. data/frontends/default/views/action_confirmation.html.erb +13 -0
  67. data/frontends/default/views/add_existing.js.rjs +17 -0
  68. data/frontends/default/views/add_existing_form.html.erb +5 -0
  69. data/frontends/default/views/create.html.erb +5 -0
  70. data/frontends/default/views/delete.html.erb +13 -0
  71. data/frontends/default/views/destroy.js.rjs +11 -0
  72. data/frontends/default/views/edit_associated.js.rjs +11 -0
  73. data/frontends/default/views/field_search.html.erb +5 -0
  74. data/frontends/default/views/form_messages.js.rjs +1 -0
  75. data/frontends/default/views/list.html.erb +1 -0
  76. data/frontends/default/views/list.js.rjs +1 -0
  77. data/frontends/default/views/on_action_update.js.rjs +8 -0
  78. data/frontends/default/views/on_create.js.rjs +41 -0
  79. data/frontends/default/views/on_update.js.rjs +28 -0
  80. data/frontends/default/views/search.html.erb +5 -0
  81. data/frontends/default/views/show.html.erb +5 -0
  82. data/frontends/default/views/update.html.erb +8 -0
  83. data/frontends/default/views/update_column.js.rjs +13 -0
  84. data/frontends/default/views/update_row.js.rjs +1 -0
  85. data/init.rb +9 -0
  86. data/lib/active_record_permissions.rb +134 -0
  87. data/lib/active_scaffold/actions/common_search.rb +22 -0
  88. data/lib/active_scaffold/actions/core.rb +170 -0
  89. data/lib/active_scaffold/actions/create.rb +145 -0
  90. data/lib/active_scaffold/actions/delete.rb +75 -0
  91. data/lib/active_scaffold/actions/field_search.rb +82 -0
  92. data/lib/active_scaffold/actions/list.rb +184 -0
  93. data/lib/active_scaffold/actions/mark.rb +50 -0
  94. data/lib/active_scaffold/actions/nested.rb +250 -0
  95. data/lib/active_scaffold/actions/search.rb +47 -0
  96. data/lib/active_scaffold/actions/show.rb +61 -0
  97. data/lib/active_scaffold/actions/subform.rb +17 -0
  98. data/lib/active_scaffold/actions/update.rb +141 -0
  99. data/lib/active_scaffold/attribute_params.rb +207 -0
  100. data/lib/active_scaffold/bridges/ancestry/bridge.rb +5 -0
  101. data/lib/active_scaffold/bridges/ancestry/lib/ancestry_bridge.rb +39 -0
  102. data/lib/active_scaffold/bridges/bridge.rb +52 -0
  103. data/lib/active_scaffold/bridges/calendar_date_select/bridge.rb +16 -0
  104. data/lib/active_scaffold/bridges/calendar_date_select/lib/as_cds_bridge.rb +79 -0
  105. data/lib/active_scaffold/bridges/carrierwave/bridge.rb +7 -0
  106. data/lib/active_scaffold/bridges/carrierwave/lib/carrierwave_bridge.rb +38 -0
  107. data/lib/active_scaffold/bridges/carrierwave/lib/carrierwave_bridge_helpers.rb +26 -0
  108. data/lib/active_scaffold/bridges/carrierwave/lib/form_ui.rb +35 -0
  109. data/lib/active_scaffold/bridges/carrierwave/lib/list_ui.rb +17 -0
  110. data/lib/active_scaffold/bridges/date_picker/bridge.rb +22 -0
  111. data/lib/active_scaffold/bridges/date_picker/lib/datepicker_bridge.rb +225 -0
  112. data/lib/active_scaffold/bridges/date_picker/public/javascripts/date_picker_bridge.js +22 -0
  113. data/lib/active_scaffold/bridges/file_column/bridge.rb +11 -0
  114. data/lib/active_scaffold/bridges/file_column/lib/as_file_column_bridge.rb +46 -0
  115. data/lib/active_scaffold/bridges/file_column/lib/file_column_helpers.rb +59 -0
  116. data/lib/active_scaffold/bridges/file_column/lib/form_ui.rb +37 -0
  117. data/lib/active_scaffold/bridges/file_column/lib/list_ui.rb +26 -0
  118. data/lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb +43 -0
  119. data/lib/active_scaffold/bridges/file_column/test/mock_model.rb +9 -0
  120. data/lib/active_scaffold/bridges/file_column/test/test_helper.rb +15 -0
  121. data/lib/active_scaffold/bridges/paperclip/bridge.rb +10 -0
  122. data/lib/active_scaffold/bridges/paperclip/lib/form_ui.rb +27 -0
  123. data/lib/active_scaffold/bridges/paperclip/lib/list_ui.rb +16 -0
  124. data/lib/active_scaffold/bridges/paperclip/lib/paperclip_bridge.rb +38 -0
  125. data/lib/active_scaffold/bridges/paperclip/lib/paperclip_bridge_helpers.rb +26 -0
  126. data/lib/active_scaffold/bridges/semantic_attributes/bridge.rb +5 -0
  127. data/lib/active_scaffold/bridges/semantic_attributes/lib/semantic_attributes_bridge.rb +20 -0
  128. data/lib/active_scaffold/bridges/shared/date_bridge.rb +187 -0
  129. data/lib/active_scaffold/bridges/tiny_mce/bridge.rb +5 -0
  130. data/lib/active_scaffold/bridges/tiny_mce/lib/tiny_mce_bridge.rb +45 -0
  131. data/lib/active_scaffold/bridges/validation_reflection/bridge.rb +8 -0
  132. data/lib/active_scaffold/bridges/validation_reflection/lib/validation_reflection_bridge.rb +21 -0
  133. data/lib/active_scaffold/config/base.rb +62 -0
  134. data/lib/active_scaffold/config/core.rb +220 -0
  135. data/lib/active_scaffold/config/create.rb +51 -0
  136. data/lib/active_scaffold/config/delete.rb +34 -0
  137. data/lib/active_scaffold/config/field_search.rb +75 -0
  138. data/lib/active_scaffold/config/form.rb +47 -0
  139. data/lib/active_scaffold/config/list.rb +174 -0
  140. data/lib/active_scaffold/config/mark.rb +22 -0
  141. data/lib/active_scaffold/config/nested.rb +44 -0
  142. data/lib/active_scaffold/config/search.rb +69 -0
  143. data/lib/active_scaffold/config/show.rb +35 -0
  144. data/lib/active_scaffold/config/subform.rb +35 -0
  145. data/lib/active_scaffold/config/update.rb +46 -0
  146. data/lib/active_scaffold/configurable.rb +29 -0
  147. data/lib/active_scaffold/constraints.rb +184 -0
  148. data/lib/active_scaffold/data_structures/action_columns.rb +133 -0
  149. data/lib/active_scaffold/data_structures/action_link.rb +171 -0
  150. data/lib/active_scaffold/data_structures/action_links.rb +175 -0
  151. data/lib/active_scaffold/data_structures/actions.rb +45 -0
  152. data/lib/active_scaffold/data_structures/column.rb +351 -0
  153. data/lib/active_scaffold/data_structures/columns.rb +75 -0
  154. data/lib/active_scaffold/data_structures/error_message.rb +24 -0
  155. data/lib/active_scaffold/data_structures/nested_info.rb +123 -0
  156. data/lib/active_scaffold/data_structures/set.rb +62 -0
  157. data/lib/active_scaffold/data_structures/sorting.rb +168 -0
  158. data/lib/active_scaffold/finder.rb +333 -0
  159. data/lib/active_scaffold/helpers/association_helpers.rb +40 -0
  160. data/lib/active_scaffold/helpers/controller_helpers.rb +82 -0
  161. data/lib/active_scaffold/helpers/country_helpers.rb +352 -0
  162. data/lib/active_scaffold/helpers/form_column_helpers.rb +347 -0
  163. data/lib/active_scaffold/helpers/human_condition_helpers.rb +59 -0
  164. data/lib/active_scaffold/helpers/id_helpers.rb +127 -0
  165. data/lib/active_scaffold/helpers/list_column_helpers.rb +361 -0
  166. data/lib/active_scaffold/helpers/pagination_helpers.rb +55 -0
  167. data/lib/active_scaffold/helpers/search_column_helpers.rb +243 -0
  168. data/lib/active_scaffold/helpers/show_column_helpers.rb +46 -0
  169. data/lib/active_scaffold/helpers/view_helpers.rb +356 -0
  170. data/lib/active_scaffold/locale/de.rb +120 -0
  171. data/lib/active_scaffold/locale/en.rb +119 -0
  172. data/lib/active_scaffold/locale/es.yml +115 -0
  173. data/lib/active_scaffold/locale/fr.rb +116 -0
  174. data/lib/active_scaffold/locale/hu.yml +63 -0
  175. data/lib/active_scaffold/locale/ja.yml +64 -0
  176. data/lib/active_scaffold/locale/ru.yml +119 -0
  177. data/lib/active_scaffold/marked_model.rb +38 -0
  178. data/lib/active_scaffold/version.rb +9 -0
  179. data/lib/active_scaffold.rb +345 -0
  180. data/lib/active_scaffold_assets.rb +45 -0
  181. data/lib/dhtml_confirm.rb +54 -0
  182. data/lib/environment.rb +14 -0
  183. data/lib/extensions/action_controller_rendering.rb +20 -0
  184. data/lib/extensions/action_view_rendering.rb +113 -0
  185. data/lib/extensions/action_view_resolver.rb +7 -0
  186. data/lib/extensions/active_association_reflection.rb +13 -0
  187. data/lib/extensions/active_record_offset.rb +12 -0
  188. data/lib/extensions/array.rb +7 -0
  189. data/lib/extensions/localize.rb +10 -0
  190. data/lib/extensions/name_option_for_datetime.rb +12 -0
  191. data/lib/extensions/nil_id_in_url_params.rb +7 -0
  192. data/lib/extensions/paginator_extensions.rb +26 -0
  193. data/lib/extensions/reverse_associations.rb +62 -0
  194. data/lib/extensions/routing_mapper.rb +34 -0
  195. data/lib/extensions/to_label.rb +8 -0
  196. data/lib/extensions/unsaved_associated.rb +61 -0
  197. data/lib/extensions/unsaved_record.rb +20 -0
  198. data/lib/extensions/usa_state.rb +46 -0
  199. data/lib/generators/active_scaffold/USAGE +29 -0
  200. data/lib/generators/active_scaffold/active_scaffold_generator.rb +20 -0
  201. data/lib/generators/active_scaffold_controller/USAGE +19 -0
  202. data/lib/generators/active_scaffold_controller/active_scaffold_controller_generator.rb +28 -0
  203. data/lib/generators/active_scaffold_controller/templates/controller.rb +4 -0
  204. data/lib/generators/active_scaffold_setup/USAGE +10 -0
  205. data/lib/generators/active_scaffold_setup/active_scaffold_setup_generator.rb +53 -0
  206. data/lib/paginator.rb +136 -0
  207. data/lib/responds_to_parent.rb +70 -0
  208. data/public/blank.html +33 -0
  209. data/shoulda_macros/macros.rb +136 -0
  210. data/test/bridges/bridge_test.rb +47 -0
  211. data/test/config/base_test.rb +15 -0
  212. data/test/config/create_test.rb +55 -0
  213. data/test/config/list_test.rb +74 -0
  214. data/test/config/show_test.rb +43 -0
  215. data/test/config/update_test.rb +17 -0
  216. data/test/const_mocker.rb +36 -0
  217. data/test/data_structures/action_columns_test.rb +113 -0
  218. data/test/data_structures/action_link_test.rb +78 -0
  219. data/test/data_structures/action_links_test.rb +78 -0
  220. data/test/data_structures/actions_test.rb +25 -0
  221. data/test/data_structures/association_column_test.rb +42 -0
  222. data/test/data_structures/column_test.rb +185 -0
  223. data/test/data_structures/columns_test.rb +69 -0
  224. data/test/data_structures/error_message_test.rb +28 -0
  225. data/test/data_structures/set_test.rb +86 -0
  226. data/test/data_structures/sorting_test.rb +126 -0
  227. data/test/data_structures/standard_column_test.rb +24 -0
  228. data/test/data_structures/virtual_column_test.rb +23 -0
  229. data/test/extensions/active_record_test.rb +45 -0
  230. data/test/extensions/array_test.rb +12 -0
  231. data/test/helpers/form_column_helpers_test.rb +31 -0
  232. data/test/helpers/list_column_helpers_test.rb +31 -0
  233. data/test/helpers/pagination_helpers_test.rb +55 -0
  234. data/test/misc/active_record_permissions_test.rb +154 -0
  235. data/test/misc/attribute_params_test.rb +110 -0
  236. data/test/misc/configurable_test.rb +96 -0
  237. data/test/misc/constraints_test.rb +193 -0
  238. data/test/misc/finder_test.rb +93 -0
  239. data/test/misc/lang_test.rb +12 -0
  240. data/test/mock_app/.gitignore +2 -0
  241. data/test/mock_app/app/controllers/application_controller.rb +10 -0
  242. data/test/mock_app/app/helpers/application_helper.rb +3 -0
  243. data/test/mock_app/config/boot.rb +110 -0
  244. data/test/mock_app/config/database.yml +16 -0
  245. data/test/mock_app/config/environment.rb +43 -0
  246. data/test/mock_app/config/environments/development.rb +17 -0
  247. data/test/mock_app/config/environments/production.rb +28 -0
  248. data/test/mock_app/config/environments/test.rb +28 -0
  249. data/test/mock_app/config/initializers/backtrace_silencers.rb +7 -0
  250. data/test/mock_app/config/initializers/inflections.rb +10 -0
  251. data/test/mock_app/config/initializers/mime_types.rb +5 -0
  252. data/test/mock_app/config/initializers/new_rails_defaults.rb +19 -0
  253. data/test/mock_app/config/initializers/session_store.rb +15 -0
  254. data/test/mock_app/config/locales/en.yml +5 -0
  255. data/test/mock_app/config/routes.rb +43 -0
  256. data/test/mock_app/db/test.sqlite3 +1 -0
  257. data/test/mock_app/public/blank.html +33 -0
  258. data/test/mock_app/public/images/active_scaffold/DO_NOT_EDIT +2 -0
  259. data/test/mock_app/public/images/active_scaffold/default/add.gif +0 -0
  260. data/test/mock_app/public/images/active_scaffold/default/arrow_down.gif +0 -0
  261. data/test/mock_app/public/images/active_scaffold/default/arrow_up.gif +0 -0
  262. data/test/mock_app/public/images/active_scaffold/default/close.gif +0 -0
  263. data/test/mock_app/public/images/active_scaffold/default/cross.png +0 -0
  264. data/test/mock_app/public/images/active_scaffold/default/indicator-small.gif +0 -0
  265. data/test/mock_app/public/images/active_scaffold/default/indicator.gif +0 -0
  266. data/test/mock_app/public/images/active_scaffold/default/magnifier.png +0 -0
  267. data/test/mock_app/public/javascripts/active_scaffold/DO_NOT_EDIT +2 -0
  268. data/test/mock_app/public/javascripts/active_scaffold/default/active_scaffold.js +532 -0
  269. data/test/mock_app/public/javascripts/active_scaffold/default/dhtml_history.js +867 -0
  270. data/test/mock_app/public/javascripts/active_scaffold/default/form_enhancements.js +117 -0
  271. data/test/mock_app/public/javascripts/active_scaffold/default/rico_corner.js +370 -0
  272. data/test/mock_app/public/stylesheets/active_scaffold/DO_NOT_EDIT +2 -0
  273. data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet-ie.css +35 -0
  274. data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet.css +839 -0
  275. data/test/model_stub.rb +55 -0
  276. data/test/run_all.rb +8 -0
  277. data/test/test_helper.rb +39 -0
  278. data/uninstall.rb +13 -0
  279. metadata +492 -0
@@ -0,0 +1,170 @@
1
+ module ActiveScaffold::Actions
2
+ module Core
3
+ def self.included(base)
4
+ base.class_eval do
5
+ after_filter :clear_flashes
6
+ end
7
+ base.helper_method :nested?
8
+ base.helper_method :beginning_of_chain
9
+ end
10
+ def render_field
11
+ if params[:in_place_editing]
12
+ render_field_for_inplace_editing
13
+ else
14
+ render_field_for_update_columns
15
+ end
16
+ end
17
+
18
+ protected
19
+
20
+ def nested?
21
+ false
22
+ end
23
+
24
+ def render_field_for_inplace_editing
25
+ register_constraints_with_action_columns(nested.constrained_fields, active_scaffold_config.update.hide_nested_column ? [] : [:update]) if nested?
26
+ @record = find_if_allowed(params[:id], :update)
27
+ render :inline => "<%= active_scaffold_input_for(active_scaffold_config.columns[params[:update_column].to_sym]) %>"
28
+ end
29
+
30
+ def render_field_for_update_columns
31
+ @record = new_model
32
+ column = active_scaffold_config.columns[params[:column]]
33
+ unless column.nil?
34
+ value = column_value_from_param_value(@record, column, params[:value])
35
+ @record.send "#{column.name}=", value
36
+ after_render_field(@record, column)
37
+ render :partial => "render_field", :collection => Array(params[:update_columns]), :content_type => 'text/javascript'
38
+ end
39
+ end
40
+
41
+ # override this method if you want to do something after render_field
42
+ def after_render_field(record, column); end
43
+
44
+ def authorized_for?(options = {})
45
+ active_scaffold_config.model.authorized_for?(options)
46
+ end
47
+
48
+ def clear_flashes
49
+ if request.xhr?
50
+ flash.keys.each do |flash_key|
51
+ flash[flash_key] = nil
52
+ end
53
+ end
54
+ end
55
+
56
+ def default_formats
57
+ [:html, :js, :json, :xml, :yaml]
58
+ end
59
+ # Returns true if the client accepts one of the MIME types passed to it
60
+ # ex: accepts? :html, :xml
61
+ def accepts?(*types)
62
+ for priority in request.accepts.compact
63
+ if priority == Mime::ALL
64
+ # Because IE always sends */* in the accepts header and we assume
65
+ # that if you really wanted XML or something else you would say so
66
+ # explicitly, we will assume */* to only ask for :html
67
+ return types.include?(:html)
68
+ elsif types.include?(priority.to_sym)
69
+ return true
70
+ end
71
+ end
72
+ false
73
+ end
74
+
75
+ def response_status
76
+ if successful?
77
+ action_name == 'create' ? 201 : 200
78
+ else
79
+ 422
80
+ end
81
+ end
82
+
83
+ # API response object that will be converted to XML/YAML/JSON using to_xxx
84
+ def response_object
85
+ @response_object = successful? ? (@record || @records) : @record.errors
86
+ end
87
+
88
+ # Success is the existence of certain variables and the absence of errors (when applicable).
89
+ # Success can also be defined.
90
+ def successful?
91
+ if @successful.nil?
92
+ @records or (@record and @record.errors.count == 0 and @record.no_errors_in_associated?)
93
+ else
94
+ @successful
95
+ end
96
+ end
97
+
98
+ def successful=(val)
99
+ @successful = (val) ? true : false
100
+ end
101
+
102
+ # Redirect to the main page (override if the ActiveScaffold is used as a component on another controllers page) for Javascript degradation
103
+ def return_to_main
104
+ redirect_to main_path_to_return
105
+ end
106
+
107
+ # Override this method on your controller to define conditions to be used when querying a recordset (e.g. for List). The return of this method should be any format compatible with the :conditions clause of ActiveRecord::Base's find.
108
+ def conditions_for_collection
109
+ end
110
+
111
+ # Override this method on your controller to define joins to be used when querying a recordset (e.g. for List). The return of this method should be any format compatible with the :joins clause of ActiveRecord::Base's find.
112
+ def joins_for_collection
113
+ end
114
+
115
+ # Override this method on your controller to provide custom finder options to the find() call. The return of this method should be a hash.
116
+ def custom_finder_options
117
+ {}
118
+ end
119
+
120
+ #Overide this method on your controller to provide model with named scopes
121
+ def beginning_of_chain
122
+ active_scaffold_config.model
123
+ end
124
+
125
+ # Builds search conditions by search params for column names. This allows urls like "contacts/list?company_id=5".
126
+ def conditions_from_params
127
+ conditions = nil
128
+ params.reject {|key, value| [:controller, :action, :id, :page, :sort, :sort_direction].include?(key.to_sym)}.each do |key, value|
129
+ next unless active_scaffold_config.model.column_names.include?(key)
130
+ if value.is_a?(Array)
131
+ conditions = merge_conditions(conditions, ["#{active_scaffold_config.model.table_name}.#{key.to_s} in (?)", value])
132
+ else
133
+ conditions = merge_conditions(conditions, ["#{active_scaffold_config.model.table_name}.#{key.to_s} = ?", value])
134
+ end
135
+ end
136
+ conditions
137
+ end
138
+
139
+ def new_model
140
+ model = beginning_of_chain
141
+ if model.columns_hash[model.inheritance_column]
142
+ build_options = {model.inheritance_column.to_sym => active_scaffold_config.model_id} if nested? && nested.association && nested.association.collection?
143
+ params = self.params # in new action inheritance_column must be in params
144
+ params = params[:record] || {} unless params[model.inheritance_column] # in create action must be inside record key
145
+ model = params.delete(model.inheritance_column).camelize.constantize if params[model.inheritance_column]
146
+ end
147
+ model.respond_to?(:build) ? model.build(build_options || {}) : model.new
148
+ end
149
+
150
+ private
151
+ def respond_to_action(action)
152
+ respond_to do |type|
153
+ send("#{action}_formats").each do |format|
154
+ type.send(format){ send("#{action}_respond_to_#{format}") }
155
+ end
156
+ end
157
+ end
158
+
159
+ def response_code_for_rescue(exception)
160
+ case exception
161
+ when ActiveScaffold::RecordNotAllowed
162
+ "403 Record Not Allowed"
163
+ when ActiveScaffold::ActionNotAllowed
164
+ "403 Action Not Allowed"
165
+ else
166
+ super
167
+ end
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,145 @@
1
+ module ActiveScaffold::Actions
2
+ module Create
3
+ def self.included(base)
4
+ base.before_filter :create_authorized_filter, :only => [:new, :create]
5
+ base.verify :method => :post,
6
+ :only => :create,
7
+ :redirect_to => { :action => :index }
8
+ end
9
+
10
+ def new
11
+ do_new
12
+ respond_to_action(:new)
13
+ end
14
+
15
+ def create
16
+ do_create
17
+ respond_to_action(:create)
18
+ end
19
+
20
+ protected
21
+ def response_location
22
+ url_for(params_for(:action => "show", :id => @record.id)) if successful?
23
+ end
24
+
25
+ def new_respond_to_html
26
+ if successful?
27
+ render(:action => 'create')
28
+ else
29
+ return_to_main
30
+ end
31
+ end
32
+
33
+ def new_respond_to_js
34
+ render(:partial => 'create_form')
35
+ end
36
+
37
+ def create_respond_to_html
38
+ if params[:iframe]=='true' # was this an iframe post ?
39
+ responds_to_parent do
40
+ render :action => 'on_create.js', :layout => false
41
+ end
42
+ else
43
+ if successful?
44
+ flash[:info] = as_(:created_model, :model => @record.to_label)
45
+ if active_scaffold_config.create.edit_after_create
46
+ redirect_to params_for(:action => "edit", :id => @record.id)
47
+ elsif active_scaffold_config.create.persistent
48
+ redirect_to params_for(:action => "new")
49
+ else
50
+ return_to_main
51
+ end
52
+ else
53
+ if !nested? && active_scaffold_config.actions.include?(:list) && active_scaffold_config.list.always_show_create
54
+ do_list
55
+ render(:action => 'list')
56
+ else
57
+ render(:action => 'create')
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ def create_respond_to_js
64
+ if active_scaffold_config.create.refresh_list && successful?
65
+ do_search if respond_to? :do_search
66
+ do_list
67
+ end
68
+ render :action => 'on_create'
69
+ end
70
+
71
+ def create_respond_to_xml
72
+ render :xml => response_object.to_xml(:only => active_scaffold_config.create.columns.names), :content_type => Mime::XML, :status => response_status, :location => response_location
73
+ end
74
+
75
+ def create_respond_to_json
76
+ render :text => response_object.to_json(:only => active_scaffold_config.create.columns.names), :content_type => Mime::JSON, :status => response_status, :location => response_location
77
+ end
78
+
79
+ def create_respond_to_yaml
80
+ render :text => Hash.from_xml(response_object.to_xml(:only => active_scaffold_config.create.columns.names)).to_yaml, :content_type => Mime::YAML, :status => response_status, :location => response_location
81
+ end
82
+
83
+ # A simple method to find and prepare an example new record for the form
84
+ # May be overridden to customize the behavior (add default values, for instance)
85
+ def do_new
86
+ @record = new_model
87
+ apply_constraints_to_record(@record)
88
+ if nested?
89
+ create_association_with_parent(@record)
90
+ register_constraints_with_action_columns(nested.constrained_fields)
91
+ end
92
+ @record
93
+ end
94
+
95
+ # A somewhat complex method to actually create a new record. The complexity is from support for subforms and associated records.
96
+ # If you want to customize this behavior, consider using the +before_create_save+ and +after_create_save+ callbacks.
97
+ def do_create
98
+ begin
99
+ active_scaffold_config.model.transaction do
100
+ @record = update_record_from_params(new_model, active_scaffold_config.create.columns, params[:record])
101
+ apply_constraints_to_record(@record, :allow_autosave => true)
102
+ if nested?
103
+ create_association_with_parent(@record)
104
+ register_constraints_with_action_columns(nested.constrained_fields)
105
+ end
106
+ before_create_save(@record)
107
+ self.successful = [@record.valid?, @record.associated_valid?].all? {|v| v == true} # this syntax avoids a short-circuit
108
+ if successful?
109
+ @record.save! and @record.save_associated!
110
+ after_create_save(@record)
111
+ end
112
+ end
113
+ rescue ActiveRecord::RecordInvalid
114
+ end
115
+ end
116
+
117
+ # override this method if you want to inject data in the record (or its associated objects) before the save
118
+ def before_create_save(record); end
119
+
120
+ # override this method if you want to do something after the save
121
+ def after_create_save(record); end
122
+
123
+ # The default security delegates to ActiveRecordPermissions.
124
+ # You may override the method to customize.
125
+
126
+ def create_ignore?
127
+ nested? && active_scaffold_config.list.always_show_create
128
+ end
129
+
130
+ def create_authorized?
131
+ (!nested? || !nested.readonly?) && authorized_for?(:crud_type => :create)
132
+ end
133
+ private
134
+ def create_authorized_filter
135
+ link = active_scaffold_config.create.link || active_scaffold_config.create.class.link
136
+ raise ActiveScaffold::ActionNotAllowed unless self.send(link.security_method)
137
+ end
138
+ def new_formats
139
+ (default_formats + active_scaffold_config.formats).uniq
140
+ end
141
+ def create_formats
142
+ (default_formats + active_scaffold_config.formats + active_scaffold_config.create.formats).uniq
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,75 @@
1
+ module ActiveScaffold::Actions
2
+ module Delete
3
+ def self.included(base)
4
+ base.before_filter :delete_authorized_filter, :only => [:destroy]
5
+ end
6
+
7
+ def destroy
8
+ params.delete :destroy_action
9
+ process_action_link_action(:destroy) do |record|
10
+ do_destroy
11
+ end
12
+ end
13
+
14
+ protected
15
+ def destroy_respond_to_html
16
+ if self.successful?
17
+ flash[:info] = as_(:deleted_model, :model => @record.to_label)
18
+ else
19
+ #error_message_for not available in controller...
20
+ #flash[:error] = active_scaffold_error_messages_for(@record, :object_name => "#{@record.class.model_name.human.downcase}#{@record.new_record? ? '' : ": #{@record.to_label}"}", :header_message => '', :message => "#{@record.class.model_name.human.downcase}#{@record.new_record? ? '' : ": #{@record.to_label}"}", :container_tag => nil, :list_type => :br)
21
+ end
22
+ return_to_main
23
+ end
24
+
25
+ def destroy_respond_to_js
26
+ if active_scaffold_config.delete.refresh_list && successful?
27
+ do_search if respond_to? :do_search
28
+ do_list
29
+ end
30
+ render(:action => 'destroy')
31
+ end
32
+
33
+ def destroy_respond_to_xml
34
+ render :xml => successful? ? "" : response_object.to_xml(:only => active_scaffold_config.list.columns.names), :content_type => Mime::XML, :status => response_status
35
+ end
36
+
37
+ def destroy_respond_to_json
38
+ render :text => successful? ? "" : response_object.to_json(:only => active_scaffold_config.list.columns.names), :content_type => Mime::JSON, :status => response_status
39
+ end
40
+
41
+ def destroy_respond_to_yaml
42
+ render :text => successful? ? "" : Hash.from_xml(response_object.to_xml(:only => active_scaffold_config.list.columns.names)).to_yaml, :content_type => Mime::YAML, :status => response_status
43
+ end
44
+
45
+ def destroy_find_record
46
+ @record = find_if_allowed(params[:id], :delete)
47
+ end
48
+
49
+ # A simple method to handle the actual destroying of a record
50
+ # May be overridden to customize the behavior
51
+ def do_destroy
52
+ @record ||= destroy_find_record
53
+ begin
54
+ self.successful = @record.destroy
55
+ rescue
56
+ flash[:warning] = as_(:cant_destroy_record, :record => @record.to_label)
57
+ self.successful = false
58
+ end
59
+ end
60
+
61
+ # The default security delegates to ActiveRecordPermissions.
62
+ # You may override the method to customize.
63
+ def delete_authorized?(record = nil)
64
+ (!nested? || !nested.readonly?) && authorized_for?(:crud_type => :delete)
65
+ end
66
+ private
67
+ def delete_authorized_filter
68
+ link = active_scaffold_config.delete.link || active_scaffold_config.delete.class.link
69
+ raise ActiveScaffold::ActionNotAllowed unless self.send(link.security_method)
70
+ end
71
+ def destroy_formats
72
+ (default_formats + active_scaffold_config.formats + active_scaffold_config.delete.formats).uniq
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,82 @@
1
+ module ActiveScaffold::Actions
2
+ module FieldSearch
3
+ include ActiveScaffold::Actions::CommonSearch
4
+ def self.included(base)
5
+ base.before_filter :search_authorized_filter, :only => :show_search
6
+ base.before_filter :store_search_params_into_session, :only => [:index]
7
+ base.before_filter :do_search, :only => [:index]
8
+ base.helper_method :field_search_params
9
+ end
10
+
11
+ # FieldSearch uses params[:search] and not @record because search conditions do not always pass the Model's validations.
12
+ # This facilitates for example, textual searches against associations via .search_sql
13
+ def show_search
14
+ @record = active_scaffold_config.model.new
15
+ respond_to_action(:field_search)
16
+ end
17
+
18
+ protected
19
+
20
+ def store_search_params_into_session
21
+ set_field_search_default_params(active_scaffold_config.field_search.default_params) unless active_scaffold_config.field_search.default_params.nil?
22
+ super
23
+ active_scaffold_session_storage[:search] = nil if search_params.is_a?(String)
24
+ end
25
+
26
+ def set_field_search_default_params(default_params)
27
+ if (params[:search].nil? && search_params.nil?) || (params[:search].is_a?(String) && params[:search].blank?)
28
+ params[:search] = default_params.is_a?(Proc) ? self.instance_eval(&default_params) : default_params
29
+ end
30
+ end
31
+
32
+ def field_search_params
33
+ search_params || {}
34
+ end
35
+
36
+ def field_search_respond_to_html
37
+ render(:action => "field_search")
38
+ end
39
+
40
+ def field_search_respond_to_js
41
+ render(:partial => "field_search")
42
+ end
43
+
44
+ def do_search
45
+ unless search_params.nil?
46
+ text_search = active_scaffold_config.field_search.text_search
47
+ search_conditions = []
48
+ human_condition_columns = [] if active_scaffold_config.field_search.human_conditions
49
+ columns = active_scaffold_config.field_search.columns
50
+ search_params.each do |key, value|
51
+ next unless columns.include? key
52
+ search_condition = self.class.condition_for_column(active_scaffold_config.columns[key], value, text_search)
53
+ unless search_condition.blank?
54
+ search_conditions << search_condition
55
+ human_condition_columns << active_scaffold_config.columns[key] unless human_condition_columns.nil?
56
+ end
57
+ end
58
+ self.active_scaffold_conditions = merge_conditions(self.active_scaffold_conditions, *search_conditions)
59
+ if search_conditions.blank?
60
+ @filtered = false
61
+ else
62
+ @filtered = human_condition_columns.nil? ? true : human_condition_columns
63
+ end
64
+
65
+ includes_for_search_columns = columns.collect{ |column| column.includes}.flatten.uniq.compact
66
+ self.active_scaffold_includes.concat includes_for_search_columns
67
+
68
+ active_scaffold_config.list.user.page = nil
69
+ end
70
+ end
71
+
72
+ private
73
+
74
+ def search_authorized_filter
75
+ link = active_scaffold_config.field_search.link || active_scaffold_config.field_search.class.link
76
+ raise ActiveScaffold::ActionNotAllowed unless self.send(link.security_method)
77
+ end
78
+ def field_search_formats
79
+ (default_formats + active_scaffold_config.formats + active_scaffold_config.field_search.formats).uniq
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,184 @@
1
+ module ActiveScaffold::Actions
2
+ module List
3
+ def self.included(base)
4
+ base.before_filter :list_authorized_filter, :only => [:index, :row]
5
+ base.helper_method :list_columns
6
+ end
7
+
8
+ def index
9
+ list
10
+ end
11
+
12
+ # get just a single row
13
+ def row
14
+ @record = find_if_allowed(params[:id], :read)
15
+ respond_to_action(:row)
16
+ end
17
+
18
+ def list
19
+ do_list
20
+ do_new if active_scaffold_config.list.always_show_create
21
+ @record ||= active_scaffold_config.model.new if active_scaffold_config.list.always_show_search
22
+ @nested_auto_open = active_scaffold_config.list.nested_auto_open
23
+ respond_to_action(:list)
24
+ end
25
+
26
+ protected
27
+ def list_respond_to_html
28
+ if params.delete(:embedded)
29
+ render :action => 'list', :layout => false
30
+ else
31
+ render :action => 'list'
32
+ end
33
+ end
34
+ def list_respond_to_js
35
+ if params[:adapter]
36
+ render(:partial => 'list_with_header')
37
+ elsif params[:embedded]
38
+ params.delete(:embedded)
39
+ render(:partial => 'list_with_header')
40
+ else
41
+ render :action => 'list.js'
42
+ end
43
+ end
44
+ def list_respond_to_xml
45
+ render :xml => response_object.to_xml(:only => list_columns_names), :content_type => Mime::XML, :status => response_status
46
+ end
47
+ def list_respond_to_json
48
+ render :text => response_object.to_json(:only => list_columns_names), :content_type => Mime::JSON, :status => response_status
49
+ end
50
+ def list_respond_to_yaml
51
+ render :text => Hash.from_xml(response_object.to_xml(:only => list_columns_names)).to_yaml, :content_type => Mime::YAML, :status => response_status
52
+ end
53
+
54
+ def row_respond_to_html
55
+ render(:partial => 'row', :locals => {:record => @record})
56
+ end
57
+
58
+ def row_respond_to_js
59
+ render(:partial => 'row', :locals => {:record => @record})
60
+ end
61
+
62
+ # The actual algorithm to prepare for the list view
63
+ def do_list
64
+ includes_for_list_columns = active_scaffold_config.list.columns.collect{ |c| c.includes }.flatten.uniq.compact
65
+ self.active_scaffold_includes.concat includes_for_list_columns
66
+
67
+ options = { :sorting => active_scaffold_config.list.user.sorting,
68
+ :count_includes => active_scaffold_config.list.user.count_includes }
69
+ paginate = (params[:format].nil?) ? (accepts? :html, :js) : ['html', 'js'].include?(params[:format])
70
+ if paginate
71
+ options.merge!({
72
+ :per_page => active_scaffold_config.list.user.per_page,
73
+ :page => active_scaffold_config.list.user.page,
74
+ :pagination => active_scaffold_config.list.pagination
75
+ })
76
+ end
77
+
78
+ page = find_page(options);
79
+ if page.items.blank? && !page.pager.infinite?
80
+ page = page.pager.last
81
+ active_scaffold_config.list.user.page = page.number
82
+ end
83
+ @page, @records = page, page.items
84
+ end
85
+
86
+ def each_record_in_scope
87
+ do_search if respond_to? :do_search
88
+ finder_options = { :order => "#{active_scaffold_config.model.connection.quote_table_name(active_scaffold_config.model.table_name)}.#{active_scaffold_config.model.primary_key} ASC",
89
+ :conditions => all_conditions,
90
+ :joins => joins_for_finder}
91
+ finder_options.merge! custom_finder_options
92
+ finder_options.merge! :include => (active_scaffold_includes.blank? ? nil : active_scaffold_includes)
93
+ klass = beginning_of_chain
94
+ klass.all(finder_options).each {|record| yield record}
95
+ end
96
+
97
+ # The default security delegates to ActiveRecordPermissions.
98
+ # You may override the method to customize.
99
+ def list_authorized?
100
+ authorized_for?(:crud_type => :read)
101
+ end
102
+
103
+ # call this method in your action_link action to simplify processing of actions
104
+ # eg for member action_link :fire
105
+ # process_action_link_action do |record|
106
+ # record.update_attributes(:fired => true)
107
+ # self.successful = true
108
+ # flash[:info] = 'Player fired'
109
+ # end
110
+ def process_action_link_action(render_action = :action_update)
111
+ if request.get?
112
+ # someone has disabled javascript, we have to show confirmation form first
113
+ @record = find_if_allowed(params[:id], :read) if params[:id] && params[:id] && params[:id].to_i > 0
114
+ respond_to_action(:action_confirmation)
115
+ else
116
+ if params[:id] && params[:id] && params[:id].to_i > 0
117
+ @record = find_if_allowed(params[:id], (request.post? || request.put?) ? :update : :delete)
118
+ unless @record.nil?
119
+ yield @record
120
+ else
121
+ self.successful = false
122
+ flash[:error] = as_(:no_authorization_for_action, :action => action_name)
123
+ end
124
+ else
125
+ yield
126
+ end
127
+ respond_to_action(render_action)
128
+ end
129
+ end
130
+
131
+ def action_confirmation_respond_to_html(confirm_action = action_name.to_sym)
132
+ link = active_scaffold_config.action_links[confirm_action]
133
+ render :action => 'action_confirmation', :locals => {:record => @record, :link => link}
134
+ end
135
+
136
+ def action_update_respond_to_html
137
+ do_search if respond_to? :do_search
138
+ do_list
139
+ redirect_to :action => 'index'
140
+ end
141
+
142
+ def action_update_respond_to_js
143
+ render(:action => 'on_action_update')
144
+ end
145
+
146
+ def action_update_respond_to_xml
147
+ render :xml => successful? ? "" : response_object.to_xml(:only => list_columns_names), :content_type => Mime::XML, :status => response_status
148
+ end
149
+
150
+ def action_update_respond_to_json
151
+ render :text => successful? ? "" : response_object.to_json(:only => list_columns_names), :content_type => Mime::JSON, :status => response_status
152
+ end
153
+
154
+ def action_update_respond_to_yaml
155
+ render :text => successful? ? "" : Hash.from_xml(response_object.to_xml(:only => list_columns_names)).to_yaml, :content_type => Mime::YAML, :status => response_status
156
+ end
157
+
158
+ private
159
+ def list_authorized_filter
160
+ raise ActiveScaffold::ActionNotAllowed unless list_authorized?
161
+ end
162
+
163
+ def list_formats
164
+ (default_formats + active_scaffold_config.formats + active_scaffold_config.list.formats).uniq
165
+ end
166
+ alias_method :row_formats, :list_formats
167
+
168
+ def action_update_formats
169
+ (default_formats + active_scaffold_config.formats).uniq
170
+ end
171
+
172
+ def action_confirmation_formats
173
+ (default_formats + active_scaffold_config.formats).uniq
174
+ end
175
+
176
+ def list_columns
177
+ active_scaffold_config.list.columns.collect_visible
178
+ end
179
+
180
+ def list_columns_names
181
+ list_columns.collect(&:name)
182
+ end
183
+ end
184
+ end