active_scaffold 3.5.5 → 3.6.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +18 -2
  3. data/README.md +17 -7
  4. data/app/assets/javascripts/jquery/active_scaffold.js +28 -2
  5. data/app/views/active_scaffold_overrides/_base_form.html.erb +2 -2
  6. data/app/views/active_scaffold_overrides/_form.html.erb +1 -1
  7. data/app/views/active_scaffold_overrides/_form_association_footer.html.erb +3 -2
  8. data/app/views/active_scaffold_overrides/_form_association_record.html.erb +6 -6
  9. data/app/views/active_scaffold_overrides/_horizontal_subform.html.erb +1 -1
  10. data/app/views/active_scaffold_overrides/_horizontal_subform_header.html.erb +1 -1
  11. data/app/views/active_scaffold_overrides/_list.html.erb +2 -1
  12. data/app/views/active_scaffold_overrides/_list_messages.html.erb +1 -0
  13. data/app/views/active_scaffold_overrides/_messages.html.erb +1 -0
  14. data/app/views/active_scaffold_overrides/_render_field.js.erb +2 -1
  15. data/app/views/active_scaffold_overrides/_show_association_horizontal.html.erb +2 -1
  16. data/app/views/active_scaffold_overrides/_show_columns.html.erb +2 -2
  17. data/app/views/active_scaffold_overrides/_show_horizontal_record.html.erb +4 -4
  18. data/app/views/active_scaffold_overrides/_update_calculations.js.erb +1 -1
  19. data/app/views/active_scaffold_overrides/_update_column.js.erb +2 -2
  20. data/app/views/active_scaffold_overrides/action_confirmation.html.erb +2 -2
  21. data/app/views/active_scaffold_overrides/delete.html.erb +2 -2
  22. data/app/views/active_scaffold_overrides/on_action_update.js.erb +16 -6
  23. data/app/views/active_scaffold_overrides/on_update.js.erb +1 -1
  24. data/app/views/active_scaffold_overrides/row.js.erb +1 -1
  25. data/app/views/active_scaffold_overrides/update_column.js.erb +1 -1
  26. data/lib/active_scaffold.rb +11 -13
  27. data/lib/active_scaffold/actions/core.rb +25 -35
  28. data/lib/active_scaffold/actions/create.rb +1 -1
  29. data/lib/active_scaffold/actions/delete.rb +2 -2
  30. data/lib/active_scaffold/actions/field_search.rb +2 -2
  31. data/lib/active_scaffold/actions/list.rb +8 -7
  32. data/lib/active_scaffold/actions/nested.rb +9 -9
  33. data/lib/active_scaffold/actions/search.rb +1 -1
  34. data/lib/active_scaffold/actions/show.rb +1 -1
  35. data/lib/active_scaffold/actions/subform.rb +3 -1
  36. data/lib/active_scaffold/actions/update.rb +5 -4
  37. data/lib/active_scaffold/active_record_permissions.rb +2 -11
  38. data/lib/active_scaffold/attribute_params.rb +16 -23
  39. data/lib/active_scaffold/bridges.rb +8 -8
  40. data/lib/active_scaffold/bridges/bitfields/bitfields_bridge.rb +1 -1
  41. data/lib/active_scaffold/bridges/calendar_date_select/as_cds_bridge.rb +1 -1
  42. data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +3 -18
  43. data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge.rb +1 -1
  44. data/lib/active_scaffold/bridges/chosen/helpers.rb +7 -6
  45. data/lib/active_scaffold/bridges/date_picker/ext.rb +0 -13
  46. data/lib/active_scaffold/bridges/date_picker/helper.rb +3 -3
  47. data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +1 -1
  48. data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +3 -3
  49. data/lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb +8 -7
  50. data/lib/active_scaffold/bridges/file_column/test/test_helper.rb +2 -4
  51. data/lib/active_scaffold/bridges/paper_trail.rb +1 -1
  52. data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
  53. data/lib/active_scaffold/bridges/paperclip/paperclip_bridge.rb +1 -1
  54. data/lib/active_scaffold/bridges/paperclip/paperclip_bridge_helpers.rb +2 -2
  55. data/lib/active_scaffold/bridges/record_select/helpers.rb +9 -9
  56. data/lib/active_scaffold/bridges/shared/date_bridge.rb +3 -3
  57. data/lib/active_scaffold/bridges/usa_state_select/usa_state_select_helper.rb +1 -1
  58. data/lib/active_scaffold/config/base.rb +89 -21
  59. data/lib/active_scaffold/config/core.rb +127 -18
  60. data/lib/active_scaffold/config/delete.rb +2 -0
  61. data/lib/active_scaffold/config/field_search.rb +7 -1
  62. data/lib/active_scaffold/config/form.rb +10 -1
  63. data/lib/active_scaffold/config/list.rb +27 -11
  64. data/lib/active_scaffold/config/mark.rb +3 -1
  65. data/lib/active_scaffold/config/nested.rb +16 -17
  66. data/lib/active_scaffold/config/search.rb +9 -0
  67. data/lib/active_scaffold/config/show.rb +4 -0
  68. data/lib/active_scaffold/config/update.rb +4 -0
  69. data/lib/active_scaffold/configurable.rb +11 -6
  70. data/lib/active_scaffold/constraints.rb +1 -1
  71. data/lib/active_scaffold/core.rb +46 -16
  72. data/lib/active_scaffold/data_structures/action_columns.rb +50 -59
  73. data/lib/active_scaffold/data_structures/action_link.rb +20 -8
  74. data/lib/active_scaffold/data_structures/action_links.rb +6 -2
  75. data/lib/active_scaffold/data_structures/association/abstract.rb +9 -5
  76. data/lib/active_scaffold/data_structures/association/active_record.rb +1 -1
  77. data/lib/active_scaffold/data_structures/column.rb +51 -33
  78. data/lib/active_scaffold/data_structures/nested_info.rb +1 -1
  79. data/lib/active_scaffold/data_structures/set.rb +8 -0
  80. data/lib/active_scaffold/data_structures/sorting.rb +5 -2
  81. data/lib/active_scaffold/delayed_setup.rb +2 -1
  82. data/lib/active_scaffold/extensions/action_controller_rendering.rb +2 -1
  83. data/lib/active_scaffold/extensions/action_view_rendering.rb +1 -1
  84. data/lib/active_scaffold/extensions/cow_proxy.rb +43 -0
  85. data/lib/active_scaffold/extensions/ice_nine.rb +36 -0
  86. data/lib/active_scaffold/extensions/left_outer_joins.rb +8 -33
  87. data/lib/active_scaffold/extensions/routing_mapper.rb +4 -43
  88. data/lib/active_scaffold/extensions/unsaved_record.rb +2 -4
  89. data/lib/active_scaffold/finder.rb +26 -30
  90. data/lib/active_scaffold/helpers/action_link_helpers.rb +16 -16
  91. data/lib/active_scaffold/helpers/association_helpers.rb +5 -5
  92. data/lib/active_scaffold/helpers/controller_helpers.rb +11 -1
  93. data/lib/active_scaffold/helpers/form_column_helpers.rb +25 -24
  94. data/lib/active_scaffold/helpers/id_helpers.rb +2 -2
  95. data/lib/active_scaffold/helpers/list_column_helpers.rb +8 -6
  96. data/lib/active_scaffold/helpers/search_column_helpers.rb +4 -4
  97. data/lib/active_scaffold/helpers/view_helpers.rb +7 -13
  98. data/lib/active_scaffold/marked_model.rb +2 -2
  99. data/lib/active_scaffold/orm_checks.rb +1 -5
  100. data/lib/active_scaffold/paginator.rb +6 -4
  101. data/lib/active_scaffold/registry.rb +22 -0
  102. data/lib/active_scaffold/responds_to_parent.rb +2 -6
  103. data/lib/active_scaffold/tableless.rb +63 -59
  104. data/lib/active_scaffold/version.rb +2 -2
  105. data/lib/generators/active_scaffold/controller_generator.rb +2 -2
  106. data/lib/generators/active_scaffold/install_generator.rb +1 -1
  107. data/lib/generators/active_scaffold/resource_generator.rb +2 -2
  108. data/test/bridges/date_picker_test.rb +1 -2
  109. data/test/bridges/paperclip_test.rb +5 -5
  110. data/test/class_with_finder.rb +2 -2
  111. data/test/company.rb +2 -2
  112. data/test/config/create_test.rb +4 -2
  113. data/test/config/nested_test.rb +1 -1
  114. data/test/config/show_test.rb +1 -1
  115. data/test/config/update_test.rb +7 -6
  116. data/test/data_structures/action_links_test.rb +1 -1
  117. data/test/data_structures/sorting_test.rb +7 -0
  118. data/test/misc/active_record_permissions_test.rb +1 -9
  119. data/test/misc/attribute_params_test.rb +8 -8
  120. data/test/misc/calculation_test.rb +1 -1
  121. data/test/misc/constraints_test.rb +2 -2
  122. data/test/misc/convert_numbers_format_test.rb +3 -3
  123. data/test/misc/lang_test.rb +1 -1
  124. data/test/misc/parse_datetime_test.rb +3 -4
  125. data/test/misc/tableless_test.rb +6 -0
  126. data/test/mock_app/Rakefile +1 -1
  127. data/test/mock_app/config/application.rb +1 -1
  128. data/test/mock_app/config/boot.rb +1 -1
  129. data/test/mock_app/config/environment.rb +2 -2
  130. data/test/test_helper.rb +8 -1
  131. metadata +38 -13
@@ -1,5 +1,7 @@
1
1
  module ActiveScaffold::DataStructures
2
2
  class ActionLink
3
+ NO_OPTIONS = {}.freeze
4
+
3
5
  # provides a quick way to set any property of the object from a hash
4
6
  def initialize(action, options = {})
5
7
  # set defaults
@@ -9,9 +11,9 @@ module ActiveScaffold::DataStructures
9
11
  self.type = :collection
10
12
  self.inline = true
11
13
  self.method = :get
12
- self.crud_type = :delete if [:destroy].include?(action.try(:to_sym))
13
- self.crud_type = :create if %i[create new].include?(action.try(:to_sym))
14
- self.crud_type = :update if %i[edit update].include?(action.try(:to_sym))
14
+ self.crud_type = :delete if [:destroy].include?(action&.to_sym)
15
+ self.crud_type = :create if %i[create new].include?(action&.to_sym)
16
+ self.crud_type = :update if %i[edit update].include?(action&.to_sym)
15
17
  self.crud_type ||= :read
16
18
  self.column = nil
17
19
  self.image = nil
@@ -23,7 +25,7 @@ module ActiveScaffold::DataStructures
23
25
  setter = "#{k}="
24
26
  send(setter, v) if respond_to? setter
25
27
  end
26
- self.toggle = self.action.try(:to_sym) == :index && (parameters.present? || dynamic_parameters) unless options.include? :toggle
28
+ self.toggle = self.action&.to_sym == :index && (parameters.present? || dynamic_parameters) unless options.include? :toggle
27
29
  end
28
30
 
29
31
  def initialize_copy(action_link)
@@ -52,7 +54,8 @@ module ActiveScaffold::DataStructures
52
54
  # a hash of request parameters
53
55
  attr_writer :parameters
54
56
  def parameters
55
- @parameters ||= {}
57
+ return @parameters || NO_OPTIONS if frozen?
58
+ @parameters ||= NO_OPTIONS.dup
56
59
  end
57
60
 
58
61
  # if active class is added to link when current request matches link
@@ -186,7 +189,8 @@ module ActiveScaffold::DataStructures
186
189
  # html options for the link
187
190
  attr_writer :html_options
188
191
  def html_options
189
- @html_options ||= {}
192
+ return @html_options || NO_OPTIONS if frozen?
193
+ @html_options ||= NO_OPTIONS.dup
190
194
  end
191
195
 
192
196
  # nested action_links are referencing a column
@@ -200,11 +204,19 @@ module ActiveScaffold::DataStructures
200
204
 
201
205
  # indicates that this a nested_link
202
206
  def nested_link?
203
- @column || (parameters && parameters[:named_scope])
207
+ @column || parameters&.dig(:named_scope)
204
208
  end
205
209
 
206
210
  def name_to_cache
207
- @name_to_cache ||= "#{controller || 'self'}_#{type}_#{action}#{'_' if parameters.present?}#{parameters.map { |k, v| "#{k}=#{v.is_a?(Array) ? v.join(',') : v}" }.join('_')}"
211
+ return @name_to_cache if defined? @name_to_cache
212
+ [
213
+ controller || 'self',
214
+ type,
215
+ action,
216
+ *parameters.map { |k, v| "#{k}=#{v.is_a?(Array) ? v.join(',') : v}" }
217
+ ].compact.join('_').tap do |name_to_cache|
218
+ @name_to_cache = name_to_cache unless frozen?
219
+ end
208
220
  end
209
221
  end
210
222
  end
@@ -90,7 +90,6 @@ module ActiveScaffold::DataStructures
90
90
  break
91
91
  else
92
92
  group.delete_group(name)
93
- break
94
93
  end
95
94
  end
96
95
  end
@@ -147,8 +146,9 @@ module ActiveScaffold::DataStructures
147
146
  end
148
147
 
149
148
  def method_missing(name, *args, &block)
149
+ return super if name =~ /[!?]$/
150
150
  class_eval %{
151
- def #{name}(label = nil)
151
+ def #{name}(label = nil) # rubocop:disable Style/CommentedKeyword
152
152
  @#{name} ||= subgroup('#{name}'.to_sym, label)
153
153
  yield @#{name} if block_given?
154
154
  @#{name}
@@ -157,6 +157,10 @@ module ActiveScaffold::DataStructures
157
157
  send(name, args.first, &block)
158
158
  end
159
159
 
160
+ def respond_to_missing?(name, *)
161
+ name !~ /[!?]$/
162
+ end
163
+
160
164
  attr_accessor :name
161
165
  attr_accessor :weight
162
166
 
@@ -4,12 +4,16 @@ module ActiveScaffold::DataStructures::Association
4
4
  @association = association
5
5
  end
6
6
  attr_writer :reverse
7
- delegate :name, :klass, :foreign_key, :==, to: :@association
7
+ delegate :name, :foreign_key, :==, to: :@association
8
8
 
9
9
  def allow_join?
10
10
  !polymorphic?
11
11
  end
12
12
 
13
+ def klass
14
+ @association.klass unless polymorphic?
15
+ end
16
+
13
17
  def belongs_to?
14
18
  @association.macro == :belongs_to
15
19
  end
@@ -66,13 +70,13 @@ module ActiveScaffold::DataStructures::Association
66
70
 
67
71
  def reverse(klass = nil)
68
72
  unless polymorphic? || defined?(@reverse)
69
- @reverse ||= inverse || get_reverse.try(:name)
73
+ @reverse ||= inverse || get_reverse&.name
70
74
  end
71
- @reverse || (get_reverse(klass).try(:name) unless klass.nil?)
75
+ @reverse || (get_reverse(klass)&.name unless klass.nil?)
72
76
  end
73
77
 
74
78
  def inverse_for?(klass)
75
- inverse_class = reverse_association(klass).try(:inverse_klass)
79
+ inverse_class = reverse_association(klass)&.inverse_klass
76
80
  inverse_class.present? && (inverse_class == klass || klass < inverse_class)
77
81
  end
78
82
 
@@ -116,7 +120,7 @@ module ActiveScaffold::DataStructures::Association
116
120
 
117
121
  def reverse_match?(assoc)
118
122
  return false if assoc == @association
119
- return false unless assoc.polymorphic? || assoc.class_name == inverse_klass.try(:name)
123
+ return false unless assoc.polymorphic? || assoc.class_name == inverse_klass&.name
120
124
 
121
125
  if through?
122
126
  reverse_through_match?(assoc)
@@ -48,7 +48,7 @@ module ActiveScaffold::DataStructures::Association
48
48
 
49
49
  # name of inverse
50
50
  def inverse
51
- @association.inverse_of.try(:name)
51
+ @association.inverse_of&.name
52
52
  end
53
53
 
54
54
  def quoted_table_name
@@ -2,6 +2,8 @@ module ActiveScaffold::DataStructures
2
2
  class Column
3
3
  include ActiveScaffold::Configurable
4
4
  include ActiveScaffold::OrmChecks
5
+ NO_PARAMS = Set.new.freeze
6
+ NO_OPTIONS = {}.freeze
5
7
 
6
8
  attr_reader :active_record_class
7
9
  alias model active_record_class
@@ -31,8 +33,8 @@ module ActiveScaffold::DataStructures
31
33
 
32
34
  # Any extra parameters this particular column uses. This is for create/update purposes.
33
35
  def params
34
- # lazy initialize
35
- @params ||= Set.new
36
+ return @params || NO_PARAMS if frozen?
37
+ @params ||= NO_PARAMS.dup
36
38
  end
37
39
 
38
40
  # the display-name of the column. this will be used, for instance, as the column title in the table and as the field name in the form.
@@ -140,10 +142,12 @@ module ActiveScaffold::DataStructures
140
142
  # a place to store dev's column specific options
141
143
  attr_writer :options
142
144
  def options
143
- @options ||= {}
145
+ return @options || NO_OPTIONS if frozen?
146
+ @options ||= NO_OPTIONS.dup
144
147
  end
145
148
 
146
149
  def link
150
+ return @link.call(self) if frozen? && @link.is_a?(Proc)
147
151
  @link = @link.call(self) if @link.is_a? Proc
148
152
  @link
149
153
  end
@@ -210,7 +214,7 @@ module ActiveScaffold::DataStructures
210
214
  def search_sql=(value)
211
215
  @search_sql =
212
216
  if value
213
- (value == true || value.is_a?(Proc)) ? value : Array(value)
217
+ value == true || value.is_a?(Proc) ? value : Array(value)
214
218
  else
215
219
  value
216
220
  end
@@ -304,17 +308,17 @@ module ActiveScaffold::DataStructures
304
308
  def initialize(name, active_record_class, delegated_association = nil) #:nodoc:
305
309
  self.name = name.to_sym
306
310
  @active_record_class = active_record_class
307
- @column = _columns_hash[self.name.to_s]
311
+ @column = _columns_hash[name.to_s]
308
312
  @delegated_association = delegated_association
309
313
  setup_association_info
310
314
 
311
- @autolink = self.association.present?
315
+ @autolink = association.present?
312
316
  @table = _table_name
313
317
  @associated_limit = self.class.associated_limit
314
318
  @associated_number = self.class.associated_number
315
319
  @show_blank_record = self.class.show_blank_record
316
320
  @send_form_on_update_column = self.class.send_form_on_update_column
317
- @actions_for_association_links = self.class.actions_for_association_links.clone if self.association
321
+ @actions_for_association_links = self.class.actions_for_association_links.clone if association
318
322
  @select_columns = default_select_columns
319
323
 
320
324
  @text = @column.nil? || [:string, :text, String].include?(column_type)
@@ -337,7 +341,7 @@ module ActiveScaffold::DataStructures
337
341
  @allow_add_existing = true
338
342
  @form_ui = self.class.association_form_ui if @association && self.class.association_form_ui
339
343
 
340
- self.includes = [association.name] if association && association.allow_join?
344
+ self.includes = [association.name] if association&.allow_join?
341
345
  if delegated_association
342
346
  self.includes = includes ? [delegated_association.name => includes] : [delegated_association.name]
343
347
  end
@@ -345,7 +349,7 @@ module ActiveScaffold::DataStructures
345
349
 
346
350
  # default all the configurable variables
347
351
  self.css_class = ''
348
- self.required = active_record_class.validators_on(self.name).any? do |val|
352
+ self.required = active_record_class.validators_on(name).any? do |val|
349
353
  validator_force_required?(val)
350
354
  end
351
355
  self.sort = true
@@ -386,10 +390,27 @@ module ActiveScaffold::DataStructures
386
390
  end
387
391
 
388
392
  # to cache method to get value in list
389
- attr_accessor :list_method
393
+ def list_method
394
+ Rails.cache.fetch(cache_key(:list_method))
395
+ end
396
+
397
+ def list_method=(value)
398
+ Rails.cache.write(cache_key(:list_method), value)
399
+ end
390
400
 
391
401
  # cache constraints for numeric columns (get in ActiveScaffold::Helpers::FormColumnHelpers::numerical_constraints_for_column)
392
- attr_accessor :numerical_constraints
402
+ def numerical_constraints
403
+ Rails.cache.fetch(cache_key(:numerical_constraints))
404
+ end
405
+
406
+ def numerical_constraints=(value)
407
+ Rails.cache.write(cache_key(:numerical_constraints), value)
408
+ end
409
+
410
+ # cache key to cache column info
411
+ def cache_key(attr)
412
+ [@active_record_class.name, name, attr].compact.map(&:to_s).join('#')
413
+ end
393
414
 
394
415
  # the table.field name for this column, if applicable
395
416
  def field
@@ -407,16 +428,18 @@ module ActiveScaffold::DataStructures
407
428
  protected
408
429
 
409
430
  def setup_association_info
410
- assoc = active_record_class.reflect_on_association(self.name)
411
- @association = if assoc
412
- case
413
- when active_record? then Association::ActiveRecord.new(assoc)
414
- when mongoid? then Association::Mongoid.new(assoc)
415
- end
416
- elsif defined?(ActiveMongoid) && model < ActiveMongoid::Associations
417
- assoc = active_record_class.reflect_on_am_association(name)
418
- Association::ActiveMongoid.new(assoc) if assoc
419
- end
431
+ assoc = active_record_class.reflect_on_association(name)
432
+ @association =
433
+ if assoc
434
+ if active_record?
435
+ Association::ActiveRecord.new(assoc)
436
+ elsif mongoid?
437
+ Association::Mongoid.new(assoc)
438
+ end
439
+ elsif defined?(ActiveMongoid) && model < ActiveMongoid::Associations
440
+ assoc = active_record_class.reflect_on_am_association(name)
441
+ Association::ActiveMongoid.new(assoc) if assoc
442
+ end
420
443
  end
421
444
 
422
445
  def validator_force_required?(val)
@@ -438,7 +461,7 @@ module ActiveScaffold::DataStructures
438
461
  def default_select_columns
439
462
  if association.nil? && column
440
463
  [field]
441
- elsif association.try(:polymorphic?)
464
+ elsif association&.polymorphic?
442
465
  [field, quoted_field(quoted_field_name(association.foreign_type))]
443
466
  elsif association
444
467
  if association.belongs_to?
@@ -448,7 +471,7 @@ module ActiveScaffold::DataStructures
448
471
  if _columns_hash[count_column = "#{association.name}_count"]
449
472
  columns << quoted_field(quoted_field_name(count_column))
450
473
  end
451
- if association.through_reflection.try(:belongs_to?)
474
+ if association.through_reflection&.belongs_to?
452
475
  columns << quoted_field(quoted_field_name(association.through_reflection.foreign_key))
453
476
  end
454
477
  columns
@@ -474,15 +497,10 @@ module ActiveScaffold::DataStructures
474
497
  end
475
498
 
476
499
  def initialize_sort
477
- if virtual?
478
- # we don't automatically enable method sorting for virtual columns because it's slow, and we expect fewer complaints this way.
479
- self.sort = false
500
+ if column && !tableless?
501
+ self.sort = {:sql => field}
480
502
  else
481
- if column && !tableless?
482
- self.sort = {:sql => field}
483
- else
484
- self.sort = false
485
- end
503
+ self.sort = false
486
504
  end
487
505
  end
488
506
 
@@ -501,9 +519,9 @@ module ActiveScaffold::DataStructures
501
519
  attr_reader :table
502
520
 
503
521
  def estimate_weight
504
- if association.try(:singular?)
522
+ if association&.singular?
505
523
  400
506
- elsif association.try(:collection?)
524
+ elsif association&.collection?
507
525
  500
508
526
  elsif %i[created_at updated_at].include?(name)
509
527
  600
@@ -74,7 +74,7 @@ module ActiveScaffold::DataStructures
74
74
  column = parent_scaffold.active_scaffold_config.columns[params[:association].to_sym]
75
75
  @param_name = column.model.name.foreign_key.to_sym
76
76
  @parent_id = params[@param_name]
77
- @association = column.try(:association)
77
+ @association = column&.association
78
78
  @child_association = association.reverse_association(model) if association
79
79
  setup_constrained_fields
80
80
  end
@@ -7,6 +7,10 @@ module ActiveScaffold::DataStructures
7
7
  set_values(*args)
8
8
  end
9
9
 
10
+ def initialize_dup(other)
11
+ @set = other.set.dup
12
+ end
13
+
10
14
  def set_values(*args)
11
15
  @set = []
12
16
  add(*args)
@@ -56,5 +60,9 @@ module ActiveScaffold::DataStructures
56
60
  def empty?
57
61
  @set.empty?
58
62
  end
63
+
64
+ protected
65
+
66
+ attr_reader :set
59
67
  end
60
68
  end
@@ -55,6 +55,9 @@ module ActiveScaffold::DataStructures
55
55
  # set({column => direction}, {column => direction})
56
56
  # set([column, direction], [column, direction])
57
57
  def set(*args)
58
+ # TODO: add deprecation unless args.size == 1 && args[0].is_a? Hash
59
+ # when deprecation is removed:
60
+ # * change list#sorting= to sorting.set(val)
58
61
  clear
59
62
  if args.first.is_a?(Enumerable)
60
63
  args.each do |h|
@@ -120,7 +123,7 @@ module ActiveScaffold::DataStructures
120
123
  order = []
121
124
  each do |sort_column, sort_direction|
122
125
  next if constraint_columns.include? sort_column.name
123
- sql = grouped_columns_calculations.try(:dig, sort_column.name) || sort_column.sort[:sql]
126
+ sql = grouped_columns_calculations&.dig(sort_column.name) || sort_column.sort[:sql]
124
127
  next if sql.blank?
125
128
  sql = sql.to_sql if sql.respond_to?(:to_sql)
126
129
 
@@ -200,7 +203,7 @@ module ActiveScaffold::DataStructures
200
203
  end
201
204
 
202
205
  def postgres?
203
- model.connection.try(:adapter_name) == 'PostgreSQL'
206
+ model.connection&.adapter_name == 'PostgreSQL'
204
207
  end
205
208
 
206
209
  def setup_primary_key_order_clause
@@ -17,7 +17,8 @@ module ActiveScaffold
17
17
  def config_active_scaffold_delayed
18
18
  return unless @active_scaffold_delayed
19
19
  @_prefixes = nil # clean prefixes in case is already cached, so our local_prefixes override is picked up
20
- block, @active_scaffold_delayed = @active_scaffold_delayed, nil
20
+ block = @active_scaffold_delayed
21
+ @active_scaffold_delayed = nil
21
22
  block.call
22
23
  end
23
24
 
@@ -5,7 +5,8 @@ module ActiveScaffold
5
5
  if self.class.uses_active_scaffold? && params[:adapter] && @rendering_adapter.nil? && request.xhr?
6
6
  @rendering_adapter = true # recursion control
7
7
  # if we need an adapter, then we render the actual stuff to a string and insert it into the adapter template
8
- opts = args.blank? ? {} : args.first
8
+ opts = args.any? ? args.first : {}
9
+
9
10
  render :partial => params[:adapter][1..-1],
10
11
  :locals => {:payload => render_to_string(opts.merge(:layout => false), &block).html_safe},
11
12
  :use_full_path => true, :layout => false, :content_type => :html
@@ -114,7 +114,7 @@ module ActiveScaffold #:nodoc:
114
114
  content_tag(:div, :id => id, :class => 'active-scaffold-component', :data => {:refresh => url}) do
115
115
  # parse the ActiveRecord model name from the controller path, which
116
116
  # might be a namespaced controller (e.g., 'admin/admins')
117
- model = remote_controller.to_s.sub(/.*\//, '').singularize
117
+ model = remote_controller.to_s.sub(%r{/.*//}, '').singularize
118
118
  content_tag(:div, :class => 'active-scaffold-header') do
119
119
  content_tag :h2, link_to(options[:label] || active_scaffold_config_for(model).list.label, url, :remote => true, :class => 'load-embedded')
120
120
  end
@@ -0,0 +1,43 @@
1
+ require 'cow_proxy'
2
+
3
+ module CowProxy
4
+ module ActiveScaffold
5
+ module DataStructures
6
+ class Column < ::CowProxy::WrapClass(::ActiveScaffold::DataStructures::Column)
7
+ end
8
+
9
+ class Set < ::CowProxy::WrapClass(::ActiveScaffold::DataStructures::Set)
10
+ protected
11
+
12
+ # Copy wrapped values to duplicated wrapped object
13
+ # @see CowProxy::Base#__copy_on_write__
14
+ # @return duplicated wrapped object
15
+ def __copy_on_write__(*)
16
+ super.tap do
17
+ new_set = __getobj__.instance_variable_get(:@set).dup
18
+ __getobj__.instance_variable_set(:@set, new_set)
19
+ end
20
+ end
21
+ end
22
+
23
+ class ActionLinks < ::CowProxy::WrapClass(::ActiveScaffold::DataStructures::ActionLinks)
24
+ def method_missing(name, *args, &block)
25
+ return super if name =~ /[!?]$/
26
+ __copy_on_write__ if frozen?
27
+ subgroup =
28
+ if _instance_variable_defined?("@#{name}")
29
+ _instance_variable_get("@#{name}")
30
+ else
31
+ _instance_variable_set("@#{name}", __wrap__(__getobj__.subgroup(name, args.first)))
32
+ end
33
+ yield subgroup if block
34
+ subgroup
35
+ end
36
+
37
+ def respond_to_missing?(name, *)
38
+ name !~ /[!?]$/
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end