active_scaffold 3.4.17 → 3.4.18

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 (183) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +12 -1
  3. data/README.md +8 -4
  4. data/app/assets/javascripts/jquery/active_scaffold.js +82 -67
  5. data/app/assets/stylesheets/active_scaffold.scss +1 -1
  6. data/app/assets/stylesheets/active_scaffold_colors.scss +1 -1
  7. data/app/assets/stylesheets/blue-theme.css +1 -1
  8. data/app/views/active_scaffold_overrides/_form_association.html.erb +3 -3
  9. data/app/views/active_scaffold_overrides/_form_association_record.html.erb +3 -3
  10. data/app/views/active_scaffold_overrides/_show_columns.html.erb +1 -1
  11. data/lib/active_scaffold.rb +16 -16
  12. data/lib/active_scaffold/actions/common_search.rb +13 -11
  13. data/lib/active_scaffold/actions/core.rb +85 -78
  14. data/lib/active_scaffold/actions/create.rb +29 -28
  15. data/lib/active_scaffold/actions/delete.rb +17 -17
  16. data/lib/active_scaffold/actions/field_search.rb +18 -19
  17. data/lib/active_scaffold/actions/list.rb +30 -22
  18. data/lib/active_scaffold/actions/mark.rb +1 -1
  19. data/lib/active_scaffold/actions/nested.rb +78 -65
  20. data/lib/active_scaffold/actions/search.rb +13 -10
  21. data/lib/active_scaffold/actions/show.rb +10 -6
  22. data/lib/active_scaffold/actions/subform.rb +1 -2
  23. data/lib/active_scaffold/actions/update.rb +39 -31
  24. data/lib/active_scaffold/active_record_permissions.rb +14 -15
  25. data/lib/active_scaffold/attribute_params.rb +42 -43
  26. data/lib/active_scaffold/bridges.rb +22 -12
  27. data/lib/active_scaffold/bridges/ancestry.rb +1 -1
  28. data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +6 -6
  29. data/lib/active_scaffold/bridges/bitfields.rb +1 -1
  30. data/lib/active_scaffold/bridges/bitfields/bitfields_bridge.rb +12 -13
  31. data/lib/active_scaffold/bridges/calendar_date_select.rb +5 -5
  32. data/lib/active_scaffold/bridges/calendar_date_select/as_cds_bridge.rb +17 -20
  33. data/lib/active_scaffold/bridges/cancan.rb +1 -1
  34. data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +8 -9
  35. data/lib/active_scaffold/bridges/carrierwave.rb +4 -4
  36. data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge.rb +9 -8
  37. data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +11 -10
  38. data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +7 -6
  39. data/lib/active_scaffold/bridges/chosen.rb +1 -1
  40. data/lib/active_scaffold/bridges/chosen/helpers.rb +4 -4
  41. data/lib/active_scaffold/bridges/country_helper.rb +1 -1
  42. data/lib/active_scaffold/bridges/country_helper/country_helper_bridge.rb +259 -260
  43. data/lib/active_scaffold/bridges/date_picker.rb +2 -2
  44. data/lib/active_scaffold/bridges/date_picker/ext.rb +9 -11
  45. data/lib/active_scaffold/bridges/date_picker/helper.rb +61 -67
  46. data/lib/active_scaffold/bridges/dragonfly.rb +4 -4
  47. data/lib/active_scaffold/bridges/dragonfly/dragonfly_bridge.rb +9 -8
  48. data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +11 -10
  49. data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +6 -5
  50. data/lib/active_scaffold/bridges/file_column.rb +5 -5
  51. data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +20 -23
  52. data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +20 -23
  53. data/lib/active_scaffold/bridges/file_column/form_ui.rb +13 -14
  54. data/lib/active_scaffold/bridges/file_column/list_ui.rb +7 -8
  55. data/lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb +18 -22
  56. data/lib/active_scaffold/bridges/file_column/test/mock_model.rb +5 -4
  57. data/lib/active_scaffold/bridges/file_column/test/test_helper.rb +2 -10
  58. data/lib/active_scaffold/bridges/paper_trail.rb +7 -5
  59. data/lib/active_scaffold/bridges/paper_trail/paper_trail_bridge.rb +4 -3
  60. data/lib/active_scaffold/bridges/paperclip.rb +5 -5
  61. data/lib/active_scaffold/bridges/paperclip/form_ui.rb +11 -10
  62. data/lib/active_scaffold/bridges/paperclip/list_ui.rb +6 -5
  63. data/lib/active_scaffold/bridges/paperclip/paperclip_bridge.rb +10 -9
  64. data/lib/active_scaffold/bridges/record_select.rb +1 -1
  65. data/lib/active_scaffold/bridges/record_select/helpers.rb +28 -28
  66. data/lib/active_scaffold/bridges/semantic_attributes.rb +1 -1
  67. data/lib/active_scaffold/bridges/semantic_attributes/column.rb +1 -1
  68. data/lib/active_scaffold/bridges/shared/date_bridge.rb +58 -52
  69. data/lib/active_scaffold/bridges/tiny_mce.rb +2 -2
  70. data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +3 -3
  71. data/lib/active_scaffold/config/base.rb +9 -10
  72. data/lib/active_scaffold/config/core.rb +24 -29
  73. data/lib/active_scaffold/config/create.rb +0 -1
  74. data/lib/active_scaffold/config/field_search.rb +8 -10
  75. data/lib/active_scaffold/config/form.rb +5 -5
  76. data/lib/active_scaffold/config/list.rb +21 -20
  77. data/lib/active_scaffold/config/mark.rb +3 -3
  78. data/lib/active_scaffold/config/nested.rb +11 -10
  79. data/lib/active_scaffold/config/search.rb +2 -3
  80. data/lib/active_scaffold/config/show.rb +1 -1
  81. data/lib/active_scaffold/config/update.rb +1 -2
  82. data/lib/active_scaffold/configurable.rb +9 -11
  83. data/lib/active_scaffold/constraints.rb +9 -8
  84. data/lib/active_scaffold/core.rb +72 -84
  85. data/lib/active_scaffold/data_structures/action_columns.rb +26 -25
  86. data/lib/active_scaffold/data_structures/action_link.rb +43 -43
  87. data/lib/active_scaffold/data_structures/action_links.rb +17 -15
  88. data/lib/active_scaffold/data_structures/actions.rb +5 -5
  89. data/lib/active_scaffold/data_structures/bridge.rb +6 -3
  90. data/lib/active_scaffold/data_structures/column.rb +110 -89
  91. data/lib/active_scaffold/data_structures/columns.rb +3 -3
  92. data/lib/active_scaffold/data_structures/error_message.rb +4 -6
  93. data/lib/active_scaffold/data_structures/nested_info.rb +43 -48
  94. data/lib/active_scaffold/data_structures/set.rb +7 -8
  95. data/lib/active_scaffold/data_structures/sorting.rb +38 -33
  96. data/lib/active_scaffold/delayed_setup.rb +5 -6
  97. data/lib/active_scaffold/engine.rb +4 -4
  98. data/lib/active_scaffold/extensions/action_controller_rendering.rb +3 -4
  99. data/lib/active_scaffold/extensions/action_controller_rescueing.rb +1 -1
  100. data/lib/active_scaffold/extensions/action_view_rendering.rb +5 -6
  101. data/lib/active_scaffold/extensions/left_outer_joins.rb +11 -11
  102. data/lib/active_scaffold/extensions/localize.rb +1 -1
  103. data/lib/active_scaffold/extensions/name_option_for_datetime.rb +1 -1
  104. data/lib/active_scaffold/extensions/paginator_extensions.rb +2 -5
  105. data/lib/active_scaffold/extensions/reverse_associations.rb +13 -13
  106. data/lib/active_scaffold/extensions/routing_mapper.rb +9 -9
  107. data/lib/active_scaffold/extensions/unsaved_associated.rb +9 -9
  108. data/lib/active_scaffold/finder.rb +90 -93
  109. data/lib/active_scaffold/helpers/association_helpers.rb +5 -5
  110. data/lib/active_scaffold/helpers/controller_helpers.rb +22 -19
  111. data/lib/active_scaffold/helpers/form_column_helpers.rb +115 -105
  112. data/lib/active_scaffold/helpers/human_condition_helpers.rb +62 -35
  113. data/lib/active_scaffold/helpers/id_helpers.rb +6 -6
  114. data/lib/active_scaffold/helpers/list_column_helpers.rb +89 -94
  115. data/lib/active_scaffold/helpers/pagination_helpers.rb +9 -9
  116. data/lib/active_scaffold/helpers/search_column_helpers.rb +47 -44
  117. data/lib/active_scaffold/helpers/show_column_helpers.rb +2 -2
  118. data/lib/active_scaffold/helpers/view_helpers.rb +86 -91
  119. data/lib/active_scaffold/marked_model.rb +10 -10
  120. data/lib/active_scaffold/paginator.rb +30 -34
  121. data/lib/active_scaffold/responds_to_parent.rb +27 -28
  122. data/lib/active_scaffold/tableless.rb +20 -15
  123. data/lib/active_scaffold/version.rb +1 -1
  124. data/lib/generators/active_scaffold/active_scaffold_generator.rb +8 -8
  125. data/lib/generators/active_scaffold_controller/active_scaffold_controller_generator.rb +9 -9
  126. data/shoulda_macros/macros.rb +27 -22
  127. data/test/bridges/bridge_test.rb +38 -29
  128. data/test/bridges/date_picker_test.rb +1 -1
  129. data/test/bridges/paper_trail_test.rb +17 -0
  130. data/test/bridges/paperclip_test.rb +3 -2
  131. data/test/bridges/tiny_mce_test.rb +5 -2
  132. data/test/company.rb +25 -30
  133. data/test/config/base_test.rb +1 -1
  134. data/test/config/core_test.rb +9 -9
  135. data/test/config/create_test.rb +14 -8
  136. data/test/config/delete_test.rb +4 -4
  137. data/test/config/field_search_test.rb +6 -6
  138. data/test/config/list_test.rb +16 -16
  139. data/test/config/nested_test.rb +4 -4
  140. data/test/config/search_test.rb +8 -8
  141. data/test/config/show_test.rb +6 -6
  142. data/test/config/subform_test.rb +1 -1
  143. data/test/config/update_test.rb +5 -5
  144. data/test/const_mocker.rb +4 -4
  145. data/test/data_structures/action_columns_test.rb +4 -5
  146. data/test/data_structures/action_link_test.rb +1 -0
  147. data/test/data_structures/action_links_test.rb +5 -5
  148. data/test/data_structures/column_test.rb +9 -9
  149. data/test/data_structures/columns_test.rb +2 -2
  150. data/test/data_structures/error_message_test.rb +4 -5
  151. data/test/data_structures/set_test.rb +1 -2
  152. data/test/data_structures/sorting_test.rb +10 -10
  153. data/test/data_structures/validation_reflection_test.rb +8 -0
  154. data/test/extensions/routing_mapper_test.rb +2 -2
  155. data/test/helpers/list_column_helpers_test.rb +3 -2
  156. data/test/helpers/pagination_helpers_test.rb +5 -4
  157. data/test/helpers/search_column_helpers_test.rb +1 -1
  158. data/test/misc/active_record_permissions_test.rb +63 -50
  159. data/test/misc/attribute_params_test.rb +28 -26
  160. data/test/misc/calculation_test.rb +10 -3
  161. data/test/misc/configurable_test.rb +12 -13
  162. data/test/misc/constraints_test.rb +6 -6
  163. data/test/misc/convert_numbers_format_test.rb +7 -6
  164. data/test/misc/finder_test.rb +17 -12
  165. data/test/misc/lang_test.rb +3 -4
  166. data/test/misc/tableless_test.rb +2 -3
  167. data/test/mock_app/app/controllers/addresses_controller.rb +1 -1
  168. data/test/mock_app/app/controllers/buildings_controller.rb +1 -1
  169. data/test/mock_app/app/controllers/cars_controller.rb +1 -1
  170. data/test/mock_app/app/controllers/contacts_controller.rb +1 -1
  171. data/test/mock_app/app/controllers/people_controller.rb +1 -1
  172. data/test/mock_app/app/models/file_model.rb +2 -2
  173. data/test/mock_app/app/models/person.rb +1 -1
  174. data/test/mock_app/config/application.rb +3 -3
  175. data/test/mock_app/config/boot.rb +1 -1
  176. data/test/mock_app/config/environment.rb +1 -0
  177. data/test/mock_app/config/environments/development.rb +0 -1
  178. data/test/mock_app/config/environments/production.rb +1 -1
  179. data/test/mock_app/db/schema.rb +14 -15
  180. data/test/model_stub.rb +13 -16
  181. data/test/run_all.rb +5 -7
  182. data/test/test_helper.rb +12 -9
  183. metadata +19 -3
@@ -10,10 +10,10 @@ module ActiveScaffold::DataStructures
10
10
  # Whether to enable inplace editing for this column. Currently works for text columns, in the List.
11
11
  attr_reader :inplace_edit
12
12
  def inplace_edit=(value)
13
- self.clear_link if value
13
+ clear_link if value
14
14
  @inplace_edit = value
15
15
  end
16
-
16
+
17
17
  attr_accessor :inplace_edit_update
18
18
 
19
19
  # Whether this column set is collapsed by default in contexts where collapsing is supported
@@ -21,10 +21,10 @@ module ActiveScaffold::DataStructures
21
21
 
22
22
  # Whether to enable add_existing for this column
23
23
  attr_accessor :allow_add_existing
24
-
24
+
25
25
  # What columns load from main table
26
26
  attr_accessor :select_columns
27
-
27
+
28
28
  # Any extra parameters this particular column uses. This is for create/update purposes.
29
29
  def params
30
30
  # lazy initialize
@@ -63,9 +63,9 @@ module ActiveScaffold::DataStructures
63
63
  def required?
64
64
  @required
65
65
  end
66
-
66
+
67
67
  attr_reader :update_columns
68
-
68
+
69
69
  # update dependent columns after value change in form
70
70
  # update_columns = :name
71
71
  # update_columns = [:name, :age]
@@ -92,7 +92,7 @@ module ActiveScaffold::DataStructures
92
92
  end
93
93
 
94
94
  def sort
95
- self.initialize_sort if @sort === true
95
+ initialize_sort if @sort == true
96
96
  @sort
97
97
  end
98
98
 
@@ -112,9 +112,7 @@ module ActiveScaffold::DataStructures
112
112
  self.list_method = nil if @list_ui.nil? && value != @form_ui
113
113
  @form_ui = value
114
114
  end
115
- def form_ui
116
- @form_ui
117
- end
115
+ attr_reader :form_ui
118
116
 
119
117
  def list_ui=(value)
120
118
  self.list_method = nil if value != @list_ui
@@ -141,13 +139,13 @@ module ActiveScaffold::DataStructures
141
139
  @link
142
140
  end
143
141
 
144
- # associate an action_link with this column
142
+ # associate an action_link with this column
145
143
  def set_link(action, options = {})
146
144
  if action.is_a?(ActiveScaffold::DataStructures::ActionLink) || (action.is_a? Proc)
147
145
  @link = action
148
146
  else
149
- options[:label] ||= self.label
150
- options[:position] ||= :after unless options.has_key?(:position)
147
+ options[:label] ||= label
148
+ options[:position] ||= :after unless options.key?(:position)
151
149
  options[:type] ||= :member
152
150
  @link = ActiveScaffold::DataStructures::ActionLink.new(action, options)
153
151
  end
@@ -169,14 +167,14 @@ module ActiveScaffold::DataStructures
169
167
 
170
168
  # get whether to run a calculation on this column
171
169
  def calculation?
172
- !(@calculate == false or @calculate.nil?)
170
+ !(@calculate == false || @calculate.nil?)
173
171
  end
174
172
 
175
173
  # a collection of associations to pre-load when finding the records on a page
176
174
  attr_reader :includes
177
175
  def includes=(value)
178
176
  @includes = case value
179
- when Array then value
177
+ when Array then value
180
178
  else value ? [value] : value # not convert nil to [nil]
181
179
  end
182
180
  end
@@ -188,7 +186,7 @@ module ActiveScaffold::DataStructures
188
186
 
189
187
  def search_joins=(value)
190
188
  @search_joins = case value
191
- when Array then value
189
+ when Array then value
192
190
  else [value] # automatically convert to an array
193
191
  end
194
192
  end
@@ -201,18 +199,21 @@ module ActiveScaffold::DataStructures
201
199
  # search = "CONCAT(a, b)" define your own sql for searching. this should be the "left-side" of a WHERE condition. the operator and value will be supplied by ActiveScaffold.
202
200
  # search = [:a, :b] searches in both fields
203
201
  def search_sql=(value)
204
- @search_sql = if value
205
- (value == true || value.is_a?(Proc)) ? value : Array(value)
206
- else
207
- value
208
- end
202
+ @search_sql =
203
+ if value
204
+ (value == true || value.is_a?(Proc)) ? value : Array(value)
205
+ else
206
+ value
207
+ end
209
208
  end
209
+
210
210
  def search_sql
211
- self.initialize_search_sql if @search_sql === true
211
+ initialize_search_sql if @search_sql == true
212
212
  @search_sql
213
213
  end
214
+
214
215
  def searchable?
215
- !!search_sql
216
+ search_sql.present?
216
217
  end
217
218
 
218
219
  # to modify the default order of columns
@@ -236,17 +237,16 @@ module ActiveScaffold::DataStructures
236
237
  @@show_blank_record = true
237
238
  attr_writer :show_blank_record
238
239
  def show_blank_record?(associated)
239
- if @show_blank_record
240
- return false unless self.association.klass.authorized_for?(:crud_type => :create) and not self.association.options[:readonly]
241
- self.plural_association? or (self.singular_association? and associated.blank?)
242
- end
240
+ return false unless @show_blank_record
241
+ return false unless association.klass.authorized_for?(:crud_type => :create) && !association.options[:readonly]
242
+ self.plural_association? || (self.singular_association? && associated.blank?)
243
243
  end
244
244
 
245
245
  # methods for automatic links in singular association columns
246
246
  cattr_accessor :actions_for_association_links
247
247
  @@actions_for_association_links = [:new, :edit, :show]
248
248
  attr_accessor :actions_for_association_links
249
-
249
+
250
250
  cattr_accessor :association_form_ui
251
251
  @@association_form_ui = nil
252
252
 
@@ -260,24 +260,27 @@ 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 !self.association.collection?
263
+ association && !association.collection?
264
264
  end
265
+
265
266
  def plural_association?
266
- self.association and self.association.collection?
267
+ association && association.collection?
267
268
  end
269
+
268
270
  def through_association?
269
- self.association and self.association.options[:through]
271
+ association && association.options[:through]
270
272
  end
273
+
271
274
  def polymorphic_association?
272
- self.association and self.association.options[:polymorphic]
275
+ association && association.options[:polymorphic]
273
276
  end
277
+
274
278
  def readonly_association?
275
- if self.association
276
- if self.association.options.has_key? :readonly
277
- self.association.options[:readonly]
278
- else
279
- self.through_association?
280
- end
279
+ return false unless association
280
+ if association.options.key? :readonly
281
+ association.options[:readonly]
282
+ else
283
+ self.through_association?
281
284
  end
282
285
  end
283
286
 
@@ -285,7 +288,7 @@ module ActiveScaffold::DataStructures
285
288
  def virtual?
286
289
  column.nil? && association.nil?
287
290
  end
288
-
291
+
289
292
  attr_writer :number
290
293
  def number?
291
294
  @number
@@ -298,11 +301,11 @@ module ActiveScaffold::DataStructures
298
301
  # this is so that array.delete and array.include?, etc., will work by column name
299
302
  def ==(other) #:nodoc:
300
303
  # another column
301
- if other.respond_to? :name and other.class == self.class
302
- self.name == other.name.to_sym
304
+ if other.respond_to?(:name) && other.class == self.class
305
+ name == other.name.to_sym
303
306
  # a string or symbol
304
307
  elsif other.respond_to? :to_sym
305
- self.name == other.to_sym rescue false # catch "interning empty string"
308
+ name == other.to_sym rescue false # catch "interning empty string"
306
309
  # unknown
307
310
  else
308
311
  self.eql? other
@@ -323,25 +326,8 @@ module ActiveScaffold::DataStructures
323
326
  @show_blank_record = self.class.show_blank_record
324
327
  @send_form_on_update_column = self.class.send_form_on_update_column
325
328
  @actions_for_association_links = self.class.actions_for_association_links.clone if @association
326
- @select_columns = if @association.nil? && @column
327
- [field]
328
- elsif polymorphic_association?
329
- [field, quoted_field(@active_record_class.connection.quote_column_name(@association.foreign_type))]
330
- elsif @association
331
- if self.association.belongs_to?
332
- [field]
333
- else
334
- columns = []
335
- if active_record_class.columns_hash[count_column = "#{@association.name}_count"]
336
- columns << quoted_field(@active_record_class.connection.quote_column_name(count_column))
337
- end
338
- if @association.through_reflection.try(:belongs_to?)
339
- columns << quoted_field(@active_record_class.connection.quote_column_name(@association.through_reflection.foreign_key))
340
- end
341
- columns
342
- end
343
- end
344
-
329
+ @select_columns = default_select_columns
330
+
345
331
  @text = @column.nil? || [:string, :text].include?(@column.type)
346
332
  if @column
347
333
  @form_ui = case @column.type
@@ -356,23 +342,21 @@ module ActiveScaffold::DataStructures
356
342
  end
357
343
  @allow_add_existing = true
358
344
  @form_ui = self.class.association_form_ui if @association && self.class.association_form_ui
359
-
345
+
346
+ if association && !polymorphic_association?
347
+ self.includes = [association.name]
348
+ self.search_joins = includes.clone
349
+ end
350
+
360
351
  # default all the configurable variables
361
352
  self.css_class = ''
362
353
  self.required = active_record_class.validators_on(self.name).any? do |val|
363
- !val.options[:if] && !val.options[:unless] && (ActiveModel::Validations::PresenceValidator === val ||
364
- (ActiveModel::Validations::InclusionValidator === val && !val.options[:allow_nil] && !val.options[:allow_blank] && !(@form_ui == :checkbox && [[true, false], [false, true]].include?(val.send(:delimiter))))
365
- )
354
+ validator_force_required?(val)
366
355
  end
367
356
  self.sort = true
368
357
  self.search_sql = true
369
-
370
- @weight = estimate_weight
371
358
 
372
- if association && !polymorphic_association?
373
- self.includes = [association.name]
374
- self.search_joins = self.includes.clone
375
- end
359
+ @weight = estimate_weight
376
360
  end
377
361
 
378
362
  # just the field (not table.field)
@@ -381,16 +365,16 @@ module ActiveScaffold::DataStructures
381
365
  @field_name ||= column ? @active_record_class.connection.quote_column_name(column.name) : association.foreign_key
382
366
  end
383
367
 
384
- def <=>(other_column)
385
- order_weight = self.weight <=> other_column.weight
386
- order_weight != 0 ? order_weight : self.name.to_s <=> other_column.name.to_s
368
+ def <=>(other)
369
+ order_weight = weight <=> other.weight
370
+ order_weight != 0 ? order_weight : name.to_s <=> other.name.to_s
387
371
  end
388
372
 
389
373
  def number_to_native(value)
390
374
  return value if value.blank? || !value.is_a?(String)
391
375
  native = '.' # native ruby separator
392
376
  format = {:separator => '', :delimiter => ''}.merge! I18n.t('number.format', :default => {})
393
- specific = case self.options[:format]
377
+ specific = case options[:format]
394
378
  when :currency
395
379
  I18n.t('number.currency.format', :default => nil)
396
380
  when :size
@@ -399,10 +383,10 @@ module ActiveScaffold::DataStructures
399
383
  I18n.t('number.percentage.format', :default => nil)
400
384
  end
401
385
  format.merge! specific unless specific.nil?
402
- unless format[:separator].blank? || !value.include?(format[:separator]) && value.include?(native) && (format[:delimiter] != native || value !~ /\.\d{3}$/)
403
- value.gsub(/[^0-9\-#{format[:separator]}]/, '').gsub(format[:separator], native)
404
- else
386
+ if format[:separator].blank? || !value.include?(format[:separator]) && value.include?(native) && (format[:delimiter] != native || value !~ /\.\d{3}$/)
405
387
  value
388
+ else
389
+ value.gsub(/[^0-9\-#{format[:separator]}]/, '').gsub(format[:separator], native)
406
390
  end
407
391
  end
408
392
 
@@ -419,6 +403,42 @@ module ActiveScaffold::DataStructures
419
403
 
420
404
  protected
421
405
 
406
+ def validator_force_required?(val)
407
+ return false if val.options[:if] || val.options[:unless]
408
+ case val
409
+ when ActiveModel::Validations::PresenceValidator
410
+ true
411
+ when ActiveModel::Validations::InclusionValidator
412
+ !val.options[:allow_nil] && !val.options[:allow_blank] &&
413
+ !inclusion_validator_for_checkbox?(val)
414
+ end
415
+ end
416
+
417
+ def inclusion_validator_for_checkbox?(val)
418
+ @form_ui == :checkbox && [[true, false], [false, true]].include?(val.options[:with] || val.options[:within])
419
+ end
420
+
421
+ def default_select_columns
422
+ if association.nil? && column
423
+ [field]
424
+ elsif polymorphic_association?
425
+ [field, quoted_field(@active_record_class.connection.quote_column_name(association.foreign_type))]
426
+ elsif association
427
+ if association.belongs_to?
428
+ [field]
429
+ else
430
+ columns = []
431
+ if active_record_class.columns_hash[count_column = "#{association.name}_count"]
432
+ columns << quoted_field(@active_record_class.connection.quote_column_name(count_column))
433
+ end
434
+ if association.through_reflection.try(:belongs_to?)
435
+ columns << quoted_field(@active_record_class.connection.quote_column_name(association.through_reflection.foreign_key))
436
+ end
437
+ columns
438
+ end
439
+ end
440
+ end
441
+
422
442
  def quoted_field(name)
423
443
  [@active_record_class.quoted_table_name, name].join('.')
424
444
  end
@@ -429,34 +449,35 @@ module ActiveScaffold::DataStructures
429
449
  self.sort = false
430
450
  else
431
451
  if column && !@tableless
432
- self.sort = {:sql => self.field}
452
+ self.sort = {:sql => field}
433
453
  else
434
454
  self.sort = false
435
455
  end
436
456
  end
437
457
  end
438
-
458
+
439
459
  def initialize_search_sql
440
- self.search_sql = unless self.virtual?
441
- if association.nil?
442
- self.field.to_s unless @tableless
443
- elsif !self.polymorphic_association?
444
- [association.klass.quoted_table_name, association.klass.quoted_primary_key].join('.') unless association.klass < ActiveScaffold::Tableless
460
+ self.search_sql =
461
+ unless self.virtual?
462
+ if association.nil?
463
+ field.to_s unless @tableless
464
+ elsif !self.polymorphic_association?
465
+ [association.klass.quoted_table_name, association.klass.quoted_primary_key].join('.') unless association.klass < ActiveScaffold::Tableless
466
+ end
445
467
  end
446
- end
447
468
  end
448
469
 
449
470
  # the table name from the ActiveRecord class
450
471
  attr_reader :table
451
-
472
+
452
473
  def estimate_weight
453
474
  if singular_association?
454
475
  400
455
476
  elsif plural_association?
456
477
  500
457
- elsif [:created_at, :updated_at].include?(self.name)
478
+ elsif [:created_at, :updated_at].include?(name)
458
479
  600
459
- elsif [:name, :label, :title].include?(self.name)
480
+ elsif [:name, :label, :title].include?(name)
460
481
  100
461
482
  elsif required?
462
483
  200
@@ -24,14 +24,14 @@ module ActiveScaffold::DataStructures
24
24
  @_inheritable = []
25
25
  @set = []
26
26
 
27
- self.add *args
27
+ add *args
28
28
  end
29
29
 
30
30
  # the way to add columns to the set. this is primarily useful for virtual columns.
31
31
  # note that this also makes columns inheritable
32
32
  def add(*args)
33
33
  args.flatten! # allow [] as a param
34
- args = args.collect{ |a| a.to_sym }
34
+ args = args.collect(&:to_sym)
35
35
 
36
36
  # make the columns inheritable
37
37
  @_inheritable.concat(args)
@@ -59,7 +59,7 @@ module ActiveScaffold::DataStructures
59
59
  alias_method :[], :find_by_name
60
60
 
61
61
  def each
62
- @set.each {|i| yield i }
62
+ @set.each { |i| yield i }
63
63
  end
64
64
 
65
65
  def _inheritable
@@ -6,19 +6,17 @@ module ActiveScaffold::DataStructures
6
6
  end
7
7
 
8
8
  def public_attributes
9
- { :error => @error }
9
+ {:error => @error}
10
10
  end
11
11
 
12
12
  def to_xml
13
- public_attributes.to_xml(:root => "errors")
13
+ public_attributes.to_xml(:root => 'errors')
14
14
  end
15
15
 
16
- def to_yaml
17
- public_attributes.to_yaml
18
- end
16
+ delegate :to_yaml, :to => :public_attributes
19
17
 
20
18
  def to_s
21
19
  @error
22
20
  end
23
21
  end
24
- end
22
+ end
@@ -1,37 +1,34 @@
1
1
  module ActiveScaffold::DataStructures
2
2
  class NestedInfo
3
3
  def self.get(model, params)
4
- nested_info = {}
5
- begin
6
- unless params[:association].nil?
7
- ActiveScaffold::DataStructures::NestedInfoAssociation.new(model, params)
8
- else
9
- ActiveScaffold::DataStructures::NestedInfoScope.new(model, params)
10
- end
11
- rescue ActiveScaffold::ControllerNotFound
12
- nil
4
+ if params[:association].nil?
5
+ ActiveScaffold::DataStructures::NestedInfoScope.new(model, params)
6
+ else
7
+ ActiveScaffold::DataStructures::NestedInfoAssociation.new(model, params)
13
8
  end
9
+ rescue ActiveScaffold::ControllerNotFound
10
+ nil
14
11
  end
15
-
12
+
16
13
  attr_accessor :association, :child_association, :parent_model, :parent_scaffold, :parent_id, :param_name, :constrained_fields, :scope
17
-
14
+
18
15
  def initialize(model, params)
19
16
  @parent_scaffold = "#{params[:parent_scaffold].to_s.camelize}Controller".constantize
20
17
  @parent_model = @parent_scaffold.active_scaffold_config.model
21
18
  end
22
-
19
+
23
20
  def to_params
24
21
  {:parent_scaffold => parent_scaffold.controller_path}
25
22
  end
26
-
23
+
27
24
  def new_instance?
28
25
  result = @new_instance.nil?
29
26
  @new_instance = false
30
27
  result
31
28
  end
32
-
29
+
33
30
  def habtm?
34
- false
31
+ false
35
32
  end
36
33
 
37
34
  def has_many?
@@ -61,7 +58,7 @@ module ActiveScaffold::DataStructures
61
58
  def through_association?
62
59
  false
63
60
  end
64
-
61
+
65
62
  def readonly?
66
63
  false
67
64
  end
@@ -70,7 +67,7 @@ module ActiveScaffold::DataStructures
70
67
  false
71
68
  end
72
69
  end
73
-
70
+
74
71
  class NestedInfoAssociation < NestedInfo
75
72
  def initialize(model, params)
76
73
  super
@@ -79,88 +76,86 @@ module ActiveScaffold::DataStructures
79
76
  @parent_id = params[@param_name]
80
77
  iterate_model_associations(model)
81
78
  end
82
-
83
- def name
84
- self.association.name
85
- end
86
-
79
+
80
+ delegate :name, :to => :association
81
+
87
82
  def has_many?
88
- association.macro == :has_many
83
+ association.macro == :has_many
89
84
  end
90
-
85
+
91
86
  def habtm?
92
- association.macro == :has_and_belongs_to_many
93
- end
94
-
95
- def belongs_to?
96
- association.belongs_to?
87
+ association.macro == :has_and_belongs_to_many
97
88
  end
98
89
 
90
+ delegate :belongs_to?, :to => :association
91
+
99
92
  def has_one?
100
93
  association.macro == :has_one
101
94
  end
102
-
95
+
103
96
  # A through association with has_one or has_many as source association
104
- # create cannot be called in such through association, unless create columns include through reflection of reverse association
97
+ # create cannot be called in nested through associations, and not-nested through associations
98
+ # unless create columns include through reflection of reverse association
105
99
  # e.g. customer -> networks -> firewall, reverse is firewall -> network -> customer,
106
100
  # firewall can be created if create columns include network
107
101
  def readonly_through_association?(columns)
108
- through_association? && association.source_reflection.macro != :belongs_to && (
102
+ return false unless through_association?
103
+ return true if association.through_reflection.options[:through]
104
+ association.source_reflection.macro != :belongs_to && (
109
105
  !child_association || !columns.include?(child_association.through_reflection.name)
110
106
  )
111
107
  end
112
-
108
+
113
109
  def through_association?
114
110
  association.options[:through]
115
111
  end
116
-
112
+
117
113
  def readonly?
118
114
  association.options[:readonly]
119
115
  end
120
116
 
121
117
  def sorted?
122
- association.options.has_key? :order
118
+ association.options.key? :order
123
119
  end
124
120
 
125
121
  def default_sorting
126
- if association.options[:order] # TODO remove when rails 3 compatibility is removed
122
+ if association.options[:order] # TODO: remove when rails 3 compatibility is removed
127
123
  association.options[:order]
128
124
  elsif association.respond_to?(:scope) # rails 4
129
125
  association.klass.class_eval(&association.scope).values[:order] if association.scope.is_a? Proc
130
126
  end
131
127
  end
132
-
128
+
133
129
  def to_params
134
130
  super.merge(:association => @association.name, :assoc_id => parent_id)
135
131
  end
136
-
132
+
137
133
  protected
138
-
134
+
139
135
  def iterate_model_associations(model)
140
136
  @constrained_fields = []
141
137
  constrained_fields << association.foreign_key.to_sym unless association.belongs_to?
142
- if reverse = association.reverse(model)
143
- @child_association = model.reflect_on_association(reverse)
144
- constrained_fields << @child_association.name unless @child_association == association
145
- end
138
+ return if (reverse = association.reverse(model)).nil?
139
+ @child_association = model.reflect_on_association(reverse)
140
+ constrained_fields << @child_association.name unless @child_association == association
146
141
  end
147
142
  end
148
-
143
+
149
144
  class NestedInfoScope < NestedInfo
150
145
  def initialize(model, params)
151
146
  super
152
147
  @scope = params[:named_scope].to_sym
153
148
  @param_name = parent_model.name.foreign_key.to_sym
154
149
  @parent_id = params[@param_name]
155
- @constrained_fields = []
150
+ @constrained_fields = []
156
151
  end
157
-
152
+
158
153
  def to_params
159
154
  super.merge(:named_scope => @scope)
160
155
  end
161
-
156
+
162
157
  def name
163
- self.scope
158
+ scope
164
159
  end
165
160
  end
166
161
  end