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,26 @@
1
+ require 'paginator'
2
+
3
+ class Paginator
4
+
5
+ # Total number of pages
6
+ def number_of_pages_with_infinite
7
+ number_of_pages_without_infinite unless infinite?
8
+ end
9
+ alias_method_chain :number_of_pages, :infinite
10
+
11
+ # Is this an "infinite" paginator
12
+ def infinite?
13
+ @count.nil?
14
+ end
15
+
16
+ class Page
17
+ # Checks to see if there's a page after this one
18
+ def next_with_infinite?
19
+ return true if @pager.infinite?
20
+ next_without_infinite?
21
+ end
22
+ alias_method_chain :next?, :infinite
23
+ end
24
+
25
+ end
26
+
@@ -0,0 +1,62 @@
1
+ module ActiveRecord
2
+ module Reflection
3
+ class AssociationReflection #:nodoc:
4
+ def reverse_for?(klass)
5
+ reverse_matches_for(klass).empty? ? false : true
6
+ end
7
+
8
+ attr_writer :reverse
9
+ def reverse
10
+ if @reverse.nil? and not self.options[:polymorphic]
11
+ reverse_matches = reverse_matches_for(self.class_name.constantize) rescue nil
12
+ # grab first association, or make a wild guess
13
+ @reverse = reverse_matches.blank? ? false : reverse_matches.first.name
14
+ end
15
+ @reverse
16
+ end
17
+
18
+ protected
19
+
20
+ def reverse_matches_for(klass)
21
+ reverse_matches = []
22
+
23
+ # stage 1 filter: collect associations that point back to this model and use the same primary_key_name
24
+ klass.reflect_on_all_associations.each do |assoc|
25
+ if self.options[:through]
26
+ # only iterate has_many :through associations
27
+ next unless assoc.options[:through]
28
+ next unless assoc.through_reflection.klass == self.through_reflection.klass
29
+ else
30
+ # skip over has_many :through associations
31
+ next if assoc.options[:through]
32
+ next unless assoc.options[:polymorphic] or assoc.class_name.constantize == self.active_record
33
+
34
+ case [assoc.macro, self.macro].find_all{|m| m == :has_and_belongs_to_many}.length
35
+ # if both are a habtm, then match them based on the join table
36
+ when 2
37
+ next unless assoc.options[:join_table] == self.options[:join_table]
38
+
39
+ # if only one is a habtm, they do not match
40
+ when 1
41
+ next
42
+
43
+ # otherwise, match them based on the primary_key_name
44
+ when 0
45
+ next unless assoc.primary_key_name.to_sym == self.primary_key_name.to_sym
46
+ end
47
+ end
48
+
49
+ reverse_matches << assoc
50
+ end
51
+
52
+ # stage 2 filter: name-based matching (association name vs self.active_record.to_s)
53
+ reverse_matches.find_all do |assoc|
54
+ self.active_record.to_s.underscore.include? assoc.name.to_s.pluralize.singularize
55
+ end if reverse_matches.length > 1
56
+
57
+ reverse_matches
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,34 @@
1
+ module ActionDispatch
2
+ module Routing
3
+ ACTIVE_SCAFFOLD_CORE_ROUTING = {
4
+ :collection => {:show_search => :get, :render_field => :get},
5
+ :member => {:row => :get, :update_column => :post, :render_field => :get}
6
+ }
7
+ ACTIVE_SCAFFOLD_ASSOCIATION_ROUTING = {
8
+ :collection => {:edit_associated => :get, :new_existing => :get, :add_existing => :post},
9
+ :member => {:edit_associated => :get, :add_association => :get, :destroy_existing => :delete}
10
+ }
11
+ class Mapper
12
+ module Base
13
+ def as_routes(options = {:association => true})
14
+ collection do
15
+ ActionDispatch::Routing::ACTIVE_SCAFFOLD_CORE_ROUTING[:collection].each {|name, type| send(type, name)}
16
+ end
17
+ member do
18
+ ActionDispatch::Routing::ACTIVE_SCAFFOLD_CORE_ROUTING[:member].each {|name, type| send(type, name)}
19
+ end
20
+ as_association_routes if options[:association]
21
+ end
22
+
23
+ def as_association_routes
24
+ collection do
25
+ ActionDispatch::Routing::ACTIVE_SCAFFOLD_ASSOCIATION_ROUTING[:collection].each {|name, type| send(type, name)}
26
+ end
27
+ member do
28
+ ActionDispatch::Routing::ACTIVE_SCAFFOLD_ASSOCIATION_ROUTING[:member].each {|name, type| send(type, name)}
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,8 @@
1
+ # the ever-useful to_label method
2
+ class ActiveRecord::Base
3
+ def to_label
4
+ [:name, :label, :title, :to_s].each do |attribute|
5
+ return send(attribute).to_s if respond_to?(attribute)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,61 @@
1
+ # save and validation support for associations.
2
+ class ActiveRecord::Base
3
+ def associated_valid?(path = [])
4
+ return true if path.include?(self) # prevent recursion (if associated and parent are new records)
5
+ path << self
6
+ # using [].all? syntax to avoid a short-circuit
7
+ with_unsaved_associated { |a| [a.valid?, a.associated_valid?(path)].all? {|v| v == true} }
8
+ end
9
+
10
+ def save_associated
11
+ with_unsaved_associated { |a| a.save and a.save_associated }
12
+ end
13
+
14
+ def save_associated!
15
+ save_associated or raise(ActiveRecord::RecordNotSaved)
16
+ end
17
+
18
+ def no_errors_in_associated?
19
+ with_unsaved_associated {|a| a.errors.count == 0 and a.no_errors_in_associated?}
20
+ end
21
+
22
+ protected
23
+
24
+ # Provide an override to allow the model to restrict which associations are considered
25
+ # by ActiveScaffolds update mechanism. This allows the model to restrict things like
26
+ # Acts-As-Versioned versions associations being traversed.
27
+ #
28
+ # By defining the method :scaffold_update_nofollow returning an array of associations
29
+ # these associations will not be traversed.
30
+ # By defining the method :scaffold_update_follow returning an array of associations,
31
+ # only those associations will be traversed.
32
+ #
33
+ # Otherwise the default behaviour of traversing all associations will be preserved.
34
+ def associations_for_update
35
+ if self.respond_to?( :scaffold_update_nofollow )
36
+ self.class.reflect_on_all_associations.reject { |association| self.scaffold_update_nofollow.include?( association.name ) }
37
+ elsif self.respond_to?( :scaffold_update_follow )
38
+ self.class.reflect_on_all_associations.select { |association| self.scaffold_update_follow.include?( association.name ) }
39
+ else
40
+ self.class.reflect_on_all_associations
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ # yields every associated object that has been instantiated and is flagged as unsaved.
47
+ # returns false if any yield returns false.
48
+ # returns true otherwise, even when none of the associations have been instantiated. build wrapper methods accordingly.
49
+ def with_unsaved_associated
50
+ associations_for_update.all? do |association|
51
+ association_proxy = instance_variable_get("@#{association.name}")
52
+ if association_proxy
53
+ records = association_proxy
54
+ records = [records] unless records.is_a? Array # convert singular associations into collections for ease of use
55
+ records.select {|r| r.unsaved? and not r.readonly?}.all? {|r| yield r} # must use select instead of find_all, which Rails overrides on association proxies for db access
56
+ else
57
+ true
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,20 @@
1
+ # a simple (manual) unsaved? flag and method. at least it automatically reverts after a save!
2
+ class ActiveRecord::Base
3
+ # acts like a dirty? flag, manually thrown during update_record_from_params.
4
+ def unsaved=(val)
5
+ @unsaved = (val) ? true : false
6
+ end
7
+
8
+ # whether the unsaved? flag has been thrown
9
+ def unsaved?
10
+ @unsaved
11
+ end
12
+
13
+ # automatically unsets the unsaved flag
14
+ def save_with_unsaved_flag(*args)
15
+ result = save_without_unsaved_flag(*args)
16
+ self.unsaved = false
17
+ return result
18
+ end
19
+ alias_method_chain :save, :unsaved_flag
20
+ end
@@ -0,0 +1,46 @@
1
+ module ActionView
2
+ module Helpers
3
+ module FormOptionsHelper
4
+
5
+ # Return a full select and option tags for the given object and method, using usa_state_options_for_select to generate the list of option <tags>.
6
+ def usa_state_select(object, method, priority_states = nil, options = {}, html_options = {})
7
+ InstanceTag.new(object, method, self, options.delete(:object)).to_usa_state_select_tag(priority_states, options, html_options)
8
+ end
9
+
10
+
11
+ # Returns a string of option tags for the states in the United States. Supply a state name as +selected to
12
+ # have it marked as the selected option tag. Included also is the option to set a couple of +priority_states+
13
+ # in case you want to highligh a local area
14
+ # NOTE: Only the option tags are returned from this method, wrap it in a <select>
15
+ def usa_state_options_for_select(selected = nil, priority_states = nil)
16
+ state_options = ""
17
+ if priority_states
18
+ state_options += options_for_select(priority_states, selected)
19
+ state_options += "<option>-------------</option>\n"
20
+ end
21
+
22
+ if priority_states && priority_states.include?(selected)
23
+ state_options += options_for_select(USASTATES - priority_states, selected)
24
+ else
25
+ state_options += options_for_select(USASTATES, selected)
26
+ end
27
+
28
+ return state_options
29
+ end
30
+
31
+ USASTATES = [["Alabama", "AL"], ["Alaska", "AK"], ["Arizona", "AZ"], ["Arkansas", "AR"], ["California", "CA"], ["Colorado", "CO"], ["Connecticut", "CT"], ["Delaware", "DE"], ["District of Columbia", "DC"], ["Florida", "FL"], ["Georgia", "GA"], ["Hawaii", "HI"], ["Idaho", "ID"], ["Illinois", "IL"], ["Indiana", "IN"], ["Iowa", "IA"], ["Kansas", "KS"], ["Kentucky", "KY"], ["Louisiana", "LA"], ["Maine", "ME"], ["Maryland", "MD"], ["Massachusetts", "MA"], ["Michigan", "MI"], ["Minnesota", "MN"], ["Mississippi", "MS"], ["Missouri", "MO"], ["Montana", "MT"], ["Nebraska", "NE"], ["Nevada", "NV"], ["New Hampshire", "NH"], ["New Jersey", "NJ"], ["New Mexico", "NM"], ["New York", "NY"], ["North Carolina", "NC"], ["North Dakota", "ND"], ["Ohio", "OH"], ["Oklahoma", "OK"], ["Oregon", "OR"], ["Pennsylvania", "PA"], ["Rhode Island", "RI"], ["South Carolina", "SC"], ["South Dakota", "SD"], ["Tennessee", "TN"], ["Texas", "TX"], ["Utah", "UT"], ["Vermont", "VT"], ["Virginia", "VA"], ["Washington", "WA"], ["Wisconsin", "WI"], ["West Virginia", "WV"], ["Wyoming", "WY"]] unless const_defined?("USASTATES")
32
+
33
+ end
34
+
35
+ class InstanceTag #:nodoc:
36
+ include FormOptionsHelper
37
+
38
+ def to_usa_state_select_tag(priority_states, options, html_options)
39
+ html_options = html_options.stringify_keys
40
+ add_default_name_and_id(html_options)
41
+ value = value(object) if method(:value).arity > 0
42
+ content_tag("select", add_options(usa_state_options_for_select(value, priority_states), options, value), html_options)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,29 @@
1
+ Description:
2
+ Scaffolds an entire resource, from model and migration to controller,
3
+ along with a full test suite and configured to use active_scaffold.
4
+ The resource is ready to use as a starting point for your RESTful,
5
+ resource-oriented application.
6
+
7
+ Pass the name of the model (in singular form), either CamelCased or
8
+ under_scored, as the first argument, and an optional list of attribute
9
+ pairs.
10
+
11
+ Attribute pairs are field:type arguments specifying the
12
+ model's attributes. Timestamps are added by default, so you don't have to
13
+ specify them by hand as 'created_at:datetime updated_at:datetime'.
14
+
15
+ You don't have to think up every attribute up front, but it helps to
16
+ sketch out a few so you can start working with the resource immediately.
17
+
18
+ For example, 'active_scaffold post title:string body:text published:boolean'
19
+ gives you a model with those three attributes, a controller configured to use active_scaffold,
20
+ as well as a resources :posts with additional active_scaffold routes
21
+ declaration in config/routes.rb.
22
+
23
+ If you want to remove all the generated files, run
24
+ 'rails destroy active_scaffold ModelName'.
25
+
26
+ Examples:
27
+ `rails generate active_scaffold post`
28
+ `rails generate active_scaffold post title:string body:text published:boolean`
29
+ `rails generate active_scaffold purchase order_id:integer amount:decimal`
@@ -0,0 +1,20 @@
1
+ require 'rails/generators/rails/resource/resource_generator'
2
+ #require 'generators/active_scaffold_controller/active_scaffold_controller_generator'
3
+
4
+ module Rails
5
+ module Generators
6
+ class ActiveScaffoldGenerator < ResourceGenerator #metagenerator
7
+ remove_hook_for :resource_controller
8
+ remove_class_option :actions
9
+
10
+ def add_resource_route
11
+ route_config = class_path.collect{|namespace| "namespace :#{namespace} do " }.join(" ")
12
+ route_config << "resources :#{file_name.pluralize} do as_routes end"
13
+ route_config << " end" * class_path.size
14
+ route route_config
15
+ end
16
+
17
+ invoke "active_scaffold_controller"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ Description:
2
+ Stubs out a active_scaffolded controller. Pass the model name,
3
+ either CamelCased or under_scored.
4
+ The controller name is retrieved as a pluralized version of the model
5
+ name.
6
+
7
+ To create a controller within a module, specify the model name as a
8
+ path like 'parent_module/controller_name'.
9
+
10
+ This generates a controller class in app/controllers and invokes helper,
11
+ template engine and test framework generators.
12
+
13
+ Example:
14
+ `rails generate active_scaffold_controller CreditCard`
15
+
16
+ Credit card controller with URLs like /credit_card/debit.
17
+ Controller: app/controllers/credit_cards_controller.rb
18
+ Functional Test: test/functional/credit_cards_controller_test.rb
19
+ Helper: app/helpers/credit_cards_helper.rb
@@ -0,0 +1,28 @@
1
+ #require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator'
2
+
3
+ module Rails
4
+ module Generators
5
+ class ActiveScaffoldControllerGenerator < NamedBase #metagenerator
6
+ include ResourceHelpers
7
+
8
+ def self.source_root
9
+ @source_root ||= File.join(File.dirname(__FILE__), 'templates')
10
+ end
11
+
12
+ check_class_collision :suffix => "Controller"
13
+
14
+ class_option :orm, :banner => "NAME", :type => :string, :required => true,
15
+ :desc => "ORM to generate the controller for"
16
+
17
+ def create_controller_files
18
+ template 'controller.rb', File.join('app/controllers', class_path, "#{controller_file_name}_controller.rb")
19
+ end
20
+
21
+ hook_for :test_framework, :as => :scaffold
22
+
23
+ def create_view_root_folder
24
+ empty_directory File.join("app/views", controller_file_path)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,4 @@
1
+ class <%= controller_class_name %>Controller < ApplicationController
2
+ active_scaffold :<%= class_name.demodulize.underscore %> do |conf|
3
+ end
4
+ end
@@ -0,0 +1,10 @@
1
+ Description:
2
+ Setup a new Rails 3 Application with active_scaffold.
3
+ Pass 'jquery' in case you would like to use it instead of prototype
4
+
5
+ This installs required plugins and configures active_scaffold to use
6
+ specified js lib and application layout file to include all required
7
+ assets
8
+
9
+ Example:
10
+ `rails generate active_scaffold_setup jquery`
@@ -0,0 +1,53 @@
1
+ module Rails
2
+ module Generators
3
+ class ActiveScaffoldSetupGenerator < Rails::Generators::Base #metagenerator
4
+ argument :js_lib, :type => :string, :default => 'prototype', :desc => 'js_lib for activescaffold (prototype|jquery)'
5
+
6
+ def self.source_root
7
+ @source_root ||= File.join(File.dirname(__FILE__), 'templates')
8
+ end
9
+
10
+ def install_plugins
11
+ plugin 'verification', :git => 'git://github.com/rails/verification.git'
12
+ plugin 'render_component', :git => 'git://github.com/vhochstein/render_component.git'
13
+ if js_lib == 'prototype'
14
+ get "https://github.com/vhochstein/prototype-ujs/raw/master/src/rails.js", "public/javascripts/rails.js"
15
+ elsif js_lib == 'jquery'
16
+ get "https://github.com/vhochstein/jquery-ujs/raw/master/src/rails.js", "public/javascripts/rails_jquery.js"
17
+ get "https://github.com/vhochstein/jQuery-Timepicker-Addon/raw/master/jquery-ui-timepicker-addon.js", "public/javascripts/jquery-ui-timepicker-addon.js"
18
+ end
19
+ end
20
+
21
+ def configure_active_scaffold
22
+ if js_lib == 'jquery'
23
+ gsub_file 'vendor/plugins/active_scaffold/lib/environment.rb', /#ActiveScaffold.js_framework = :jquery/, 'ActiveScaffold.js_framework = :jquery'
24
+ end
25
+ end
26
+
27
+ def configure_application_layout
28
+ if js_lib == 'prototype'
29
+ inject_into_file "app/views/layouts/application.html.erb",
30
+ " <%= active_scaffold_includes %>\n",
31
+ :after => "<%= javascript_include_tag :defaults %>\n"
32
+ elsif js_lib == 'jquery'
33
+ inject_into_file "app/views/layouts/application.html.erb",
34
+ " <%= stylesheet_link_tag 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/themes/ui-lightness/jquery-ui.css' %>
35
+ <%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.js' %>
36
+ <%= javascript_include_tag 'rails_jquery.js' %>
37
+ <%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/jquery-ui.js' %>
38
+ <%= javascript_include_tag 'jquery-ui-timepicker-addon.js' %>
39
+ <%= javascript_include_tag 'application.js' %>
40
+ <%= active_scaffold_includes %>\n",
41
+ :after => "<%= javascript_include_tag :defaults %>\n"
42
+
43
+ inject_into_file "config/locales/en.yml",
44
+ " time:
45
+ formats:
46
+ default: \"%a, %d %b %Y %H:%M:%S\"",
47
+ :after => "hello: \"Hello world\"\n"
48
+ gsub_file 'app/views/layouts/application.html.erb', /<%= javascript_include_tag :defaults/, '<%# javascript_include_tag :defaults'
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
data/lib/paginator.rb ADDED
@@ -0,0 +1,136 @@
1
+ require 'forwardable'
2
+
3
+ class Paginator
4
+
5
+ VERSION = '1.0.9'
6
+
7
+ class ArgumentError < ::ArgumentError; end
8
+ class MissingCountError < ArgumentError; end
9
+ class MissingSelectError < ArgumentError; end
10
+
11
+ attr_reader :per_page, :count
12
+
13
+ # Instantiate a new Paginator object
14
+ #
15
+ # Provide:
16
+ # * A total count of the number of objects to paginate
17
+ # * The number of objects in each page
18
+ # * A block that returns the array of items
19
+ # * The block is passed the item offset
20
+ # (and the number of items to show per page, for
21
+ # convenience, if the arity is 2)
22
+ def initialize(count, per_page, &select)
23
+ @count, @per_page = count, per_page
24
+ unless select
25
+ raise MissingSelectError, "Must provide block to select data for each page"
26
+ end
27
+ @select = select
28
+ end
29
+
30
+ # Total number of pages
31
+ def number_of_pages
32
+ (@count / @per_page).to_i + (@count % @per_page > 0 ? 1 : 0)
33
+ end
34
+
35
+ # First page object
36
+ def first
37
+ page 1
38
+ end
39
+
40
+ # Last page object
41
+ def last
42
+ page number_of_pages
43
+ end
44
+
45
+ # Iterate through pages
46
+ def each
47
+ each_with_index do |item, index|
48
+ yield item
49
+ end
50
+ end
51
+
52
+ # Iterate through pages with indices
53
+ def each_with_index
54
+ 1.upto(number_of_pages) do |number|
55
+ yield(page(number), number - 1)
56
+ end
57
+ end
58
+
59
+ # Retrieve page object by number
60
+ def page(number)
61
+ number = (n = number.to_i) > 0 ? n : 1
62
+ Page.new(self, number, lambda {
63
+ offset = (number - 1) * @per_page
64
+ args = [offset]
65
+ args << @per_page if @select.arity == 2
66
+ @select.call(*args)
67
+ })
68
+ end
69
+
70
+ # Page object
71
+ #
72
+ # Retrieves items for a page and provides metadata about the position
73
+ # of the page in the paginator
74
+ class Page
75
+
76
+ extend Forwardable
77
+ def_delegator :@pager, :first, :first
78
+ def_delegator :@pager, :last, :last
79
+ def_delegator :items, :each
80
+ def_delegator :items, :each_with_index
81
+
82
+ attr_reader :number, :pager
83
+
84
+ def initialize(pager, number, select) #:nodoc:
85
+ @pager, @number = pager, number
86
+ @offset = (number - 1) * pager.per_page
87
+ @select = select
88
+ end
89
+
90
+ # Retrieve the items for this page
91
+ # * Caches
92
+ def items
93
+ @items ||= @select.call
94
+ end
95
+
96
+ # Checks to see if there's a page before this one
97
+ def prev?
98
+ @number > 1
99
+ end
100
+
101
+ # Get previous page (if possible)
102
+ def prev
103
+ @pager.page(@number - 1) if prev?
104
+ end
105
+
106
+ # Checks to see if there's a page after this one
107
+ def next?
108
+ @number < @pager.number_of_pages
109
+ end
110
+
111
+ # Get next page (if possible)
112
+ def next
113
+ @pager.page(@number + 1) if next?
114
+ end
115
+
116
+ # The "item number" of the first item on this page
117
+ def first_item_number
118
+ 1 + @offset
119
+ end
120
+
121
+ # The "item number" of the last item on this page
122
+ def last_item_number
123
+ if next?
124
+ @offset + @pager.per_page
125
+ else
126
+ @pager.count
127
+ end
128
+ end
129
+
130
+ def ==(other) #:nodoc:
131
+ @pager == other.pager && self.number == other.number
132
+ end
133
+
134
+ end
135
+
136
+ end
@@ -0,0 +1,70 @@
1
+ # Copyright (c) 2006 Sean Treadway
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+
23
+ # Module containing the methods useful for child IFRAME to parent window communication
24
+ module RespondsToParent
25
+
26
+ # Executes the response body as JavaScript in the context of the parent window.
27
+ # Use this method of you are posting a form to a hidden IFRAME or if you would like
28
+ # to use IFRAME base RPC.
29
+ def responds_to_parent(&block)
30
+ yield
31
+
32
+ if performed?
33
+ # We're returning HTML instead of JS or XML now
34
+ response.headers['Content-Type'] = 'text/html; charset=UTF-8'
35
+
36
+ # Either pull out a redirect or the request body
37
+ script = if response.headers['Location']
38
+ #TODO: erase_redirect_results is missing in rails 3.0 has to be implemented
39
+ #erase redirect
40
+ "document.location.href = #{location.to_s.inspect}"
41
+ else
42
+ response.body
43
+ end
44
+
45
+ # Escape quotes, linebreaks and slashes, maintaining previously escaped slashes
46
+ # Suggestions for improvement?
47
+ script = (script || '').
48
+ gsub('\\', '\\\\\\').
49
+ gsub(/\r\n|\r|\n/, '\\n').
50
+ gsub(/['"]/, '\\\\\&').
51
+ gsub('</script>','</scr"+"ipt>')
52
+
53
+ # Clear out the previous render to prevent double render
54
+ response.request.env['action_controller.instance'].instance_variable_set(:@_response_body, nil)
55
+
56
+ # Eval in parent scope and replace document location of this frame
57
+ # so back button doesn't replay action on targeted forms
58
+ # loc = document.location to be set after parent is updated for IE
59
+ # with(window.parent) - pull in variables from parent window
60
+ # setTimeout - scope the execution in the windows parent for safari
61
+ # window.eval - legal eval for Opera
62
+ render :text => "<html><body><script type='text/javascript' charset='utf-8'>
63
+ var loc = document.location;
64
+ with(window.parent) { setTimeout(function() { window.eval('#{script}'); if (typeof(loc) !== 'undefined') loc.replace('about:blank'); }, 1) };
65
+ </script></body></html>".html_safe
66
+ end
67
+ end
68
+ alias respond_to_parent responds_to_parent
69
+ end
70
+