active_scaffold 3.3.3 → 3.4.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 (198) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +39 -0
  3. data/README.md +5 -3
  4. data/app/assets/images/active_scaffold/refresh.png +0 -0
  5. data/app/assets/javascripts/jquery/active_scaffold.js +182 -91
  6. data/app/assets/javascripts/jquery/date_picker_bridge.js.erb +14 -16
  7. data/app/assets/javascripts/jquery/draggable_lists.js +33 -26
  8. data/app/assets/javascripts/jquery/jquery.editinplace.js +3 -3
  9. data/app/assets/javascripts/prototype/active_scaffold.js +61 -19
  10. data/app/assets/stylesheets/active_scaffold_colors.css.scss +4 -0
  11. data/app/assets/stylesheets/active_scaffold_images.css.scss +3 -0
  12. data/app/assets/stylesheets/active_scaffold_layout.css +23 -2
  13. data/app/views/active_scaffold_overrides/_add_existing_form.html.erb +1 -3
  14. data/app/views/active_scaffold_overrides/_base_form.html.erb +7 -5
  15. data/app/views/active_scaffold_overrides/_field_search.html.erb +1 -2
  16. data/app/views/active_scaffold_overrides/_form.html.erb +6 -4
  17. data/app/views/active_scaffold_overrides/_form_association.html.erb +4 -3
  18. data/app/views/active_scaffold_overrides/_form_association_footer.html.erb +5 -5
  19. data/app/views/active_scaffold_overrides/_form_association_record.html.erb +8 -6
  20. data/app/views/active_scaffold_overrides/_horizontal_subform_header.html.erb +3 -2
  21. data/app/views/active_scaffold_overrides/_list.html.erb +8 -6
  22. data/app/views/active_scaffold_overrides/_list_column_headings.html.erb +1 -4
  23. data/app/views/active_scaffold_overrides/_list_pagination.html.erb +4 -4
  24. data/app/views/active_scaffold_overrides/_list_pagination_links.html.erb +1 -1
  25. data/app/views/active_scaffold_overrides/_list_record.html.erb +3 -3
  26. data/app/views/active_scaffold_overrides/_refresh_list.js.erb +8 -1
  27. data/app/views/active_scaffold_overrides/_search.html.erb +7 -13
  28. data/app/views/active_scaffold_overrides/_show_columns.html.erb +1 -1
  29. data/app/views/active_scaffold_overrides/on_create.js.erb +4 -4
  30. data/app/views/active_scaffold_overrides/render_field_inplace.html.erb +1 -1
  31. data/app/views/active_scaffold_overrides/row.js.erb +1 -1
  32. data/config/locales/de.yml +106 -95
  33. data/config/locales/en.yml +108 -97
  34. data/config/locales/es.yml +109 -98
  35. data/config/locales/fr.yml +108 -97
  36. data/config/locales/hu.yml +109 -98
  37. data/config/locales/ja.yml +100 -89
  38. data/config/locales/ru.yml +115 -104
  39. data/lib/active_scaffold.rb +18 -294
  40. data/lib/active_scaffold/actions/common_search.rb +50 -17
  41. data/lib/active_scaffold/actions/core.rb +93 -22
  42. data/lib/active_scaffold/actions/create.rb +15 -6
  43. data/lib/active_scaffold/actions/field_search.rb +68 -60
  44. data/lib/active_scaffold/actions/list.rb +49 -28
  45. data/lib/active_scaffold/actions/nested.rb +14 -6
  46. data/lib/active_scaffold/actions/search.rb +36 -35
  47. data/lib/active_scaffold/actions/show.rb +9 -4
  48. data/lib/active_scaffold/actions/subform.rb +1 -1
  49. data/lib/active_scaffold/actions/update.rb +22 -7
  50. data/lib/active_scaffold/active_record_permissions.rb +125 -118
  51. data/lib/active_scaffold/attribute_params.rb +84 -66
  52. data/lib/active_scaffold/bridges.rb +3 -3
  53. data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +10 -5
  54. data/lib/active_scaffold/bridges/cancan.rb +2 -1
  55. data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +13 -2
  56. data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +11 -6
  57. data/lib/active_scaffold/bridges/chosen/helpers.rb +2 -2
  58. data/lib/active_scaffold/bridges/country_helper/country_helper_bridge.rb +45 -29
  59. data/lib/active_scaffold/bridges/date_picker/ext.rb +11 -6
  60. data/lib/active_scaffold/bridges/date_picker/helper.rb +5 -1
  61. data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +10 -5
  62. data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +6 -1
  63. data/lib/active_scaffold/bridges/file_column/form_ui.rb +12 -11
  64. data/lib/active_scaffold/bridges/paperclip/form_ui.rb +14 -6
  65. data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
  66. data/lib/active_scaffold/bridges/record_select/helpers.rb +15 -12
  67. data/lib/active_scaffold/bridges/shared/date_bridge.rb +7 -8
  68. data/lib/active_scaffold/bridges/tiny_mce.rb +5 -3
  69. data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +4 -5
  70. data/lib/active_scaffold/config/base.rb +4 -0
  71. data/lib/active_scaffold/config/core.rb +12 -5
  72. data/lib/active_scaffold/config/delete.rb +0 -2
  73. data/lib/active_scaffold/config/field_search.rb +1 -4
  74. data/lib/active_scaffold/config/form.rb +0 -2
  75. data/lib/active_scaffold/config/list.rb +31 -1
  76. data/lib/active_scaffold/config/search.rb +0 -3
  77. data/lib/active_scaffold/config/show.rb +0 -6
  78. data/lib/active_scaffold/config/subform.rb +1 -0
  79. data/lib/active_scaffold/configurable.rb +2 -2
  80. data/lib/active_scaffold/constraints.rb +11 -14
  81. data/lib/active_scaffold/core.rb +277 -0
  82. data/lib/active_scaffold/data_structures/action_columns.rb +18 -2
  83. data/lib/active_scaffold/data_structures/action_link.rb +25 -6
  84. data/lib/active_scaffold/data_structures/action_links.rb +9 -4
  85. data/lib/active_scaffold/data_structures/actions.rb +1 -1
  86. data/lib/active_scaffold/data_structures/column.rb +6 -6
  87. data/lib/active_scaffold/data_structures/columns.rb +2 -2
  88. data/lib/active_scaffold/data_structures/nested_info.rb +5 -1
  89. data/lib/active_scaffold/data_structures/sorting.rb +15 -5
  90. data/lib/active_scaffold/delayed_setup.rb +30 -0
  91. data/lib/active_scaffold/engine.rb +25 -0
  92. data/lib/active_scaffold/extensions/action_view_rendering.rb +1 -1
  93. data/lib/active_scaffold/extensions/left_outer_joins.rb +61 -21
  94. data/lib/active_scaffold/extensions/localize.rb +1 -1
  95. data/lib/active_scaffold/extensions/name_option_for_datetime.rb +13 -8
  96. data/lib/active_scaffold/extensions/paginator_extensions.rb +5 -1
  97. data/lib/active_scaffold/extensions/reverse_associations.rb +1 -0
  98. data/lib/active_scaffold/extensions/routing_mapper.rb +1 -1
  99. data/lib/active_scaffold/extensions/unsaved_record.rb +4 -6
  100. data/lib/active_scaffold/finder.rb +79 -27
  101. data/lib/active_scaffold/helpers/association_helpers.rb +48 -18
  102. data/lib/active_scaffold/helpers/controller_helpers.rb +19 -10
  103. data/lib/active_scaffold/helpers/form_column_helpers.rb +185 -87
  104. data/lib/active_scaffold/helpers/human_condition_helpers.rb +2 -1
  105. data/lib/active_scaffold/helpers/id_helpers.rb +14 -8
  106. data/lib/active_scaffold/helpers/list_column_helpers.rb +65 -56
  107. data/lib/active_scaffold/helpers/pagination_helpers.rb +5 -1
  108. data/lib/active_scaffold/helpers/search_column_helpers.rb +21 -18
  109. data/lib/active_scaffold/helpers/view_helpers.rb +102 -64
  110. data/lib/active_scaffold/responds_to_parent.rb +39 -64
  111. data/lib/active_scaffold/tableless.rb +129 -10
  112. data/lib/active_scaffold/version.rb +2 -2
  113. data/test/bridges/bridge_test.rb +1 -1
  114. data/test/bridges/date_picker_test.rb +2 -2
  115. data/test/bridges/paperclip_test.rb +10 -8
  116. data/test/bridges/tiny_mce_test.rb +2 -2
  117. data/test/company.rb +22 -10
  118. data/test/config/base_test.rb +1 -1
  119. data/test/config/core_test.rb +8 -6
  120. data/test/config/create_test.rb +6 -6
  121. data/test/config/delete_test.rb +4 -4
  122. data/test/config/field_search_test.rb +6 -6
  123. data/test/config/list_test.rb +7 -7
  124. data/test/config/nested_test.rb +8 -7
  125. data/test/config/search_test.rb +7 -7
  126. data/test/config/show_test.rb +5 -5
  127. data/test/config/subform_test.rb +1 -1
  128. data/test/config/update_test.rb +5 -4
  129. data/test/data_structures/action_columns_test.rb +15 -16
  130. data/test/data_structures/action_link_test.rb +10 -10
  131. data/test/data_structures/action_links_test.rb +6 -6
  132. data/test/data_structures/actions_test.rb +4 -4
  133. data/test/data_structures/association_column_test.rb +4 -4
  134. data/test/data_structures/column_test.rb +9 -9
  135. data/test/data_structures/columns_test.rb +7 -7
  136. data/test/data_structures/error_message_test.rb +2 -4
  137. data/test/data_structures/set_test.rb +13 -13
  138. data/test/data_structures/sorting_test.rb +8 -8
  139. data/test/data_structures/standard_column_test.rb +2 -2
  140. data/test/data_structures/validation_reflection_test.rb +8 -8
  141. data/test/data_structures/virtual_column_test.rb +5 -5
  142. data/test/extensions/active_record_test.rb +1 -1
  143. data/test/helpers/form_column_helpers_test.rb +5 -5
  144. data/test/helpers/list_column_helpers_test.rb +2 -1
  145. data/test/helpers/pagination_helpers_test.rb +1 -1
  146. data/test/misc/active_record_permissions_test.rb +23 -4
  147. data/test/misc/attribute_params_test.rb +304 -136
  148. data/test/misc/calculation_test.rb +55 -0
  149. data/test/misc/configurable_test.rb +22 -21
  150. data/test/misc/constraints_test.rb +10 -7
  151. data/test/misc/convert_numbers_format_test.rb +149 -0
  152. data/test/misc/finder_test.rb +17 -13
  153. data/test/misc/lang_test.rb +1 -1
  154. data/test/misc/tableless_test.rb +18 -0
  155. data/test/mock_app/app/controllers/addresses_controller.rb +4 -0
  156. data/test/mock_app/app/controllers/buildings_controller.rb +4 -0
  157. data/test/mock_app/app/controllers/cars_controller.rb +4 -0
  158. data/test/mock_app/app/controllers/contacts_controller.rb +4 -0
  159. data/test/mock_app/app/controllers/floors_controller.rb +6 -0
  160. data/test/mock_app/app/controllers/people_controller.rb +4 -0
  161. data/test/mock_app/app/models/address.rb +3 -0
  162. data/test/mock_app/app/models/building.rb +8 -0
  163. data/test/mock_app/app/models/car.rb +3 -0
  164. data/test/mock_app/app/models/contact.rb +3 -0
  165. data/test/mock_app/app/models/file_model.rb +19 -0
  166. data/test/mock_app/app/models/floor.rb +8 -0
  167. data/test/mock_app/app/models/person.rb +11 -0
  168. data/test/mock_app/config/application.rb +2 -0
  169. data/test/mock_app/config/environments/test.rb +1 -1
  170. data/test/mock_app/config/initializers/secret_token.rb +5 -1
  171. data/test/mock_app/config/routes.rb +1 -1
  172. data/test/mock_app/db/schema.rb +51 -0
  173. data/test/model_stub.rb +3 -3
  174. data/test/test_helper.rb +15 -12
  175. metadata +51 -50
  176. data/lib/active_scaffold/extensions/array.rb +0 -7
  177. data/lib/active_scaffold/extensions/cache_association.rb +0 -16
  178. data/lib/active_scaffold/extensions/usa_state.rb +0 -46
  179. data/lib/active_scaffold_env.rb +0 -13
  180. data/test/extensions/array_test.rb +0 -12
  181. data/test/mock_app/public/blank.html +0 -33
  182. data/test/mock_app/public/images/active_scaffold/DO_NOT_EDIT +0 -2
  183. data/test/mock_app/public/images/active_scaffold/default/add.gif +0 -0
  184. data/test/mock_app/public/images/active_scaffold/default/arrow_down.gif +0 -0
  185. data/test/mock_app/public/images/active_scaffold/default/arrow_up.gif +0 -0
  186. data/test/mock_app/public/images/active_scaffold/default/close.gif +0 -0
  187. data/test/mock_app/public/images/active_scaffold/default/cross.png +0 -0
  188. data/test/mock_app/public/images/active_scaffold/default/indicator-small.gif +0 -0
  189. data/test/mock_app/public/images/active_scaffold/default/indicator.gif +0 -0
  190. data/test/mock_app/public/images/active_scaffold/default/magnifier.png +0 -0
  191. data/test/mock_app/public/javascripts/active_scaffold/DO_NOT_EDIT +0 -2
  192. data/test/mock_app/public/javascripts/active_scaffold/default/active_scaffold.js +0 -532
  193. data/test/mock_app/public/javascripts/active_scaffold/default/dhtml_history.js +0 -867
  194. data/test/mock_app/public/javascripts/active_scaffold/default/form_enhancements.js +0 -117
  195. data/test/mock_app/public/javascripts/active_scaffold/default/rico_corner.js +0 -370
  196. data/test/mock_app/public/stylesheets/active_scaffold/DO_NOT_EDIT +0 -2
  197. data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet-ie.css +0 -35
  198. data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet.css +0 -848
@@ -12,6 +12,9 @@ module ActiveScaffold::DataStructures
12
12
  def label
13
13
  as_(@label) if @label
14
14
  end
15
+ def name
16
+ @label.to_s.underscore
17
+ end
15
18
  def css_class
16
19
  @label.to_s.underscore
17
20
  end
@@ -124,9 +127,22 @@ module ActiveScaffold::DataStructures
124
127
  end
125
128
  end
126
129
 
127
- attr_writer :constraint_columns
130
+ def action_name
131
+ @action.class.name.demodulize.underscore
132
+ end
133
+
134
+ def constraint_columns_key
135
+ "#{@action.core.model_id.to_s.underscore}-#{action_name}"
136
+ end
137
+
138
+ def constraint_columns=(columns)
139
+ Thread.current[:constraint_columns] ||= {}
140
+ Thread.current[:constraint_columns][constraint_columns_key] = columns
141
+ end
142
+
128
143
  def constraint_columns
129
- @constraint_columns ||= []
144
+ constraints = Thread.current[:constraint_columns]
145
+ (constraints[constraint_columns_key] if constraints) || []
130
146
  end
131
147
 
132
148
  attr_writer :unauthorized_columns
@@ -13,19 +13,27 @@ module ActiveScaffold::DataStructures
13
13
  self.crud_type = :create if [:create, :new].include?(action.try(:to_sym))
14
14
  self.crud_type = :update if [:edit, :update].include?(action.try(:to_sym))
15
15
  self.crud_type ||= :read
16
- self.parameters = {}
17
- self.html_options = {}
18
16
  self.column = nil
19
17
  self.image = nil
20
18
  self.dynamic_parameters = nil
19
+ self.weight = 0
21
20
 
22
21
  # apply quick properties
23
22
  options.each_pair do |k, v|
24
23
  setter = "#{k}="
25
24
  self.send(setter, v) if self.respond_to? setter
26
25
  end
26
+ self.toggle = self.action.try(:to_sym) == :index && (parameters.present? || dynamic_parameters) unless options.include? :toggle
27
27
  end
28
28
 
29
+ def initialize_copy(action_link)
30
+ self.parameters = self.parameters.clone if action_link.instance_variable_get(:@parameters)
31
+ self.html_options = self.html_options.clone if action_link.instance_variable_get(:@html_options)
32
+ end
33
+
34
+ # the weight for this link in the action links collection, it will be used to sort the collection
35
+ attr_accessor :weight
36
+
29
37
  # the action-path for this link. what page to request? this is required!
30
38
  attr_accessor :action
31
39
 
@@ -42,7 +50,15 @@ module ActiveScaffold::DataStructures
42
50
  end
43
51
 
44
52
  # a hash of request parameters
45
- attr_accessor :parameters
53
+ attr_writer :parameters
54
+ def parameters
55
+ @parameters ||= {}
56
+ end
57
+
58
+ # if active class is added to link when current request matches link
59
+ # enabled automatically for links to index with parameters or dynamic parameters
60
+ # disable when is not needed so current request match check is skipped
61
+ attr_accessor :toggle
46
62
 
47
63
  # a block for dynamic_parameters
48
64
  attr_accessor :dynamic_parameters
@@ -167,7 +183,10 @@ module ActiveScaffold::DataStructures
167
183
  attr_accessor :type
168
184
 
169
185
  # html options for the link
170
- attr_accessor :html_options
186
+ attr_writer :html_options
187
+ def html_options
188
+ @html_options ||= {}
189
+ end
171
190
 
172
191
  # nested action_links are referencing a column
173
192
  attr_accessor :column
@@ -183,8 +202,8 @@ module ActiveScaffold::DataStructures
183
202
  @column || (parameters && parameters[:named_scope])
184
203
  end
185
204
 
186
- def name_to_cache_link_url
187
- @name_to_cache_link_url ||= :"#{controller || 'self'}_#{action}#{'_' if parameters.present?}#{parameters.map{|k,v| "#{k}_#{v}"}.join('_')}_link_url"
205
+ def name_to_cache
206
+ @name_to_cache ||= "#{controller || 'self'}_#{type}_#{action}#{'_' if parameters.present?}#{parameters.map{|k,v| "#{k}=#{v.is_a?(Array) ? v.join(',') : v}"}.join('_')}"
188
207
  end
189
208
 
190
209
 
@@ -5,6 +5,7 @@ module ActiveScaffold::DataStructures
5
5
  def initialize
6
6
  @set = []
7
7
  @name = :root
8
+ @weight = 0
8
9
  end
9
10
 
10
11
  # adds an ActionLink, creating one from the arguments if need be
@@ -72,6 +73,7 @@ module ActiveScaffold::DataStructures
72
73
  self.each({:include_set => true}) do |link, set|
73
74
  if link.action.to_s == val.to_s
74
75
  set.delete link
76
+ break
75
77
  end
76
78
  end
77
79
  end
@@ -80,8 +82,10 @@ module ActiveScaffold::DataStructures
80
82
  @set.each do |group|
81
83
  if group.name == name
82
84
  @set.delete group
85
+ break
83
86
  else
84
87
  group.delete_group(name)
88
+ break
85
89
  end if group.is_a?(ActiveScaffold::DataStructures::ActionLinks)
86
90
  end
87
91
  end
@@ -89,7 +93,7 @@ module ActiveScaffold::DataStructures
89
93
  # iterates over the links, possibly by type
90
94
  def each(options = {}, &block)
91
95
  method = options[:reverse] ? :reverse_each : :each
92
- @set.send(method) do |item|
96
+ @set.sort_by(&:weight).send(method) do |item|
93
97
  if item.is_a?(ActiveScaffold::DataStructures::ActionLinks) && !options[:groups]
94
98
  item.each(options, &block)
95
99
  else
@@ -138,16 +142,17 @@ module ActiveScaffold::DataStructures
138
142
 
139
143
  def method_missing(name, *args, &block)
140
144
  class_eval %{
141
- def #{name}
142
- @#{name} ||= subgroup('#{name}'.to_sym)
145
+ def #{name}(label = nil)
146
+ @#{name} ||= subgroup('#{name}'.to_sym, label)
143
147
  yield @#{name} if block_given?
144
148
  @#{name}
145
149
  end
146
150
  }
147
- send(name, &block)
151
+ send(name, args.first, &block)
148
152
  end
149
153
 
150
154
  attr_accessor :name
155
+ attr_accessor :weight
151
156
 
152
157
  protected
153
158
 
@@ -21,7 +21,7 @@ class ActiveScaffold::DataStructures::Actions
21
21
  end
22
22
 
23
23
  def include?(val)
24
- super val.to_sym
24
+ val.is_a?(Symbol) ? super : @set.any?{|item| item.to_s == val.to_s}
25
25
  end
26
26
 
27
27
  # swaps one element in the list with the other.
@@ -260,16 +260,16 @@ module ActiveScaffold::DataStructures
260
260
  # the association from the ActiveRecord class
261
261
  attr_reader :association
262
262
  def singular_association?
263
- self.association and [:has_one, :belongs_to].include? self.association.macro
263
+ self.association and !self.association.collection?
264
264
  end
265
265
  def plural_association?
266
- self.association and [:has_many, :has_and_belongs_to_many].include? self.association.macro
266
+ self.association and self.association.collection?
267
267
  end
268
268
  def through_association?
269
269
  self.association and self.association.options[:through]
270
270
  end
271
271
  def polymorphic_association?
272
- self.association and self.association.options.has_key? :polymorphic and self.association.options[:polymorphic]
272
+ self.association and self.association.options[:polymorphic]
273
273
  end
274
274
  def readonly_association?
275
275
  if self.association
@@ -324,14 +324,14 @@ module ActiveScaffold::DataStructures
324
324
  elsif polymorphic_association?
325
325
  [field, quoted_field(@active_record_class.connection.quote_column_name(@association.foreign_type))]
326
326
  elsif @association
327
- if self.association.macro == :belongs_to
327
+ if self.association.belongs_to?
328
328
  [field]
329
329
  else
330
330
  columns = []
331
331
  if active_record_class.columns_hash[count_column = "#{@association.name}_count"]
332
332
  columns << quoted_field(@active_record_class.connection.quote_column_name(count_column))
333
333
  end
334
- if @association.through_reflection.try(:macro) == :belongs_to
334
+ if @association.through_reflection.try(:belongs_to?)
335
335
  columns << quoted_field(@active_record_class.connection.quote_column_name(@association.through_reflection.foreign_key))
336
336
  end
337
337
  columns
@@ -350,7 +350,7 @@ module ActiveScaffold::DataStructures
350
350
  self.css_class = ''
351
351
  self.required = active_record_class.validators_on(self.name).any? do |val|
352
352
  !val.options[:if] && !val.options[:unless] && (ActiveModel::Validations::PresenceValidator === val ||
353
- (ActiveModel::Validations::InclusionValidator === val && !val.options[:allow_nil] && !val.options[:allow_blank])
353
+ (ActiveModel::Validations::InclusionValidator === val && !val.options[:allow_nil] && !val.options[:allow_blank] && !(@form_ui == :checkbox && [[true, false], [false, true]].include?(val.send(:delimiter))))
354
354
  )
355
355
  end
356
356
  self.sort = true
@@ -42,7 +42,7 @@ module ActiveScaffold::DataStructures
42
42
 
43
43
  def exclude(*args)
44
44
  # only remove columns from _inheritable. we never want to completely forget about a column.
45
- args.each { |a| @_inheritable.delete a }
45
+ args.each { |a| @_inheritable.delete a.to_sym }
46
46
  end
47
47
 
48
48
  # returns an array of columns with the provided names
@@ -72,4 +72,4 @@ module ActiveScaffold::DataStructures
72
72
  end
73
73
  end
74
74
  end
75
- end
75
+ end
@@ -119,7 +119,11 @@ module ActiveScaffold::DataStructures
119
119
  end
120
120
 
121
121
  def default_sorting
122
- association.options[:order]
122
+ if association.options[:order] # TODO remove when rails 3 compatibility is removed
123
+ association.options[:order]
124
+ elsif association.respond_to?(:scope) # rails 4
125
+ association.klass.class_eval(&association.scope).values[:order] if association.scope.is_a? Proc
126
+ end
123
127
  end
124
128
 
125
129
  def to_params
@@ -13,15 +13,17 @@ module ActiveScaffold::DataStructures
13
13
 
14
14
  def set_default_sorting(model)
15
15
  model_scope = model.send(:build_default_scope)
16
- order_clause = model_scope.arel.order_clauses.join(",") if model_scope
16
+ order_clause = model_scope.order_values.join(",") if model_scope
17
17
 
18
- # If an ORDER BY clause is found set default sorting according to it, else
19
18
  # fallback to setting primary key ordering
19
+ if model.column_names.include?(model.primary_key)
20
+ set(model.primary_key, 'ASC')
21
+ @sorting_by_primary_key = clause
22
+ end
23
+ # If an ORDER BY clause is found set default sorting according to it
20
24
  if order_clause
21
25
  set_sorting_from_order_clause(order_clause, model.table_name)
22
26
  @default_sorting = true
23
- else
24
- set(model.primary_key, 'ASC') if model.column_names.include?(model.primary_key)
25
27
  end
26
28
  end
27
29
 
@@ -69,6 +71,13 @@ module ActiveScaffold::DataStructures
69
71
  clause[1]
70
72
  end
71
73
 
74
+ SORTING_STAGES = Hash[%w(reset ASC DESC reset).each_cons(2).map{|a|a}].freeze
75
+ DEFAULT_SORTING_STAGES = Hash[%w(ASC DESC ASC).each_cons(2).map{|a|a}].freeze
76
+ def next_sorting_of(column, sorted_by_default)
77
+ stages = sorted_by_default ? DEFAULT_SORTING_STAGES : SORTING_STAGES
78
+ stages[direction_of(column)] || 'ASC'
79
+ end
80
+
72
81
  # checks whether any column is configured to sort by method (using a proc)
73
82
  def sorts_by_method?
74
83
  @clauses.any? { |sorting| sorting[0].sort.is_a? Hash and sorting[0].sort.has_key? :method }
@@ -102,6 +111,7 @@ module ActiveScaffold::DataStructures
102
111
  order << Array(sql).map {|column| "#{column} #{sort_direction}"}.join(', ')
103
112
  end
104
113
 
114
+ order << @sorting_by_primary_key if @sorting_by_primary_key # mandatory for postgres
105
115
  order unless order.empty?
106
116
  end
107
117
 
@@ -135,7 +145,7 @@ module ActiveScaffold::DataStructures
135
145
  order_clause.to_s.split(',').each do |criterion|
136
146
  unless criterion.blank?
137
147
  order_parts = extract_order_parts(criterion)
138
- add(order_parts[:column_name], order_parts[:direction]) unless different_table?(model_table_name, order_parts[:table_name])
148
+ add(order_parts[:column_name], order_parts[:direction]) unless different_table?(model_table_name, order_parts[:table_name]) || get_column(order_parts[:column_name]).nil?
139
149
  end
140
150
  end
141
151
  end
@@ -0,0 +1,30 @@
1
+ module ActiveScaffold
2
+ module DelayedSetup
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ def process(*)
8
+ self.class.config_active_scaffold_delayed
9
+ super
10
+ end
11
+
12
+ module ClassMethods
13
+ def active_scaffold(model_id = nil, &block)
14
+ @active_scaffold_delayed = proc{ super(model_id, &block) }
15
+ end
16
+
17
+ def config_active_scaffold_delayed
18
+ if @active_scaffold_delayed
19
+ block, @active_scaffold_delayed = @active_scaffold_delayed, nil
20
+ block.call
21
+ end
22
+ end
23
+
24
+ def active_scaffold_config
25
+ config_active_scaffold_delayed
26
+ super
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,4 +1,29 @@
1
1
  module ActiveScaffold
2
2
  class Engine < ::Rails::Engine
3
+ initializer "active_scaffold.action_controller" do |app|
4
+ ActiveSupport.on_load :action_controller do
5
+ include ActiveScaffold::Core
6
+ include ActiveScaffold::DelayedSetup if ActiveScaffold.delayed_setup
7
+ include ActiveScaffold::RespondsToParent
8
+ include ActiveScaffold::Helpers::ControllerHelpers
9
+ include ActiveScaffold::ActiveRecordPermissions::ModelUserAccess::Controller
10
+ end
11
+ end
12
+
13
+ initializer "active_scaffold.action_view" do |app|
14
+ ActiveSupport.on_load :action_view do
15
+ include ActiveScaffold::Helpers::ViewHelpers
16
+ end
17
+ end
18
+
19
+ initializer "active_scaffold.active_record" do |app|
20
+ ActiveSupport.on_load :active_record do
21
+ include ActiveScaffold::ActiveRecordPermissions::ModelUserAccess::Model
22
+ ActiveRecord::Associations::Association.send :include, ActiveScaffold::Tableless::Association
23
+ ActiveRecord::Associations::CollectionAssociation.send :include, ActiveScaffold::Tableless::CollectionAssociation
24
+ ActiveRecord::Associations::SingularAssociation.send :include, ActiveScaffold::Tableless::SingularAssociation
25
+ end
26
+ end
27
+
3
28
  end
4
29
  end
@@ -80,7 +80,7 @@ module ActionView::Helpers #:nodoc:
80
80
  if ActiveScaffold.js_framework == :prototype
81
81
  javascript_tag("new Ajax.Updater('#{id}', '#{url}', {method: 'get', evalScripts: true});")
82
82
  elsif ActiveScaffold.js_framework == :jquery
83
- javascript_tag("jQuery('##{id}').load('#{url}', function() { $(this).trigger('as:element_updated'); });")
83
+ javascript_tag("jQuery('##{id}').load('#{url}', function() { jQuery(this).trigger('as:element_updated'); });")
84
84
  end
85
85
  end
86
86
  end
@@ -1,33 +1,73 @@
1
1
  module ActiveScaffold
2
2
  module OuterJoins
3
- def outer_joins(*assocs)
4
- joins(outer_joins_sql(*assocs))
3
+ extend ActiveSupport::Concern
4
+ attr_accessor :outer_joins_values
5
+
6
+ if Rails::VERSION::MAJOR < 4
7
+ included do
8
+ const_get(:MULTI_VALUE_METHODS) << :outer_joins
9
+ end
10
+
11
+ def outer_joins(*args)
12
+ return self if args.compact.blank?
13
+
14
+ relation = clone
15
+
16
+ args.flatten!
17
+ relation.joins_values += [''] # HACK for using outer_joins in update_all/delete_all
18
+ relation.outer_joins_values += args
19
+
20
+ relation
21
+ end
22
+ else
23
+ def outer_joins_values
24
+ @values[:outer_joins] || []
25
+ end
26
+
27
+ def outer_joins_values=(values)
28
+ raise ImmutableRelation if @loaded
29
+ @values[:outer_joins] = values
30
+ end
31
+
32
+ def outer_joins(*args)
33
+ check_if_method_has_arguments!("outer_joins", args)
34
+ spawn.outer_joins!(*args.compact.flatten)
35
+ end
36
+
37
+ def outer_joins!(*args)
38
+ self.joins_values += [''] # HACK for using outer_joins in update_all/delete_all
39
+ self.outer_joins_values += args
40
+ self
41
+ end
5
42
  end
6
43
 
7
- private
8
- def outer_joins_sql(*assocs)
9
- assocs.collect do |assoc|
10
- if assoc.is_a? Array
11
- outer_joins_sql(*assoc)
12
- elsif assoc.is_a? Hash
13
- assoc.collect do |key, val|
14
- [left_outer_join_sql(key), klass.reflect_on_association(key).klass.outer_joins_sql(*val)]
44
+ if Rails.version < '4.1'
45
+ def build_arel
46
+ unless outer_joins_values.empty?
47
+ relation = self.except(:outer_joins)
48
+ join_dependency = ActiveRecord::Associations::JoinDependency.new(@klass, outer_joins_values, [])
49
+ join_dependency.join_associations.each do |association|
50
+ relation = association.join_relation(relation)
15
51
  end
16
- elsif assoc.is_a? Symbol
17
- left_outer_join_sql(assoc)
18
- elsif assoc
19
- assoc
52
+ relation.build_arel
53
+ else
54
+ super
20
55
  end
21
- end.flatten.compact
22
- end
23
-
24
- def left_outer_join_sql(association_name)
25
- t = ActiveRecord::Associations::JoinDependency.new(klass, association_name, []).join_associations.first.join_relation(klass).arel
26
- t.joins(t)
56
+ end
57
+ else
58
+ def build_arel
59
+ unless outer_joins_values.empty?
60
+ relation = self.except(:outer_joins)
61
+ relation.joins! ActiveRecord::Associations::JoinDependency.new(@klass, outer_joins_values, [])
62
+ relation.build_arel
63
+ else
64
+ super
65
+ end
66
+ end
27
67
  end
28
68
  end
29
69
  end
30
70
  ActiveRecord::Relation.send :include, ActiveScaffold::OuterJoins
31
71
  module ActiveRecord::Querying
32
- delegate :outer_joins, :outer_joins_sql, :to => :scoped
72
+ delegate :outer_joins, :to => Rails::VERSION::MAJOR < 4 ? :scoped : :all
33
73
  end