active_scaffold 3.0.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 (272) hide show
  1. data/.autotest +27 -0
  2. data/CHANGELOG +152 -0
  3. data/Gemfile +4 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README +51 -0
  6. data/Rakefile +24 -0
  7. data/active_scaffold.gemspec +24 -0
  8. data/environment.rb +22 -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/cross.png +0 -0
  14. data/frontends/default/images/indicator-small.gif +0 -0
  15. data/frontends/default/images/indicator.gif +0 -0
  16. data/frontends/default/images/magnifier.png +0 -0
  17. data/frontends/default/javascripts/jquery/active_scaffold.js +957 -0
  18. data/frontends/default/javascripts/jquery/jquery.editinplace.js +726 -0
  19. data/frontends/default/javascripts/prototype/active_scaffold.js +954 -0
  20. data/frontends/default/javascripts/prototype/dhtml_history.js +867 -0
  21. data/frontends/default/javascripts/prototype/form_enhancements.js +117 -0
  22. data/frontends/default/javascripts/prototype/rico_corner.js +370 -0
  23. data/frontends/default/stylesheets/stylesheet-ie.css +35 -0
  24. data/frontends/default/stylesheets/stylesheet.css +858 -0
  25. data/frontends/default/views/_add_existing_form.html.erb +30 -0
  26. data/frontends/default/views/_base_form.html.erb +41 -0
  27. data/frontends/default/views/_create_form.html.erb +6 -0
  28. data/frontends/default/views/_create_form_on_list.html.erb +5 -0
  29. data/frontends/default/views/_field_search.html.erb +32 -0
  30. data/frontends/default/views/_form.html.erb +24 -0
  31. data/frontends/default/views/_form_association.html.erb +14 -0
  32. data/frontends/default/views/_form_association_footer.html.erb +40 -0
  33. data/frontends/default/views/_form_attribute.html.erb +15 -0
  34. data/frontends/default/views/_form_hidden_attribute.html.erb +2 -0
  35. data/frontends/default/views/_form_messages.html.erb +5 -0
  36. data/frontends/default/views/_horizontal_subform.html.erb +19 -0
  37. data/frontends/default/views/_horizontal_subform_header.html.erb +10 -0
  38. data/frontends/default/views/_horizontal_subform_record.html.erb +37 -0
  39. data/frontends/default/views/_human_conditions.html.erb +1 -0
  40. data/frontends/default/views/_list.html.erb +18 -0
  41. data/frontends/default/views/_list_actions.html.erb +16 -0
  42. data/frontends/default/views/_list_calculations.html.erb +16 -0
  43. data/frontends/default/views/_list_column_headings.html.erb +12 -0
  44. data/frontends/default/views/_list_header.html.erb +12 -0
  45. data/frontends/default/views/_list_inline_adapter.html.erb +10 -0
  46. data/frontends/default/views/_list_messages.html.erb +32 -0
  47. data/frontends/default/views/_list_pagination.html.erb +11 -0
  48. data/frontends/default/views/_list_pagination_links.html.erb +9 -0
  49. data/frontends/default/views/_list_record.html.erb +14 -0
  50. data/frontends/default/views/_list_record_columns.html.erb +8 -0
  51. data/frontends/default/views/_list_with_header.html.erb +32 -0
  52. data/frontends/default/views/_messages.html.erb +10 -0
  53. data/frontends/default/views/_render_field.js.rjs +13 -0
  54. data/frontends/default/views/_row.html.erb +12 -0
  55. data/frontends/default/views/_search.html.erb +34 -0
  56. data/frontends/default/views/_search_attribute.html.erb +10 -0
  57. data/frontends/default/views/_show.html.erb +8 -0
  58. data/frontends/default/views/_show_columns.html.erb +12 -0
  59. data/frontends/default/views/_update_actions.html.erb +9 -0
  60. data/frontends/default/views/_update_form.html.erb +5 -0
  61. data/frontends/default/views/_vertical_subform.html.erb +12 -0
  62. data/frontends/default/views/_vertical_subform_record.html.erb +38 -0
  63. data/frontends/default/views/add_existing.js.rjs +17 -0
  64. data/frontends/default/views/add_existing_form.html.erb +5 -0
  65. data/frontends/default/views/create.html.erb +5 -0
  66. data/frontends/default/views/delete.html.erb +13 -0
  67. data/frontends/default/views/destroy.js.rjs +5 -0
  68. data/frontends/default/views/edit_associated.js.rjs +11 -0
  69. data/frontends/default/views/field_search.html.erb +5 -0
  70. data/frontends/default/views/form_messages.js.rjs +1 -0
  71. data/frontends/default/views/list.html.erb +1 -0
  72. data/frontends/default/views/list.js.rjs +1 -0
  73. data/frontends/default/views/on_action_update.js.rjs +8 -0
  74. data/frontends/default/views/on_create.js.rjs +24 -0
  75. data/frontends/default/views/on_update.js.rjs +15 -0
  76. data/frontends/default/views/search.html.erb +5 -0
  77. data/frontends/default/views/show.html.erb +5 -0
  78. data/frontends/default/views/update.html.erb +8 -0
  79. data/frontends/default/views/update_column.js.rjs +13 -0
  80. data/frontends/default/views/update_row.js.rjs +1 -0
  81. data/init.rb +1 -0
  82. data/install_assets.rb +44 -0
  83. data/lib/active_record_permissions.rb +134 -0
  84. data/lib/active_scaffold.rb +279 -0
  85. data/lib/active_scaffold/actions/common_search.rb +22 -0
  86. data/lib/active_scaffold/actions/core.rb +150 -0
  87. data/lib/active_scaffold/actions/create.rb +152 -0
  88. data/lib/active_scaffold/actions/delete.rb +72 -0
  89. data/lib/active_scaffold/actions/field_search.rb +82 -0
  90. data/lib/active_scaffold/actions/list.rb +128 -0
  91. data/lib/active_scaffold/actions/mark.rb +50 -0
  92. data/lib/active_scaffold/actions/nested.rb +241 -0
  93. data/lib/active_scaffold/actions/search.rb +47 -0
  94. data/lib/active_scaffold/actions/show.rb +54 -0
  95. data/lib/active_scaffold/actions/subform.rb +17 -0
  96. data/lib/active_scaffold/actions/update.rb +134 -0
  97. data/lib/active_scaffold/attribute_params.rb +207 -0
  98. data/lib/active_scaffold/bridges/ancestry/bridge.rb +5 -0
  99. data/lib/active_scaffold/bridges/ancestry/lib/ancestry_bridge.rb +38 -0
  100. data/lib/active_scaffold/bridges/bridge.rb +52 -0
  101. data/lib/active_scaffold/bridges/calendar_date_select/bridge.rb +16 -0
  102. data/lib/active_scaffold/bridges/calendar_date_select/lib/as_cds_bridge.rb +79 -0
  103. data/lib/active_scaffold/bridges/carrierwave/bridge.rb +7 -0
  104. data/lib/active_scaffold/bridges/carrierwave/lib/carrierwave_bridge.rb +38 -0
  105. data/lib/active_scaffold/bridges/carrierwave/lib/carrierwave_bridge_helpers.rb +26 -0
  106. data/lib/active_scaffold/bridges/carrierwave/lib/form_ui.rb +35 -0
  107. data/lib/active_scaffold/bridges/carrierwave/lib/list_ui.rb +17 -0
  108. data/lib/active_scaffold/bridges/date_picker/bridge.rb +22 -0
  109. data/lib/active_scaffold/bridges/date_picker/lib/datepicker_bridge.rb +225 -0
  110. data/lib/active_scaffold/bridges/date_picker/public/javascripts/date_picker_bridge.js +22 -0
  111. data/lib/active_scaffold/bridges/file_column/bridge.rb +11 -0
  112. data/lib/active_scaffold/bridges/file_column/lib/as_file_column_bridge.rb +46 -0
  113. data/lib/active_scaffold/bridges/file_column/lib/file_column_helpers.rb +59 -0
  114. data/lib/active_scaffold/bridges/file_column/lib/form_ui.rb +37 -0
  115. data/lib/active_scaffold/bridges/file_column/lib/list_ui.rb +26 -0
  116. data/lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb +43 -0
  117. data/lib/active_scaffold/bridges/file_column/test/mock_model.rb +9 -0
  118. data/lib/active_scaffold/bridges/file_column/test/test_helper.rb +15 -0
  119. data/lib/active_scaffold/bridges/paperclip/bridge.rb +12 -0
  120. data/lib/active_scaffold/bridges/paperclip/lib/form_ui.rb +27 -0
  121. data/lib/active_scaffold/bridges/paperclip/lib/list_ui.rb +16 -0
  122. data/lib/active_scaffold/bridges/paperclip/lib/paperclip_bridge.rb +38 -0
  123. data/lib/active_scaffold/bridges/paperclip/lib/paperclip_bridge_helpers.rb +26 -0
  124. data/lib/active_scaffold/bridges/semantic_attributes/bridge.rb +5 -0
  125. data/lib/active_scaffold/bridges/semantic_attributes/lib/semantic_attributes_bridge.rb +20 -0
  126. data/lib/active_scaffold/bridges/shared/date_bridge.rb +187 -0
  127. data/lib/active_scaffold/bridges/tiny_mce/bridge.rb +5 -0
  128. data/lib/active_scaffold/bridges/tiny_mce/lib/tiny_mce_bridge.rb +45 -0
  129. data/lib/active_scaffold/bridges/validation_reflection/bridge.rb +8 -0
  130. data/lib/active_scaffold/bridges/validation_reflection/lib/validation_reflection_bridge.rb +21 -0
  131. data/lib/active_scaffold/config/base.rb +54 -0
  132. data/lib/active_scaffold/config/core.rb +229 -0
  133. data/lib/active_scaffold/config/create.rb +43 -0
  134. data/lib/active_scaffold/config/delete.rb +25 -0
  135. data/lib/active_scaffold/config/field_search.rb +74 -0
  136. data/lib/active_scaffold/config/form.rb +46 -0
  137. data/lib/active_scaffold/config/list.rb +174 -0
  138. data/lib/active_scaffold/config/mark.rb +22 -0
  139. data/lib/active_scaffold/config/nested.rb +43 -0
  140. data/lib/active_scaffold/config/search.rb +68 -0
  141. data/lib/active_scaffold/config/show.rb +34 -0
  142. data/lib/active_scaffold/config/subform.rb +35 -0
  143. data/lib/active_scaffold/config/update.rb +38 -0
  144. data/lib/active_scaffold/configurable.rb +29 -0
  145. data/lib/active_scaffold/constraints.rb +179 -0
  146. data/lib/active_scaffold/data_structures/action_columns.rb +133 -0
  147. data/lib/active_scaffold/data_structures/action_link.rb +162 -0
  148. data/lib/active_scaffold/data_structures/action_links.rb +59 -0
  149. data/lib/active_scaffold/data_structures/actions.rb +45 -0
  150. data/lib/active_scaffold/data_structures/column.rb +348 -0
  151. data/lib/active_scaffold/data_structures/columns.rb +75 -0
  152. data/lib/active_scaffold/data_structures/error_message.rb +24 -0
  153. data/lib/active_scaffold/data_structures/nested_info.rb +108 -0
  154. data/lib/active_scaffold/data_structures/set.rb +62 -0
  155. data/lib/active_scaffold/data_structures/sorting.rb +168 -0
  156. data/lib/active_scaffold/finder.rb +333 -0
  157. data/lib/active_scaffold/helpers/association_helpers.rb +40 -0
  158. data/lib/active_scaffold/helpers/controller_helpers.rb +40 -0
  159. data/lib/active_scaffold/helpers/country_helpers.rb +352 -0
  160. data/lib/active_scaffold/helpers/form_column_helpers.rb +343 -0
  161. data/lib/active_scaffold/helpers/human_condition_helpers.rb +59 -0
  162. data/lib/active_scaffold/helpers/id_helpers.rb +131 -0
  163. data/lib/active_scaffold/helpers/list_column_helpers.rb +363 -0
  164. data/lib/active_scaffold/helpers/pagination_helpers.rb +55 -0
  165. data/lib/active_scaffold/helpers/search_column_helpers.rb +238 -0
  166. data/lib/active_scaffold/helpers/show_column_helpers.rb +46 -0
  167. data/lib/active_scaffold/helpers/view_helpers.rb +315 -0
  168. data/lib/active_scaffold/locale/de.rb +113 -0
  169. data/lib/active_scaffold/locale/en.rb +118 -0
  170. data/lib/active_scaffold/locale/es.yml +112 -0
  171. data/lib/active_scaffold/locale/fr.rb +113 -0
  172. data/lib/active_scaffold/locale/hu.yml +63 -0
  173. data/lib/active_scaffold/locale/ja.yml +64 -0
  174. data/lib/active_scaffold/locale/ru.yml +62 -0
  175. data/lib/active_scaffold/marked_model.rb +38 -0
  176. data/lib/dhtml_confirm.rb +54 -0
  177. data/lib/extensions/action_controller_rendering.rb +20 -0
  178. data/lib/extensions/action_view_rendering.rb +113 -0
  179. data/lib/extensions/action_view_resolver.rb +7 -0
  180. data/lib/extensions/active_record_offset.rb +12 -0
  181. data/lib/extensions/array.rb +7 -0
  182. data/lib/extensions/localize.rb +10 -0
  183. data/lib/extensions/name_option_for_datetime.rb +12 -0
  184. data/lib/extensions/nil_id_in_url_params.rb +7 -0
  185. data/lib/extensions/paginator_extensions.rb +26 -0
  186. data/lib/extensions/reverse_associations.rb +62 -0
  187. data/lib/extensions/routing_mapper.rb +34 -0
  188. data/lib/extensions/to_label.rb +8 -0
  189. data/lib/extensions/unsaved_associated.rb +61 -0
  190. data/lib/extensions/unsaved_record.rb +20 -0
  191. data/lib/extensions/usa_state.rb +46 -0
  192. data/lib/generators/active_scaffold/USAGE +29 -0
  193. data/lib/generators/active_scaffold/active_scaffold_generator.rb +20 -0
  194. data/lib/generators/active_scaffold_controller/USAGE +19 -0
  195. data/lib/generators/active_scaffold_controller/active_scaffold_controller_generator.rb +28 -0
  196. data/lib/generators/active_scaffold_controller/templates/controller.rb +4 -0
  197. data/lib/generators/active_scaffold_setup/USAGE +10 -0
  198. data/lib/generators/active_scaffold_setup/active_scaffold_setup_generator.rb +53 -0
  199. data/lib/paginator.rb +136 -0
  200. data/lib/responds_to_parent.rb +70 -0
  201. data/public/blank.html +33 -0
  202. data/shoulda_macros/macros.rb +136 -0
  203. data/test/bridges/bridge_test.rb +47 -0
  204. data/test/config/base_test.rb +15 -0
  205. data/test/config/create_test.rb +55 -0
  206. data/test/config/list_test.rb +74 -0
  207. data/test/config/show_test.rb +43 -0
  208. data/test/config/update_test.rb +17 -0
  209. data/test/const_mocker.rb +36 -0
  210. data/test/data_structures/action_columns_test.rb +113 -0
  211. data/test/data_structures/action_link_test.rb +78 -0
  212. data/test/data_structures/action_links_test.rb +78 -0
  213. data/test/data_structures/actions_test.rb +25 -0
  214. data/test/data_structures/association_column_test.rb +42 -0
  215. data/test/data_structures/column_test.rb +185 -0
  216. data/test/data_structures/columns_test.rb +69 -0
  217. data/test/data_structures/error_message_test.rb +28 -0
  218. data/test/data_structures/set_test.rb +86 -0
  219. data/test/data_structures/sorting_test.rb +126 -0
  220. data/test/data_structures/standard_column_test.rb +24 -0
  221. data/test/data_structures/virtual_column_test.rb +23 -0
  222. data/test/extensions/active_record_test.rb +45 -0
  223. data/test/extensions/array_test.rb +12 -0
  224. data/test/helpers/form_column_helpers_test.rb +31 -0
  225. data/test/helpers/list_column_helpers_test.rb +31 -0
  226. data/test/helpers/pagination_helpers_test.rb +55 -0
  227. data/test/misc/active_record_permissions_test.rb +154 -0
  228. data/test/misc/attribute_params_test.rb +110 -0
  229. data/test/misc/configurable_test.rb +96 -0
  230. data/test/misc/constraints_test.rb +193 -0
  231. data/test/misc/finder_test.rb +93 -0
  232. data/test/misc/lang_test.rb +12 -0
  233. data/test/mock_app/.gitignore +2 -0
  234. data/test/mock_app/app/controllers/application_controller.rb +10 -0
  235. data/test/mock_app/app/helpers/application_helper.rb +3 -0
  236. data/test/mock_app/config/boot.rb +110 -0
  237. data/test/mock_app/config/database.yml +16 -0
  238. data/test/mock_app/config/environment.rb +43 -0
  239. data/test/mock_app/config/environments/development.rb +17 -0
  240. data/test/mock_app/config/environments/production.rb +28 -0
  241. data/test/mock_app/config/environments/test.rb +28 -0
  242. data/test/mock_app/config/initializers/backtrace_silencers.rb +7 -0
  243. data/test/mock_app/config/initializers/inflections.rb +10 -0
  244. data/test/mock_app/config/initializers/mime_types.rb +5 -0
  245. data/test/mock_app/config/initializers/new_rails_defaults.rb +19 -0
  246. data/test/mock_app/config/initializers/session_store.rb +15 -0
  247. data/test/mock_app/config/locales/en.yml +5 -0
  248. data/test/mock_app/config/routes.rb +43 -0
  249. data/test/mock_app/db/test.sqlite3 +1 -0
  250. data/test/mock_app/public/blank.html +33 -0
  251. data/test/mock_app/public/images/active_scaffold/DO_NOT_EDIT +2 -0
  252. data/test/mock_app/public/images/active_scaffold/default/add.gif +0 -0
  253. data/test/mock_app/public/images/active_scaffold/default/arrow_down.gif +0 -0
  254. data/test/mock_app/public/images/active_scaffold/default/arrow_up.gif +0 -0
  255. data/test/mock_app/public/images/active_scaffold/default/close.gif +0 -0
  256. data/test/mock_app/public/images/active_scaffold/default/cross.png +0 -0
  257. data/test/mock_app/public/images/active_scaffold/default/indicator-small.gif +0 -0
  258. data/test/mock_app/public/images/active_scaffold/default/indicator.gif +0 -0
  259. data/test/mock_app/public/images/active_scaffold/default/magnifier.png +0 -0
  260. data/test/mock_app/public/javascripts/active_scaffold/DO_NOT_EDIT +2 -0
  261. data/test/mock_app/public/javascripts/active_scaffold/default/active_scaffold.js +532 -0
  262. data/test/mock_app/public/javascripts/active_scaffold/default/dhtml_history.js +867 -0
  263. data/test/mock_app/public/javascripts/active_scaffold/default/form_enhancements.js +117 -0
  264. data/test/mock_app/public/javascripts/active_scaffold/default/rico_corner.js +370 -0
  265. data/test/mock_app/public/stylesheets/active_scaffold/DO_NOT_EDIT +2 -0
  266. data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet-ie.css +35 -0
  267. data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet.css +839 -0
  268. data/test/model_stub.rb +55 -0
  269. data/test/run_all.rb +8 -0
  270. data/test/test_helper.rb +39 -0
  271. data/uninstall.rb +13 -0
  272. metadata +478 -0
@@ -0,0 +1,241 @@
1
+ module ActiveScaffold::Actions
2
+ # The Nested module basically handles automatically linking controllers together. It does this by creating column links with the right parameters, and by providing any supporting systems (like a /:controller/nested action for returning associated scaffolds).
3
+ module Nested
4
+
5
+ def self.included(base)
6
+ super
7
+ base.module_eval do
8
+ before_filter :register_constraints_with_action_columns
9
+ before_filter :set_nested
10
+ before_filter :configure_nested
11
+ include ActiveScaffold::Actions::Nested::ChildMethods if active_scaffold_config.model.reflect_on_all_associations.any? {|a| a.macro == :has_and_belongs_to_many}
12
+ end
13
+ base.before_filter :include_habtm_actions
14
+ base.helper_method :nested
15
+ end
16
+
17
+ protected
18
+ def nested
19
+ @nested ||= ActiveScaffold::DataStructures::NestedInfo.get(active_scaffold_config.model, active_scaffold_session_storage)
20
+ if !@nested.nil? && @nested.new_instance?
21
+ register_constraints_with_action_columns(@nested.constrained_fields)
22
+ active_scaffold_constraints[:id] = nested.parent_id if @nested.belongs_to?
23
+ end
24
+ @nested
25
+ end
26
+
27
+ def nested?
28
+ !nested.nil?
29
+ end
30
+
31
+ def set_nested
32
+ if params[:parent_model] && ((params[:association] && params[:assoc_id]) || params[:named_scope])
33
+ @nested = nil
34
+ active_scaffold_session_storage[:nested] = {:parent_model => params[:parent_model].camelize.constantize,
35
+ :name => (params[:association] || params[:named_scope]).to_sym,
36
+ :parent_id => params[:assoc_id]}
37
+ params.delete_if {|key, value| [:parent_model, :association, :named_scope, :assoc_id].include? key.to_sym}
38
+ end
39
+ end
40
+
41
+ def configure_nested
42
+ if nested?
43
+ active_scaffold_session_storage[:list][:label] = if nested.belongs_to?
44
+ as_(:nested_of_model, :nested_model => active_scaffold_config.model.model_name.human, :parent_model => nested_parent_record.to_label)
45
+ else
46
+ as_(:nested_for_model, :nested_model => active_scaffold_config.list.label, :parent_model => nested_parent_record.to_label)
47
+ end
48
+ if nested.sorted?
49
+ active_scaffold_config.list.user.nested_default_sorting = {:table_name => active_scaffold_config.model.model_name, :default_sorting => nested.default_sorting}
50
+ end
51
+ end
52
+ end
53
+
54
+ def nested_authorized?(record = nil)
55
+ true
56
+ end
57
+
58
+ def include_habtm_actions
59
+ if nested?
60
+ if nested.habtm?
61
+ # Production mode is ok with adding a link everytime the scaffold is nested - we ar not ok with that.
62
+ active_scaffold_config.action_links.add('new_existing', :label => :add_existing, :type => :collection, :security_method => :add_existing_authorized?) unless active_scaffold_config.action_links['new_existing']
63
+ if active_scaffold_config.nested.shallow_delete
64
+ active_scaffold_config.action_links.add('destroy_existing', :label => :remove, :type => :member, :confirm => :are_you_sure_to_delete, :method => :delete, :position => false, :security_method => :delete_existing_authorized?) unless active_scaffold_config.action_links['destroy_existing']
65
+ active_scaffold_config.action_links.delete("delete") if active_scaffold_config.action_links['delete']
66
+ end
67
+ else
68
+ # Production mode is caching this link into a non nested scaffold
69
+ active_scaffold_config.action_links.delete('new_existing') if active_scaffold_config.action_links['new_existing']
70
+
71
+ if active_scaffold_config.nested.shallow_delete
72
+ active_scaffold_config.action_links.delete("destroy_existing") if active_scaffold_config.action_links['destroy_existing']
73
+ active_scaffold_config.action_links.add(ActiveScaffold::Config::Delete.link) unless active_scaffold_config.action_links['delete']
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ def beginning_of_chain
80
+ if nested? && nested.association && nested.association.collection?
81
+ nested.parent_scope.send(nested.association.name)
82
+ elsif nested? && nested.scope
83
+ nested.parent_scope.send(nested.scope)
84
+ else
85
+ active_scaffold_config.model
86
+ end
87
+ end
88
+
89
+ def nested_parent_record(crud = :read)
90
+ find_if_allowed(nested.parent_id, crud, nested.parent_model)
91
+ end
92
+
93
+ def create_association_with_parent(record)
94
+ if nested? && nested.belongs_to? && nested.child_association
95
+ parent = nested_parent_record(:read)
96
+ case nested.child_association.macro
97
+ when :has_one
98
+ record.send("#{nested.child_association.name}=", parent)
99
+ when :has_many
100
+ record.send("#{nested.child_association.name}").send(:<<, parent)
101
+ end unless parent.nil?
102
+ end
103
+ end
104
+
105
+ private
106
+ def nested_formats
107
+ (default_formats + active_scaffold_config.formats + active_scaffold_config.nested.formats).uniq
108
+ end
109
+ end
110
+ end
111
+
112
+ module ActiveScaffold::Actions::Nested
113
+ module ChildMethods
114
+
115
+ def self.included(base)
116
+ super
117
+ base.verify :method => :post,
118
+ :only => :add_existing,
119
+ :redirect_to => { :action => :index }
120
+ end
121
+
122
+ def new_existing
123
+ do_new
124
+ respond_to_action(:new_existing)
125
+ end
126
+
127
+ def add_existing
128
+ do_add_existing
129
+ respond_to_action(:add_existing)
130
+ end
131
+
132
+ def destroy_existing
133
+ return redirect_to(params.merge(:action => :delete)) if request.get?
134
+ do_destroy_existing
135
+ respond_to_action(:destroy_existing)
136
+ end
137
+
138
+ protected
139
+ def new_existing_respond_to_html
140
+ if successful?
141
+ render(:action => 'add_existing_form')
142
+ else
143
+ return_to_main
144
+ end
145
+ end
146
+ def new_existing_respond_to_js
147
+ render(:partial => 'add_existing_form')
148
+ end
149
+ def add_existing_respond_to_html
150
+ if successful?
151
+ flash[:info] = as_(:created_model, :model => @record.to_label)
152
+ return_to_main
153
+ else
154
+ render(:action => 'add_existing_form')
155
+ end
156
+ end
157
+ def add_existing_respond_to_js
158
+ if successful?
159
+ render :action => 'add_existing'
160
+ else
161
+ render :action => 'form_messages'
162
+ end
163
+ end
164
+ def add_existing_respond_to_xml
165
+ render :xml => response_object.to_xml(:only => active_scaffold_config.list.columns.names), :content_type => Mime::XML, :status => response_status
166
+ end
167
+ def add_existing_respond_to_json
168
+ render :text => response_object.to_json(:only => active_scaffold_config.list.columns.names), :content_type => Mime::JSON, :status => response_status
169
+ end
170
+ def add_existing_respond_to_yaml
171
+ render :text => Hash.from_xml(response_object.to_xml(:only => active_scaffold_config.list.columns.names)).to_yaml, :content_type => Mime::YAML, :status => response_status
172
+ end
173
+ def destroy_existing_respond_to_html
174
+ flash[:info] = as_(:deleted_model, :model => @record.to_label)
175
+ return_to_main
176
+ end
177
+
178
+ def destroy_existing_respond_to_js
179
+ render(:action => 'destroy')
180
+ end
181
+
182
+ def destroy_existing_respond_to_xml
183
+ render :xml => successful? ? "" : response_object.to_xml(:only => active_scaffold_config.list.columns.names), :content_type => Mime::XML, :status => response_status
184
+ end
185
+
186
+ def destroy_existing_respond_to_json
187
+ render :text => successful? ? "" : response_object.to_json(:only => active_scaffold_config.list.columns.names), :content_type => Mime::JSON, :status => response_status
188
+ end
189
+
190
+ def destroy_existing_respond_to_yaml
191
+ 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
192
+ end
193
+
194
+ def add_existing_authorized?(record = nil)
195
+ true
196
+ end
197
+ def delete_existing_authorized?(record = nil)
198
+ true
199
+ end
200
+
201
+ def after_create_save(record)
202
+ if params[:association_macro] == :has_and_belongs_to_many
203
+ params[:associated_id] = record
204
+ do_add_existing
205
+ end
206
+ end
207
+
208
+ # The actual "add_existing" algorithm
209
+ def do_add_existing
210
+ parent_record = nested_parent_record(:update)
211
+ @record = active_scaffold_config.model.find(params[:associated_id])
212
+ if parent_record && @record
213
+ parent_record.send(nested.association.name) << @record
214
+ parent_record.save
215
+ else
216
+ false
217
+ end
218
+ end
219
+
220
+ def do_destroy_existing
221
+ if active_scaffold_config.nested.shallow_delete
222
+ @record = nested_parent_record(:update)
223
+ collection = @record.send(nested.association.name)
224
+ assoc_record = collection.find(params[:id])
225
+ collection.delete(assoc_record)
226
+ else
227
+ do_destroy
228
+ end
229
+ end
230
+ private
231
+ def new_existing_formats
232
+ (default_formats + active_scaffold_config.formats).uniq
233
+ end
234
+ def add_existing_formats
235
+ (default_formats + active_scaffold_config.formats).uniq
236
+ end
237
+ def destroy_existing_formats
238
+ (default_formats + active_scaffold_config.formats).uniq
239
+ end
240
+ end
241
+ end
@@ -0,0 +1,47 @@
1
+ module ActiveScaffold::Actions
2
+ module Search
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 :search_params
9
+ end
10
+
11
+ def show_search
12
+ respond_to_action(:search)
13
+ end
14
+
15
+ protected
16
+ def search_respond_to_html
17
+ render(:action => "search")
18
+ end
19
+ def search_respond_to_js
20
+ render(:partial => "search")
21
+ end
22
+ def do_search
23
+ query = search_params.to_s.strip rescue ''
24
+ unless query.empty?
25
+ columns = active_scaffold_config.search.columns
26
+ text_search = active_scaffold_config.search.text_search
27
+ search_conditions = self.class.create_conditions_for_columns(query.split(' '), columns, text_search)
28
+ self.active_scaffold_conditions = merge_conditions(self.active_scaffold_conditions, search_conditions)
29
+ @filtered = !search_conditions.blank?
30
+
31
+ includes_for_search_columns = columns.collect{ |column| column.includes}.flatten.uniq.compact
32
+ self.active_scaffold_includes.concat includes_for_search_columns
33
+
34
+ active_scaffold_config.list.user.page = nil
35
+ end
36
+ end
37
+
38
+ private
39
+ def search_authorized_filter
40
+ link = active_scaffold_config.search.link || active_scaffold_config.search.class.link
41
+ raise ActiveScaffold::ActionNotAllowed unless self.send(link.security_method)
42
+ end
43
+ def search_formats
44
+ (default_formats + active_scaffold_config.formats + active_scaffold_config.search.formats).uniq
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,54 @@
1
+ module ActiveScaffold::Actions
2
+ module Show
3
+ def self.included(base)
4
+ base.before_filter :show_authorized_filter, :only => :show
5
+ end
6
+
7
+ def show
8
+ do_show
9
+ successful?
10
+ respond_to_action(:show)
11
+ end
12
+
13
+ protected
14
+
15
+ def show_respond_to_json
16
+ render :text => response_object.to_json(:only => active_scaffold_config.show.columns.names), :content_type => Mime::JSON, :status => response_status
17
+ end
18
+
19
+ def show_respond_to_yaml
20
+ render :text => Hash.from_xml(response_object.to_xml(:only => active_scaffold_config.show.columns.names)).to_yaml, :content_type => Mime::YAML, :status => response_status
21
+ end
22
+
23
+ def show_respond_to_xml
24
+ render :xml => response_object.to_xml(:only => active_scaffold_config.show.columns.names), :content_type => Mime::XML, :status => response_status
25
+ end
26
+
27
+ def show_respond_to_js
28
+ render :partial => 'show'
29
+ end
30
+
31
+ def show_respond_to_html
32
+ render :action => 'show'
33
+ end
34
+ # A simple method to retrieve and prepare a record for showing.
35
+ # May be overridden to customize show routine
36
+ def do_show
37
+ @record = find_if_allowed(params[:id], :read)
38
+ end
39
+
40
+ # The default security delegates to ActiveRecordPermissions.
41
+ # You may override the method to customize.
42
+ def show_authorized?(record = nil)
43
+ authorized_for?(:crud_type => :read)
44
+ end
45
+ private
46
+ def show_authorized_filter
47
+ link = active_scaffold_config.show.link || active_scaffold_config.show.class.link
48
+ raise ActiveScaffold::ActionNotAllowed unless self.send(link.security_method)
49
+ end
50
+ def show_formats
51
+ (default_formats + active_scaffold_config.formats + active_scaffold_config.show.formats).uniq
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,17 @@
1
+ module ActiveScaffold::Actions
2
+ module Subform
3
+ def edit_associated
4
+ @parent_record = params[:id].nil? ? active_scaffold_config.model.new : find_if_allowed(params[:id], :update)
5
+ @column = active_scaffold_config.columns[params[:association]]
6
+
7
+ # NOTE: we don't check whether the user is allowed to update this record, because if not, we'll still let them associate the record. we'll just refuse to do more than associate, is all.
8
+ @record = @column.association.klass.find(params[:associated_id]) if params[:associated_id]
9
+ @record ||= @column.association.klass.new
10
+
11
+ @scope = "[#{@column.name}]"
12
+ @scope += (@record.new_record?) ? "[#{(Time.now.to_f*1000).to_i.to_s}]" : "[#{@record.id}]" if @column.plural_association?
13
+
14
+ render :action => 'edit_associated'
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,134 @@
1
+ module ActiveScaffold::Actions
2
+ module Update
3
+ def self.included(base)
4
+ base.before_filter :update_authorized_filter, :only => [:edit, :update]
5
+ base.verify :method => [:post, :put],
6
+ :only => :update,
7
+ :redirect_to => { :action => :index }
8
+ end
9
+
10
+ def edit
11
+ do_edit
12
+ respond_to_action(:edit)
13
+ end
14
+
15
+ def update
16
+ do_update
17
+ respond_to_action(:update)
18
+ end
19
+
20
+ # for inline (inlist) editing
21
+ def update_column
22
+ do_update_column
23
+ render :action => 'update_column', :locals => {:column_span_id => params[:editor_id] || params[:editorId]}
24
+ end
25
+
26
+ protected
27
+ def edit_respond_to_html
28
+ if successful?
29
+ render(:action => 'update')
30
+ else
31
+ return_to_main
32
+ end
33
+ end
34
+ def edit_respond_to_js
35
+ render(:partial => 'update_form')
36
+ end
37
+ def update_respond_to_html
38
+ if params[:iframe]=='true' # was this an iframe post ?
39
+ responds_to_parent do
40
+ render :action => 'on_update.js', :layout => false
41
+ end
42
+ else # just a regular post
43
+ if successful?
44
+ flash[:info] = as_(:updated_model, :model => @record.to_label)
45
+ return_to_main
46
+ else
47
+ render(:action => 'update')
48
+ end
49
+ end
50
+ end
51
+ def update_respond_to_js
52
+ render :action => 'on_update'
53
+ end
54
+ def update_respond_to_xml
55
+ render :xml => response_object.to_xml(:only => active_scaffold_config.update.columns.names), :content_type => Mime::XML, :status => response_status
56
+ end
57
+ def update_respond_to_json
58
+ render :text => response_object.to_json(:only => active_scaffold_config.update.columns.names), :content_type => Mime::JSON, :status => response_status
59
+ end
60
+ def update_respond_to_yaml
61
+ render :text => Hash.from_xml(response_object.to_xml(:only => active_scaffold_config.update.columns.names)).to_yaml, :content_type => Mime::YAML, :status => response_status
62
+ end
63
+ # A simple method to find and prepare a record for editing
64
+ # May be overridden to customize the record (set default values, etc.)
65
+ def do_edit
66
+ register_constraints_with_action_columns(nested.constrained_fields, active_scaffold_config.update.hide_nested_column ? [] : [:update]) if nested?
67
+ @record = find_if_allowed(params[:id], :update)
68
+ end
69
+
70
+ # A complex method to update a record. The complexity comes from the support for subforms, and saving associated records.
71
+ # If you want to customize this algorithm, consider using the +before_update_save+ callback
72
+ def do_update
73
+ do_edit
74
+ @record = update_record_from_params(@record, active_scaffold_config.update.columns, params[:record])
75
+ update_save
76
+ end
77
+
78
+ def update_save
79
+ begin
80
+ active_scaffold_config.model.transaction do
81
+ before_update_save(@record)
82
+ self.successful = [@record.valid?, @record.associated_valid?].all? {|v| v == true} # this syntax avoids a short-circuit
83
+ if successful?
84
+ @record.save! and @record.save_associated!
85
+ after_update_save(@record)
86
+ end
87
+ end
88
+ rescue ActiveRecord::RecordInvalid
89
+ rescue ActiveRecord::StaleObjectError
90
+ @record.errors.add_to_base as_(:version_inconsistency)
91
+ self.successful=false
92
+ rescue ActiveRecord::RecordNotSaved
93
+ @record.errors.add_to_base as_(:record_not_saved) if @record.errors.empty?
94
+ self.successful = false
95
+ end
96
+ end
97
+
98
+ def do_update_column
99
+ @record = active_scaffold_config.model.find(params[:id])
100
+ if @record.authorized_for?(:crud_type => :update, :column => params[:column])
101
+ column = active_scaffold_config.columns[params[:column].to_sym]
102
+ params[:value] ||= @record.column_for_attribute(params[:column]).default unless @record.column_for_attribute(params[:column]).nil? || @record.column_for_attribute(params[:column]).null
103
+ params[:value] = column_value_from_param_value(@record, column, params[:value]) unless column.nil?
104
+ @record.send("#{params[:column]}=", params[:value])
105
+ before_update_save(@record)
106
+ @record.save
107
+ after_update_save(@record)
108
+ end
109
+ end
110
+
111
+ # override this method if you want to inject data in the record (or its associated objects) before the save
112
+ def before_update_save(record); end
113
+
114
+ # override this method if you want to do something after the save
115
+ def after_update_save(record); end
116
+
117
+ # The default security delegates to ActiveRecordPermissions.
118
+ # You may override the method to customize.
119
+ def update_authorized?(record = nil)
120
+ (!nested? || !nested.readonly?) && authorized_for?(:crud_type => :update)
121
+ end
122
+ private
123
+ def update_authorized_filter
124
+ link = active_scaffold_config.update.link || active_scaffold_config.update.class.link
125
+ raise ActiveScaffold::ActionNotAllowed unless self.send(link.security_method)
126
+ end
127
+ def edit_formats
128
+ (default_formats + active_scaffold_config.formats).uniq
129
+ end
130
+ def update_formats
131
+ (default_formats + active_scaffold_config.formats + active_scaffold_config.update.formats).uniq
132
+ end
133
+ end
134
+ end