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
@@ -26,5 +26,7 @@ module ActiveScaffold::Config
26
26
 
27
27
  # whether we should refresh list after destroy or not
28
28
  attr_accessor :refresh_list
29
+
30
+ undef_method :new_user_settings
29
31
  end
30
32
  end
@@ -1,6 +1,7 @@
1
1
  module ActiveScaffold::Config
2
2
  class FieldSearch < Base
3
3
  self.crud_type = :read
4
+ NO_COLUMNS = [].freeze
4
5
 
5
6
  def initialize(core_config)
6
7
  super
@@ -52,7 +53,8 @@ module ActiveScaffold::Config
52
53
  end
53
54
 
54
55
  def optional_columns
55
- @optional_columns ||= []
56
+ return @optional_columns || NO_COLUMNS if frozen?
57
+ @optional_columns ||= NO_COLUMNS.dup
56
58
  end
57
59
 
58
60
  # add array of columns as options for group by to get aggregated listings
@@ -68,5 +70,9 @@ module ActiveScaffold::Config
68
70
  # human conditions
69
71
  # instead of just filtered you may show the user a humanized search condition statment
70
72
  attr_accessor :human_conditions
73
+
74
+ UserSettings.class_eval do
75
+ user_attr :optional_columns, :group_options, :grouped_columns, :human_conditions
76
+ end
71
77
  end
72
78
  end
@@ -43,7 +43,7 @@ module ActiveScaffold::Config
43
43
 
44
44
  columns_accessor :columns do
45
45
  columns.exclude :created_on, :created_at, :updated_on, :updated_at, :as_marked
46
- columns.exclude(*@core.columns.collect { |c| c.name if c.association.try(:polymorphic?) }.compact)
46
+ columns.exclude(*@core.columns.collect { |c| c.name if c.association&.polymorphic? }.compact)
47
47
  end
48
48
 
49
49
  # whether the form should be multipart
@@ -51,5 +51,14 @@ module ActiveScaffold::Config
51
51
  def multipart?
52
52
  @multipart ? true : false
53
53
  end
54
+
55
+ UserSettings.class_eval do
56
+ user_attr :persistent, :refresh_list, :show_unauthorized_columns
57
+
58
+ attr_writer :multipart
59
+ def multipart?
60
+ defined?(@multipart) ? @multipart : @conf.multipart?
61
+ end
62
+ end
54
63
  end
55
64
  end
@@ -219,10 +219,15 @@ module ActiveScaffold::Config
219
219
  # order clause will be used for ETag when calculate_etag is disabled, so query for records can be avoided
220
220
  attr_accessor :calculate_etag
221
221
 
222
- class UserSettings < UserSettings
222
+ UserSettings.class_eval do # defined with columns_accessor
223
+ user_attr :page_links_inner_window, :page_links_outer_window, :refresh_with_header, :empty_field_text,
224
+ :association_join_text, :messages_above_header, :wrap_tag, :auto_select_columns, :calculate_etag,
225
+ :no_entries_message, :filtered_message, :show_search_reset, :always_show_create, :always_show_search,
226
+ :hide_nested_column
227
+
223
228
  def initialize(conf, storage, params)
224
229
  super(conf, storage, params, :list)
225
- @sorting = nil
230
+ @_sorting = nil
226
231
  end
227
232
 
228
233
  attr_writer :label
@@ -232,7 +237,7 @@ module ActiveScaffold::Config
232
237
  end
233
238
 
234
239
  def embedded_label
235
- @params[:embedded][:label] if @params[:embedded]
240
+ @params.dig :embedded, :label
236
241
  end
237
242
 
238
243
  def per_page
@@ -240,6 +245,10 @@ module ActiveScaffold::Config
240
245
  self['per_page'] || @conf.per_page
241
246
  end
242
247
 
248
+ def per_page=(value)
249
+ self['per_page'] = value
250
+ end
251
+
243
252
  def page
244
253
  self['page'] = @params['page'] || 1 if @params.key?('page') || @conf.auto_pagination
245
254
  self['page'] || 1
@@ -252,36 +261,43 @@ module ActiveScaffold::Config
252
261
  attr_reader :nested_default_sorting
253
262
 
254
263
  def nested_default_sorting=(options)
255
- @nested_default_sorting ||= @conf.sorting.clone
264
+ @nested_default_sorting ||= @conf.sorting.dup
256
265
  @nested_default_sorting.set_nested_sorting(options[:table_name], options[:default_sorting])
257
266
  end
258
267
 
259
268
  def default_sorting
260
- nested_default_sorting.nil? ? @conf.sorting.clone : nested_default_sorting
269
+ nested_default_sorting.nil? || @sorting.present? ? @conf.sorting.dup : nested_default_sorting
261
270
  end
262
271
 
272
+ # TODO: programatically set sorting, for per-request configuration, priority @params, then @sort
273
+
263
274
  def user_sorting?
264
275
  @params['sort'] && @params['sort_direction'] != 'reset'
265
276
  end
266
277
 
278
+ # change list sorting for this request, unless sorting is defined
279
+ # {column => direction, column => direction}
280
+ attr_writer :sorting
281
+
267
282
  def sorting
268
- if @sorting.nil?
283
+ if @_sorting.nil?
269
284
  # we want to store as little as possible in the session, but we want to return a Sorting data structure. so we recreate it each page load based on session data.
270
285
  self['sort'] = [@params['sort'], @params['sort_direction']] if @params['sort'] && @params['sort_direction']
271
286
  self['sort'] = nil if @params['sort_direction'] == 'reset'
272
287
 
273
288
  if self['sort'] && @conf.core.columns[self['sort'][0]]
274
- sorting = @conf.sorting.clone
289
+ sorting = @conf.sorting.dup
275
290
  sorting.set(*self['sort'])
276
- @sorting = sorting
291
+ @_sorting = sorting
277
292
  else
278
- @sorting = default_sorting
293
+ @_sorting = default_sorting
294
+ @_sorting.set(@sorting) if @sorting
279
295
  if @conf.columns.constraint_columns.present?
280
- @sorting.constraint_columns = @conf.columns.constraint_columns
296
+ @_sorting.constraint_columns = @conf.columns.constraint_columns
281
297
  end
282
298
  end
283
299
  end
284
- @sorting
300
+ @_sorting
285
301
  end
286
302
 
287
303
  def count_includes
@@ -24,7 +24,9 @@ module ActiveScaffold::Config
24
24
  @core.columns[:as_marked].label = 'M'
25
25
  @core.columns[:as_marked].list_ui = :marked
26
26
  @core.columns[:as_marked].sort = false
27
- @core.list.columns = [:as_marked] + @core.list.columns.names_without_auth_check unless @core.list.columns.include? :as_marked
27
+ @core.list.columns = [:as_marked] + @core.list.columns.to_a unless @core.list.columns.include? :as_marked
28
28
  end
29
+
30
+ undef_method :new_user_settings
29
31
  end
30
32
  end
@@ -25,23 +25,20 @@ module ActiveScaffold::Config
25
25
  # Add a nested ActionLink
26
26
  def add_link(attribute, options = {})
27
27
  column = @core.columns[attribute.to_sym]
28
- if column && column.association
29
- label =
30
- if column.association.polymorphic?
31
- column.label
32
- else
33
- column.association.klass.model_name.human(:count => column.association.singular? ? 1 : 2, :default => column.association.klass.name.pluralize)
34
- end
35
- options.reverse_merge! :security_method => :nested_authorized?, :label => label
36
- action_group = options.delete(:action_group) || self.action_group
37
- action_link = @core.link_for_association(column, options)
38
- @core.action_links.add_to_group(action_link, action_group) unless action_link.nil?
39
- action_link
40
- elsif column.nil?
41
- raise ArgumentError, "unknown column #{attribute}"
42
- elsif column.association.nil?
43
- raise ArgumentError, "column #{attribute} is not an association"
44
- end
28
+ raise ArgumentError, "unknown column #{attribute}" if column.nil?
29
+ raise ArgumentError, "column #{attribute} is not an association" if column.association.nil?
30
+
31
+ label =
32
+ if column.association.polymorphic?
33
+ column.label
34
+ else
35
+ column.association.klass.model_name.human(:count => column.association.singular? ? 1 : 2, :default => column.association.klass.name.pluralize)
36
+ end
37
+ options.reverse_merge! :security_method => :nested_authorized?, :label => label
38
+ action_group = options.delete(:action_group) || self.action_group
39
+ action_link = @core.link_for_association(column, options)
40
+ @core.action_links.add_to_group(action_link, action_group) unless action_link.nil?
41
+ action_link
45
42
  end
46
43
 
47
44
  def add_scoped_link(named_scope, options = {})
@@ -51,5 +48,7 @@ module ActiveScaffold::Config
51
48
 
52
49
  # the label for this Nested action. used for the header.
53
50
  attr_writer :label
51
+
52
+ undef_method :new_user_settings
54
53
  end
55
54
  end
@@ -64,5 +64,14 @@ module ActiveScaffold::Config
64
64
  def live?
65
65
  @live
66
66
  end
67
+
68
+ UserSettings.class_eval do
69
+ attr_writer :live
70
+ def live?
71
+ defined?(@live) ? @live : @conf.live?
72
+ end
73
+
74
+ user_attr :text_search, :split_terms
75
+ end
67
76
  end
68
77
  end
@@ -25,5 +25,9 @@ module ActiveScaffold::Config
25
25
  attr_writer :label
26
26
 
27
27
  columns_accessor :columns
28
+
29
+ UserSettings.class_eval do
30
+ user_attr :inline_links
31
+ end
28
32
  end
29
33
  end
@@ -32,5 +32,9 @@ module ActiveScaffold::Config
32
32
  def hide_nested_column
33
33
  @hide_nested_column.nil? ? true : @hide_nested_column
34
34
  end
35
+
36
+ UserSettings.class_eval do
37
+ user_attr :nested_links, :hide_nested_column
38
+ end
35
39
  end
36
40
  end
@@ -13,14 +13,19 @@ module ActiveScaffold
13
13
  ret
14
14
  end
15
15
 
16
- # this method will surely need tweaking. for example, i'm not sure if it should call super before or after it tries to eval with the binding.
17
16
  def method_missing(name, *args)
18
- super
19
- rescue NoMethodError, NameError
20
- if @configuration_binding.nil?
21
- raise
22
- else
17
+ if @configuration_binding&.respond_to?(name, true)
23
18
  @configuration_binding.send(name, *args)
19
+ else
20
+ super
21
+ end
22
+ end
23
+
24
+ def respond_to_missing?(name, include_all = false)
25
+ if @configuration_binding
26
+ @configuration_binding.respond_to?(name, include_all)
27
+ else
28
+ super
24
29
  end
25
30
  end
26
31
  end
@@ -143,7 +143,7 @@ module ActiveScaffold
143
143
  config = record.is_a?(active_scaffold_config.model) ? active_scaffold_config : active_scaffold_config_for(record.class)
144
144
  constraints.each do |k, v|
145
145
  column = config.columns[k]
146
- if column && column.association
146
+ if column&.association
147
147
  if column.association.collection?
148
148
  record.send(k.to_s).send(:<<, column.association.klass.find(v))
149
149
  elsif column.association.polymorphic?
@@ -4,12 +4,43 @@ module ActiveScaffold
4
4
  base.extend(ClassMethods)
5
5
  end
6
6
 
7
+ def setup_user_settings
8
+ config = self.class.active_scaffold_config
9
+ config.new_user_settings(user_settings_storage, params)
10
+ unless ActiveScaffold.threadsafe
11
+ config.actions.each do |action_name|
12
+ conf_instance = config.send(action_name) rescue next # rubocop:disable Style/RescueModifier
13
+ config.user.action_user_settings(conf_instance)
14
+ end
15
+ end
16
+ end
17
+
7
18
  def active_scaffold_config
8
- self.class.active_scaffold_config
19
+ setup_user_settings unless self.class.active_scaffold_config.user
20
+ if ActiveScaffold.threadsafe
21
+ self.class.active_scaffold_config.user
22
+ else
23
+ self.class.active_scaffold_config
24
+ end
25
+ end
26
+
27
+ def active_scaffold_session_storage_key(id = nil)
28
+ id ||= params[:eid] || "#{params[:controller]}#{"_#{nested_parent_id}" if nested?}"
29
+ "as:#{id}"
9
30
  end
10
31
 
11
- def active_scaffold_config_for(klass)
12
- self.class.active_scaffold_config_for(klass)
32
+ def active_scaffold_session_storage(id = nil)
33
+ session_index = active_scaffold_session_storage_key(id)
34
+ session[session_index] ||= {}
35
+ session[session_index]
36
+ end
37
+
38
+ def user_settings_storage
39
+ if self.class.active_scaffold_config.store_user_settings
40
+ active_scaffold_session_storage
41
+ else
42
+ {}
43
+ end
13
44
  end
14
45
 
15
46
  module ClassMethods
@@ -30,7 +61,6 @@ module ActiveScaffold
30
61
  active_scaffold_config.sti_children = nil # reset sti_children if set in parent block
31
62
  active_scaffold_config.configure(&block) if block_given?
32
63
  active_scaffold_config._configure_sti unless active_scaffold_config.sti_children.nil?
33
- active_scaffold_config._load_action_columns
34
64
 
35
65
  # defines the attribute read methods on the model, so record.send() doesn't find protected/private methods instead
36
66
  # define_attribute_methods is safe to call multiple times since rails 4.0.4
@@ -46,6 +76,7 @@ module ActiveScaffold
46
76
  active_scaffold_config.actions.each do |mod|
47
77
  include "ActiveScaffold::Actions::#{mod.to_s.camelize}".constantize
48
78
  mod_conf = active_scaffold_config.send(mod)
79
+ active_scaffold_config._setup_action(mod) if ActiveScaffold.threadsafe
49
80
  next unless mod_conf.respond_to?(:link) && (link = mod_conf.link)
50
81
 
51
82
  # sneak the action links from the actions into the main set
@@ -59,10 +90,14 @@ module ActiveScaffold
59
90
  end
60
91
  end
61
92
  _add_sti_create_links if active_scaffold_config.add_sti_create_links?
93
+ if ActiveScaffold.threadsafe
94
+ active_scaffold_config._cache_lazy_values
95
+ active_scaffold_config.deep_freeze!
96
+ end
62
97
  end
63
98
 
64
99
  module Prefixes
65
- define_method Rails.version < '4.2' ? 'parent_prefixes' : 'local_prefixes' do
100
+ define_method 'local_prefixes' do
66
101
  @local_prefixes ||= begin
67
102
  prefixes = super()
68
103
  unless superclass.uses_active_scaffold? || prefixes.include?('active_scaffold_overrides')
@@ -167,17 +202,14 @@ module ActiveScaffold
167
202
  end
168
203
 
169
204
  def active_scaffold_config_for(klass)
170
- controller = active_scaffold_controller_for(klass)
205
+ active_scaffold_controller_for(klass).active_scaffold_config
171
206
  rescue ActiveScaffold::ControllerNotFound
172
- config = ActiveScaffold::Config::Core.new(klass)
173
- config._load_action_columns
174
- config
175
- else
176
- controller.active_scaffold_config
207
+ ActiveScaffold::Config::Core.new(klass)
177
208
  end
178
209
 
179
210
  def active_scaffold_controller_for(klass)
180
211
  return self if uses_active_scaffold? && klass == active_scaffold_config.model
212
+ # noinspection RubyArgCount
181
213
  ActiveScaffold::Core.active_scaffold_controller_for(klass, to_s.deconstantize + '::')
182
214
  end
183
215
 
@@ -216,9 +248,9 @@ module ActiveScaffold
216
248
  end
217
249
 
218
250
  def self.column_type_cast(value, column)
219
- if defined?(ActiveRecord) && ActiveRecord::ConnectionAdapters::Column === column
251
+ if defined?(ActiveRecord) && column.is_a?(ActiveRecord::ConnectionAdapters::Column)
220
252
  active_record_column_type_cast(value, column)
221
- elsif defined?(Mongoid) && Mongoid::Fields::Standard === column
253
+ elsif defined?(Mongoid) && column.is_a?(Mongoid::Fields::Standard)
222
254
  mongoid_column_type_cast(value, column)
223
255
  else
224
256
  value
@@ -230,9 +262,7 @@ module ActiveScaffold
230
262
  end
231
263
 
232
264
  def self.active_record_column_type_cast(value, column)
233
- if Rails.version < '4.2'
234
- column.type_cast value
235
- elsif Rails.version < '5.0'
265
+ if Rails.version < '5.0'
236
266
  column.type_cast_from_user value
237
267
  elsif column.type.respond_to? :cast # jruby-jdbc and rails 5
238
268
  column.type.cast value
@@ -52,82 +52,77 @@ module ActiveScaffold::DataStructures
52
52
  false
53
53
  end
54
54
 
55
- def names
56
- if @columns
57
- collect_visible(:flatten => true, &:name)
58
- else
59
- names_without_auth_check
60
- end
55
+ def to_a
56
+ Array(@set)
61
57
  end
62
58
 
63
- def names_without_auth_check
64
- Array(@set)
59
+ def skip_column?(column_name, options)
60
+ # skip if this matches a constrained column
61
+ return true if constraint_columns.include?(column_name.to_sym)
62
+ # skip this field if it's not authorized
63
+ unless options[:for].authorized_for?(action: options[:action], crud_type: options[:crud_type] || action&.crud_type || :read, column: column_name)
64
+ unauthorized_columns << column_name.to_sym
65
+ return true
66
+ end
67
+ false
65
68
  end
66
69
 
67
- # Redefine the each method to yield actual Column objects.
68
- # It will skip constrained and unauthorized columns.
69
- #
70
- # Options:
71
- # * :flatten - whether to recursively iterate on nested sets. default is false.
72
- # * :for - the record (or class) being iterated over. used for column-level security. default is the class.
73
- def each(options = {}, &proc)
74
- options[:for] ||= @columns.active_record_class unless @columns.nil?
70
+ def each_column(options = {}, &proc)
71
+ columns = action.core.columns
75
72
  self.unauthorized_columns = []
76
- @set.each do |item|
77
- unless item.is_a?(ActiveScaffold::DataStructures::ActionColumns) || @columns.nil?
78
- item = (@columns[item] || ActiveScaffold::DataStructures::Column.new(item.to_sym, @columns.active_record_class))
79
- next if skip_column?(item, options)
80
- end
73
+ options[:for] ||= columns.active_record_class
74
+
75
+ each do |item|
81
76
  if item.is_a? ActiveScaffold::DataStructures::ActionColumns
82
77
  if options[:flatten]
83
- item.each(options, &proc)
78
+ item.each_column(options, &proc)
84
79
  elsif !options[:skip_groups]
85
80
  yield item
86
81
  end
87
82
  else
88
- yield item
83
+ next if skip_column?(item, options)
84
+ yield columns[item] || ActiveScaffold::DataStructures::Column.new(item.to_sym, columns.active_record_class)
89
85
  end
90
86
  end
91
87
  end
92
88
 
93
- def collect_visible(options = {}, &proc)
89
+ def visible_columns(options = {})
94
90
  columns = []
95
- options[:for] ||= @columns.active_record_class
96
- self.unauthorized_columns = []
97
- @set.each do |item|
98
- unless item.is_a?(ActiveScaffold::DataStructures::ActionColumns) || @columns.nil?
99
- item = (@columns[item] || ActiveScaffold::DataStructures::Column.new(item.to_sym, @columns.active_record_class))
100
- next if skip_column?(item, options)
101
- end
102
- if item.is_a?(ActiveScaffold::DataStructures::ActionColumns) && options.key?(:flatten) && options[:flatten]
103
- columns += item.collect_visible(options, &proc)
104
- else
105
- columns << (block_given? ? yield(item) : item)
106
- end
91
+ each_column(options) do |column|
92
+ columns << column
107
93
  end
108
94
  columns
109
95
  end
110
96
 
111
- def skip_column?(column, options)
112
- # skip if this matches a constrained column
113
- return true if constraint_columns.include?(column.name.to_sym)
114
- # skip this field if it's not authorized
115
- unless options[:for].authorized_for?(:action => options[:action], :crud_type => options[:crud_type] || action.try(:crud_type) || :read, :column => column.name)
116
- unauthorized_columns << column.name.to_sym
117
- return true
118
- end
119
- false
97
+ def visible_columns_names(options = {})
98
+ visible_columns(options.reverse_merge(flatten: true)).map(&:name)
120
99
  end
121
100
 
122
- # registers a set of column objects (recursively, for all nested ActionColumns)
123
- def set_columns(columns)
124
- @columns = columns
125
- # iterate over @set instead of self to avoid dealing with security queries
126
- @set.each do |item|
127
- item.set_columns(columns) if item.respond_to? :set_columns
101
+ def each(options = nil, &proc)
102
+ if options
103
+ ActiveSupport::Deprecation.warn 'use each_column'
104
+ each_column(options, &proc)
105
+ else
106
+ super(&proc)
128
107
  end
129
108
  end
130
109
 
110
+ def collect_visible(options = {}, &proc)
111
+ ActiveSupport::Deprecation.warn "use visible_columns#{"(#{options.inspect})" if options.present?}#{'.map(&proc)' if proc}"
112
+ columns = visible_columns(options)
113
+ proc ? columns.map(&proc) : columns
114
+ end
115
+
116
+ def names
117
+ ActiveSupport::Deprecation.warn 'use visible_columns.map(&:name)'
118
+ visible_columns(flatten: true).map(&:name)
119
+ end
120
+
121
+ def names_without_auth_check
122
+ ActiveSupport::Deprecation.warn 'use to_a'
123
+ to_a
124
+ end
125
+
131
126
  def action_name
132
127
  @action.class.name.demodulize.underscore
133
128
  end
@@ -137,23 +132,19 @@ module ActiveScaffold::DataStructures
137
132
  end
138
133
 
139
134
  def constraint_columns=(columns)
140
- Thread.current[:constraint_columns] ||= {}
141
- Thread.current[:constraint_columns][columns_key] = columns
135
+ ActiveScaffold::Registry.constraint_columns[columns_key] = columns
142
136
  end
143
137
 
144
138
  def constraint_columns
145
- constraints = Thread.current[:constraint_columns]
146
- (constraints[columns_key] if constraints) || []
139
+ ActiveScaffold::Registry.constraint_columns[columns_key]
147
140
  end
148
141
 
149
142
  def unauthorized_columns=(columns)
150
- Thread.current[:unauthorized_columns] ||= {}
151
- Thread.current[:unauthorized_columns][columns_key] = columns
143
+ ActiveScaffold::Registry.unauthorized_columns[columns_key] = columns
152
144
  end
153
145
 
154
146
  def unauthorized_columns
155
- Thread.current[:unauthorized_columns] ||= {}
156
- Thread.current[:unauthorized_columns][columns_key] ||= []
147
+ ActiveScaffold::Registry.unauthorized_columns[columns_key]
157
148
  end
158
149
 
159
150
  def length