active_scaffold 4.4.4 → 4.4.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b212c764ce6307b7968f811cd89c2042b8cb5d1f79b448ddd838360efc8375ab
4
- data.tar.gz: 4f44ea2e0e00189d67f4027e95decea8b3589e5f3d372d1c53cd289ca70188c7
3
+ metadata.gz: 53bf726d56ef1da11ee5ecdf4bc039b59ef10e74dd1ac9d31e2723e3e27716e1
4
+ data.tar.gz: 625f6798df882567a08bac210c6af4c9dbb246364ba739fc0a68bdad695c7b94
5
5
  SHA512:
6
- metadata.gz: 264149ca1905e0bae13b93a71a3720d9e09d3b2bae57b15a702474dfb40d2d8fad33ea04a8708991d6c983ef6c45159a5fd7133ad143cf95e3d5c74f5b830a34
7
- data.tar.gz: b8bf1c62d6fc8e9063ccb46df88709630a0ce6d1eb9edebcb3058df8e43535f7e0420a4781614bd479197f00f5cdcce423bf1298b15ddd264515701fa7c83b03
6
+ metadata.gz: 1948177220ec25858dc4d4a19e0313db67f8cafc544ab6bfdf5129bbd418918c9d6f4e4af1f134213e39cc97fb2da485972feca80628547f7fcbc9ad1687e2b9
7
+ data.tar.gz: 21308ad93ecc7bed4293d82dc4b011eb516e43171d9283ea26fdf24fd67f3283f280ba2c11033c3fdd1008194fef34821a9b134b2c672c8159611eb1b73eac59
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,49 @@
1
+ = 4.4.5
2
+ - Authorize the PaperTrail deleted-records action and allow overriding its version query with +deleted_records_query+
3
+ - Deprecate passing optional boolean arguments positionally; keyword arguments will be required in 4.5.
4
+
5
+ Overrides which only forward arguments can replace anonymous +*+ with +...+. This accepts the positional argument from 4.4 and forwards the keyword argument used by 4.5:
6
+
7
+ # Before
8
+ def find_or_create_for_params(params, parent_column, parent_record, *)
9
+ super
10
+ end
11
+
12
+ # Compatible with both 4.4 and 4.5
13
+ def find_or_create_for_params(params, parent_column, parent_record, ...)
14
+ super
15
+ end
16
+
17
+ An override which reads or changes the optional argument must temporarily accept both forms. It must call +super+ explicitly with keywords; bare +super+ would forward the original positional arguments and keep producing the warning:
18
+
19
+ # Before
20
+ def update_columns_options(column, scope, options, force = false)
21
+ super(column, scope, options, true)
22
+ end
23
+
24
+ # Compatible with both 4.4 and 4.5
25
+ def update_columns_options(column, scope, options, *legacy_force, force: false, **kwargs)
26
+ force = legacy_force.first unless legacy_force.empty?
27
+ force = true
28
+ super(column, scope, options, force: force, **kwargs)
29
+ end
30
+
31
+ After requiring ActiveScaffold 4.5, the compatibility rest argument can be removed:
32
+
33
+ def update_columns_options(column, scope, options, force: false, **kwargs)
34
+ super(column, scope, options, force: true, **kwargs)
35
+ end
36
+
37
+ For methods such as +form_attribute+, where another positional argument followed the boolean, normalize both arguments before calling +super+:
38
+
39
+ def form_attribute(column, record, scope = nil, *legacy_arguments,
40
+ only_value: false, col_class: nil, **kwargs)
41
+ only_value = legacy_arguments.shift unless legacy_arguments.empty?
42
+ col_class = legacy_arguments.shift unless legacy_arguments.empty?
43
+
44
+ super(column, record, scope, only_value: only_value, col_class: col_class, **kwargs)
45
+ end
46
+
1
47
  = 4.4.4
2
48
  - Fix the inconsistent behaviour for constraints containing an array with only one value
3
49
  - Wait for dynamically loaded plugins and bridges to finish registering their ready and setup callbacks before initial setup, fixing initialization on directly rendered forms
@@ -57,7 +57,13 @@ module ActiveScaffold
57
57
  #
58
58
  # This is a secure way to apply params to a record, because it's based on a loop over the columns
59
59
  # set. The columns set will not yield unauthorized columns, and it will not yield unregistered columns.
60
- def update_record_from_params(parent_record, columns, attributes, avoid_changes = false, search_attributes: false)
60
+ def update_record_from_params(parent_record, columns, attributes,
61
+ positional_avoid_changes = POSITIONAL_ARGUMENT_NOT_GIVEN,
62
+ avoid_changes: POSITIONAL_ARGUMENT_NOT_GIVEN, search_attributes: false)
63
+ avoid_changes = ActiveScaffold.deprecated_positional_argument(
64
+ positional_avoid_changes, avoid_changes,
65
+ method_name: __method__, argument_name: :avoid_changes, default: false
66
+ )
61
67
  crud_type = parent_record.new_record? ? :create : :update
62
68
  return parent_record unless parent_record.authorized_for?(crud_type: crud_type)
63
69
 
@@ -91,7 +97,13 @@ module ActiveScaffold
91
97
  column.params.select { |p| attributes.key? p }.each { |p| parent_record.send(:"#{p}=", attributes[p]) }
92
98
  end
93
99
 
94
- def update_column_from_params(parent_record, column, attribute, avoid_changes = false)
100
+ def update_column_from_params(parent_record, column, attribute,
101
+ positional_avoid_changes = POSITIONAL_ARGUMENT_NOT_GIVEN,
102
+ avoid_changes: POSITIONAL_ARGUMENT_NOT_GIVEN)
103
+ avoid_changes = ActiveScaffold.deprecated_positional_argument(
104
+ positional_avoid_changes, avoid_changes,
105
+ method_name: __method__, argument_name: :avoid_changes, default: false
106
+ )
95
107
  value = column_value_from_param_value(parent_record, column, attribute, avoid_changes)
96
108
  if column.association
97
109
  update_column_association(parent_record, column, attribute, value, avoid_changes)
@@ -110,7 +122,13 @@ module ActiveScaffold
110
122
  parent_record.send(:"#{column.association.foreign_key}=", value&.id) if column.association.belongs_to?
111
123
  end
112
124
 
113
- def update_column_association(parent_record, column, attribute, value, avoid_changes = false)
125
+ def update_column_association(parent_record, column, attribute, value,
126
+ positional_avoid_changes = POSITIONAL_ARGUMENT_NOT_GIVEN,
127
+ avoid_changes: POSITIONAL_ARGUMENT_NOT_GIVEN)
128
+ avoid_changes = ActiveScaffold.deprecated_positional_argument(
129
+ positional_avoid_changes, avoid_changes,
130
+ method_name: __method__, argument_name: :avoid_changes, default: false
131
+ )
114
132
  if avoid_changes
115
133
  assign_column_association(parent_record, column, attribute, value)
116
134
  elsif column.association.collection? && column.association.through_singular?
@@ -126,7 +144,13 @@ module ActiveScaffold
126
144
  parent_record.association(column.name).target = value
127
145
  end
128
146
 
129
- def column_value_from_param_value(parent_record, column, value, avoid_changes = false)
147
+ def column_value_from_param_value(parent_record, column, value,
148
+ positional_avoid_changes = POSITIONAL_ARGUMENT_NOT_GIVEN,
149
+ avoid_changes: POSITIONAL_ARGUMENT_NOT_GIVEN)
150
+ avoid_changes = ActiveScaffold.deprecated_positional_argument(
151
+ positional_avoid_changes, avoid_changes,
152
+ method_name: __method__, argument_name: :avoid_changes, default: false
153
+ )
130
154
  # convert the value, possibly by instantiating associated objects
131
155
  form_ui = column.form_ui || column.column&.type
132
156
  if form_ui && respond_to?(:"column_value_for_#{form_ui}_type", true)
@@ -205,7 +229,13 @@ module ActiveScaffold
205
229
  end
206
230
  end
207
231
 
208
- def column_value_from_param_hash_value(parent_record, column, value, avoid_changes = false)
232
+ def column_value_from_param_hash_value(parent_record, column, value,
233
+ positional_avoid_changes = POSITIONAL_ARGUMENT_NOT_GIVEN,
234
+ avoid_changes: POSITIONAL_ARGUMENT_NOT_GIVEN)
235
+ avoid_changes = ActiveScaffold.deprecated_positional_argument(
236
+ positional_avoid_changes, avoid_changes,
237
+ method_name: __method__, argument_name: :avoid_changes, default: false
238
+ )
209
239
  if column.association&.singular?
210
240
  manage_nested_record_from_params(parent_record, column, value, avoid_changes)
211
241
  elsif column.association&.collection?
@@ -233,7 +263,13 @@ module ActiveScaffold
233
263
  columns ? subform_cfg.build_action_columns(columns) : subform_cfg.columns
234
264
  end
235
265
 
236
- def manage_nested_record_from_params(parent_record, column, attributes, avoid_changes = false)
266
+ def manage_nested_record_from_params(parent_record, column, attributes,
267
+ positional_avoid_changes = POSITIONAL_ARGUMENT_NOT_GIVEN,
268
+ avoid_changes: POSITIONAL_ARGUMENT_NOT_GIVEN)
269
+ avoid_changes = ActiveScaffold.deprecated_positional_argument(
270
+ positional_avoid_changes, avoid_changes,
271
+ method_name: __method__, argument_name: :avoid_changes, default: false
272
+ )
237
273
  return nil unless avoid_changes || build_record_from_params?(attributes, column, parent_record)
238
274
 
239
275
  record = find_or_create_for_params(attributes, column, parent_record, avoid_changes)
@@ -259,7 +295,13 @@ module ActiveScaffold
259
295
  # Attempts to create or find an instance of the klass of the association in parent_column from the
260
296
  # request parameters given. If params[primary_key] exists it will attempt to find an existing object
261
297
  # otherwise it will build a new one.
262
- def find_or_create_for_params(params, parent_column, parent_record, avoid_changes = false)
298
+ def find_or_create_for_params(params, parent_column, parent_record,
299
+ positional_avoid_changes = POSITIONAL_ARGUMENT_NOT_GIVEN,
300
+ avoid_changes: POSITIONAL_ARGUMENT_NOT_GIVEN)
301
+ avoid_changes = ActiveScaffold.deprecated_positional_argument(
302
+ positional_avoid_changes, avoid_changes,
303
+ method_name: __method__, argument_name: :avoid_changes, default: false
304
+ )
263
305
  current = parent_record.send(parent_column.name)
264
306
  klass = parent_column.association.klass(parent_record)
265
307
  if params.key? klass.primary_key
@@ -277,7 +319,13 @@ module ActiveScaffold
277
319
 
278
320
  # Attempts to find an instance of klass (which must be an ActiveRecord object) with id primary key
279
321
  # Returns record from current if it's included or find from DB
280
- def record_from_current_or_find(klass, id, current, avoid_changes = false)
322
+ def record_from_current_or_find(klass, id, current,
323
+ positional_avoid_changes = POSITIONAL_ARGUMENT_NOT_GIVEN,
324
+ avoid_changes: POSITIONAL_ARGUMENT_NOT_GIVEN)
325
+ avoid_changes = ActiveScaffold.deprecated_positional_argument(
326
+ positional_avoid_changes, avoid_changes,
327
+ method_name: __method__, argument_name: :avoid_changes, default: false
328
+ )
281
329
  record = record_from_current(current, id)
282
330
  record ||= klass.new(klass.primary_key => id) if avoid_changes
283
331
  record ||= klass.find(id)
@@ -3,6 +3,7 @@
3
3
  module ActiveScaffold::Actions
4
4
  module DeletedRecords
5
5
  def self.included(base)
6
+ base.before_action :deleted_authorized_filter, only: :deleted
6
7
  base.class_eval do
7
8
  config = active_scaffold_config
8
9
  if config.actions.include?(:nested) && config.deleted_records.nested_link_group
@@ -14,13 +15,7 @@ module ActiveScaffold::Actions
14
15
  end
15
16
 
16
17
  def deleted
17
- query = PaperTrail::Version.destroys.where(item_type: active_scaffold_config.model.name)
18
- if nested? && nested.child_association&.belongs_to? && PaperTrail::Version.respond_to?(:where_object)
19
- foreign_key = nested.child_association.foreign_key
20
- parent_id = nested.parent_id
21
- parent_id = parent_id&.to_i if self.class.active_scaffold_config.columns[foreign_key]&.number?
22
- query = query.where_object(foreign_key => parent_id)
23
- end
18
+ query = deleted_records_query
24
19
  pager = Paginator.new(query.count, active_scaffold_config.list.per_page) do |offset, per_page|
25
20
  query.offset(offset).limit(per_page).map(&:reify)
26
21
  end
@@ -29,5 +24,26 @@ module ActiveScaffold::Actions
29
24
  @records = @page.items
30
25
  respond_to_action(:list)
31
26
  end
27
+
28
+ protected
29
+
30
+ def deleted_records_query
31
+ query = PaperTrail::Version.destroys.where(item_type: active_scaffold_config.model.name)
32
+ if nested? && nested.child_association&.belongs_to? && PaperTrail::Version.respond_to?(:where_object)
33
+ foreign_key = nested.child_association.foreign_key
34
+ parent_id = nested.parent_id
35
+ parent_id = parent_id&.to_i if self.class.active_scaffold_config.columns[foreign_key]&.number?
36
+ query = query.where_object(foreign_key => parent_id)
37
+ end
38
+ query
39
+ end
40
+
41
+ def deleted_authorized?
42
+ list_authorized?
43
+ end
44
+
45
+ def deleted_authorized_filter
46
+ raise ActiveScaffold::ActionNotAllowed unless deleted_authorized?
47
+ end
32
48
  end
33
49
  end
@@ -4,7 +4,13 @@ module ActiveScaffold
4
4
  module Helpers
5
5
  module AssociationHelpers
6
6
  # Cache the options for select
7
- def cache_association_options(association, conditions, klass, cache = true)
7
+ def cache_association_options(association, conditions, klass,
8
+ positional_cache = POSITIONAL_ARGUMENT_NOT_GIVEN,
9
+ cache: POSITIONAL_ARGUMENT_NOT_GIVEN)
10
+ cache = ActiveScaffold.deprecated_positional_argument(
11
+ positional_cache, cache,
12
+ method_name: __method__, argument_name: :cache, default: true
13
+ )
8
14
  if active_scaffold_config.cache_association_options && cache
9
15
  @_associations_cache ||= Hash.new { |h, k| h[k] = {} }
10
16
  key = [association.name, association.inverse_klass.name, klass.respond_to?(:cache_key) ? klass.cache_key : klass.name].join('/')
@@ -52,7 +52,20 @@ module ActiveScaffold
52
52
  handle_exception_on_column(e, column, record)
53
53
  end
54
54
 
55
- def active_scaffold_render_subform_column(column, scope, crud_type, readonly, add_class = false, record = nil, form_columns: nil) # rubocop:disable Metrics/ParameterLists
55
+ def active_scaffold_render_subform_column(column, scope, crud_type, readonly, *positional_arguments,
56
+ add_class: POSITIONAL_ARGUMENT_NOT_GIVEN,
57
+ record: POSITIONAL_ARGUMENT_NOT_GIVEN, form_columns: nil)
58
+ raise ArgumentError, 'too many positional arguments' if positional_arguments.size > 2
59
+
60
+ positional_add_class = positional_arguments.fetch(0, POSITIONAL_ARGUMENT_NOT_GIVEN)
61
+ positional_record = positional_arguments.fetch(1, POSITIONAL_ARGUMENT_NOT_GIVEN)
62
+ add_class = ActiveScaffold.deprecated_positional_argument(
63
+ positional_add_class, add_class,
64
+ method_name: __method__, argument_name: :add_class, default: false
65
+ )
66
+ record = ActiveScaffold.positional_or_keyword_argument(
67
+ positional_record, record, argument_name: :record, default: nil
68
+ )
56
69
  if add_class
57
70
  col_class = []
58
71
  col_class << 'required' if column.required?(action_for_validation(record))
@@ -156,7 +169,13 @@ module ActiveScaffold
156
169
  url_params
157
170
  end
158
171
 
159
- def update_columns_options(column, scope, options, force = false, form_columns: nil, url_params: {})
172
+ def update_columns_options(column, scope, options,
173
+ positional_force = POSITIONAL_ARGUMENT_NOT_GIVEN,
174
+ force: POSITIONAL_ARGUMENT_NOT_GIVEN, form_columns: nil, url_params: {})
175
+ force = ActiveScaffold.deprecated_positional_argument(
176
+ positional_force, force,
177
+ method_name: __method__, argument_name: :force, default: false
178
+ )
160
179
  record = options[:object]
161
180
  subform_controller = controller.class.active_scaffold_controller_for(record.class) if scope
162
181
  form_columns ||= current_form_columns(record, scope, subform_controller)
@@ -249,7 +268,20 @@ module ActiveScaffold
249
268
  as_element(:form_field_description, h(desc) + as_element(:form_field_description_close)) if desc.present?
250
269
  end
251
270
 
252
- def form_attribute(column, record, scope = nil, only_value = false, col_class = nil, form_columns: nil, field: nil)
271
+ def form_attribute(column, record, scope = nil, *positional_arguments,
272
+ only_value: POSITIONAL_ARGUMENT_NOT_GIVEN,
273
+ col_class: POSITIONAL_ARGUMENT_NOT_GIVEN, form_columns: nil, field: nil)
274
+ raise ArgumentError, 'too many positional arguments' if positional_arguments.size > 2
275
+
276
+ positional_only_value = positional_arguments.fetch(0, POSITIONAL_ARGUMENT_NOT_GIVEN)
277
+ positional_col_class = positional_arguments.fetch(1, POSITIONAL_ARGUMENT_NOT_GIVEN)
278
+ only_value = ActiveScaffold.deprecated_positional_argument(
279
+ positional_only_value, only_value,
280
+ method_name: __method__, argument_name: :only_value, default: false
281
+ )
282
+ col_class = ActiveScaffold.positional_or_keyword_argument(
283
+ positional_col_class, col_class, argument_name: :col_class, default: nil
284
+ )
253
285
  column_options = active_scaffold_input_options(column, scope, object: record)
254
286
  collapsible_id = column_options.delete :collapsible_id
255
287
  attributes = field_attributes(column, record)
@@ -293,14 +325,26 @@ module ActiveScaffold
293
325
  column.label unless hidden
294
326
  end
295
327
 
296
- def form_hidden_attribute(column, record, scope = nil, clear = false)
328
+ def form_hidden_attribute(column, record, scope = nil,
329
+ positional_clear = POSITIONAL_ARGUMENT_NOT_GIVEN,
330
+ clear: POSITIONAL_ARGUMENT_NOT_GIVEN)
331
+ clear = ActiveScaffold.deprecated_positional_argument(
332
+ positional_clear, clear,
333
+ method_name: __method__, argument_name: :clear, default: false
334
+ )
297
335
  content_tag :dl, style: 'display: none' do
298
336
  content_tag(:dt, '') <<
299
337
  content_tag(:dd, form_hidden_field(column, record, scope, clear))
300
338
  end
301
339
  end
302
340
 
303
- def form_hidden_field(column, record, scope, clear = false)
341
+ def form_hidden_field(column, record, scope,
342
+ positional_clear = POSITIONAL_ARGUMENT_NOT_GIVEN,
343
+ clear: POSITIONAL_ARGUMENT_NOT_GIVEN)
344
+ clear = ActiveScaffold.deprecated_positional_argument(
345
+ positional_clear, clear,
346
+ method_name: __method__, argument_name: :clear, default: false
347
+ )
304
348
  options = active_scaffold_input_options(column, scope)
305
349
  value = record.send(column.name) unless clear
306
350
  if column.association&.collection?
@@ -57,7 +57,12 @@ module ActiveScaffold
57
57
 
58
58
  # This is the template finder logic, keep it updated with however we find stuff in rails
59
59
  # currently this very similar to the logic in ActionBase::Base.render for options file
60
- def template_exists?(template_name, partial = false)
60
+ def template_exists?(template_name, positional_partial = POSITIONAL_ARGUMENT_NOT_GIVEN,
61
+ partial: POSITIONAL_ARGUMENT_NOT_GIVEN)
62
+ partial = ActiveScaffold.deprecated_positional_argument(
63
+ positional_partial, partial,
64
+ method_name: __method__, argument_name: :partial, default: false
65
+ )
61
66
  if @_view_paths
62
67
  restore_view_paths = lookup_context.view_paths
63
68
  lookup_context.view_paths = @_view_paths
@@ -4,7 +4,7 @@ module ActiveScaffold
4
4
  module Version
5
5
  MAJOR = 4
6
6
  MINOR = 4
7
- PATCH = 4
7
+ PATCH = 5
8
8
  FIX = nil
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH, FIX].compact.join('.')
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveScaffold
4
+ POSITIONAL_ARGUMENT_NOT_GIVEN = Object.new.freeze
5
+
4
6
  autoload :ActiveRecordPermissions, 'active_scaffold/active_record_permissions'
5
7
  autoload :Assets, 'active_scaffold/assets'
6
8
  autoload :AttributeParams, 'active_scaffold/attribute_params'
@@ -260,7 +262,33 @@ module ActiveScaffold
260
262
  end
261
263
 
262
264
  def self.deprecator
263
- @deprecator ||= ActiveSupport::Deprecation.new('4.3', 'ActiveScaffold')
265
+ @deprecator ||= ActiveSupport::Deprecation.new('4.5', 'ActiveScaffold')
266
+ end
267
+
268
+ def self.deprecated_positional_argument(positional, keyword, method_name:, argument_name:, default:)
269
+ if positional.equal?(POSITIONAL_ARGUMENT_NOT_GIVEN)
270
+ keyword.equal?(POSITIONAL_ARGUMENT_NOT_GIVEN) ? default : keyword
271
+ elsif keyword.equal?(POSITIONAL_ARGUMENT_NOT_GIVEN)
272
+ deprecator.warn(
273
+ "Passing `#{argument_name}` positionally to `#{method_name}` is deprecated; " \
274
+ "use `#{argument_name}:` instead. Positional support will be removed in ActiveScaffold 4.5. " \
275
+ 'Overrides must accept both forms during 4.4 and pass the argument to `super` as a keyword. ' \
276
+ 'See https://github.com/activescaffold/active_scaffold/blob/4-4-stable/CHANGELOG.rdoc'
277
+ )
278
+ positional
279
+ else
280
+ raise ArgumentError, "#{argument_name} was given both positionally and as a keyword"
281
+ end
282
+ end
283
+
284
+ def self.positional_or_keyword_argument(positional, keyword, argument_name:, default:)
285
+ if positional.equal?(POSITIONAL_ARGUMENT_NOT_GIVEN)
286
+ keyword.equal?(POSITIONAL_ARGUMENT_NOT_GIVEN) ? default : keyword
287
+ elsif keyword.equal?(POSITIONAL_ARGUMENT_NOT_GIVEN)
288
+ positional
289
+ else
290
+ raise ArgumentError, "#{argument_name} was given both positionally and as a keyword"
291
+ end
264
292
  end
265
293
 
266
294
  def self.log_exception(exception, message)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_scaffold
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.4
4
+ version: 4.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Many, see README