para 0.12.5 → 0.12.7

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: bac06958cd2f4e9d4d35a59338f77934fcb812341d56778e2284f8165a18b978
4
- data.tar.gz: '085f64e0d60c60e5562219db39a1fdc90d37eaa3e549918bed9a80814ac3acca'
3
+ metadata.gz: 5339b2dc5c28403fd3e4ba08fbb1bfc7b2b2196269f9927d25eb1d428eb99d71
4
+ data.tar.gz: 6266de04143dbd8e18aa9826e8a007d2d96909d4d4f6d9704791e30893f0cffe
5
5
  SHA512:
6
- metadata.gz: 6f32e3e3bd4c33a87ca98f900a0d46d03cc005737eb9131dd3395cb7247e0e926d45ceeefb2c8215f87eda98c19f77dd3e59b841d84dd544e250010fb8422f8f
7
- data.tar.gz: 748a7875b0783387d1ebb8fbcb545827431e908aedd5381580a6aeed0703acf7354ef9aec4d03899110574e6cdd9071555519d86b441d0b812047bb6c56063af
6
+ metadata.gz: aa7cfd1587567f56a06853bfc0acf74736d4082d79a59f51af90de4fc4afc4fc840085e1e4580aa8372eee4e6e2299584f262ba7d064ee47fffc4abf71ed6fd9
7
+ data.tar.gz: 5ad58a35c8f690c2ce70063f12cc04ebf0f2e1b812ea22c8f2918193f16e3b7f98a4758b0a780affbb3e7e72a4f319906dae122c650bd3c183aba84ac2a4db14
@@ -13,6 +13,5 @@
13
13
  - form.object_name = @object_name
14
14
  - nested_form = capture do
15
15
  = render(partial: find_partial_for(@model, :remote_nested_form), locals: { form: form, model: @model, object: @object, object_name: @object_name })
16
- = form.attributes_mappings_field_for(form)
17
16
 
18
17
  = nested_form
@@ -1,2 +1,2 @@
1
- = link_to_add_association form, attribute_name, partial: find_partial_for(model, 'nested_many/container', partial_dir: 'inputs'), form_name: 'form', class: "btn btn-shadow add-button nested-many-inset-add-button #{add_button_class}", data: { :'association-insertion-node' => "##{ dom_identifier }", :'association-insertion-method' => 'append' }, render_options: { nested_attribute_name: attribute_name, orderable: orderable, locals: { model: model, nested_locals: nested_locals, inset: inset, uncollapsed: uncollapsed, allow_destroy_if: allow_destroy_if, render_partial: render_partial, remote_partial_params: remote_partial_params } } do
1
+ = link_to_add_association form, attribute_name, partial: find_partial_for(model, 'nested_many/container', partial_dir: 'inputs'), form_name: 'form', class: "btn btn-shadow add-button nested-many-inset-add-button #{add_button_class}", data: { :'association-insertion-node' => "##{ dom_identifier }", :'association-insertion-method' => 'append' }, render_options: { nested_attribute_name: attribute_name, orderable: orderable, track_attribute_mappings: render_partial, locals: { model: model, nested_locals: nested_locals, inset: inset, uncollapsed: uncollapsed, allow_destroy_if: allow_destroy_if, render_partial: render_partial, remote_partial_params: remote_partial_params } } do
2
2
  = add_button_label
@@ -1,7 +1,7 @@
1
1
  - if subclasses.one?
2
2
  - submodel = subclasses.first
3
3
 
4
- = link_to_add_association form, attribute_name, wrap_object: proc { with_inverse_association_for(submodel.new, attribute_name, form.object) }, partial: find_partial_for(model, 'nested_many/container', partial_dir: 'inputs'), form_name: 'form', class: "btn btn-shadow add-button nested-many-inset-add-button #{add_button_class}", data: { :'association-insertion-node' => "##{ dom_identifier }", :'association-insertion-method' => 'append' }, render_options: { nested_attribute_name: attribute_name, orderable: orderable, locals: { model: submodel, nested_locals: nested_locals, inset: inset, uncollapsed: uncollapsed, render_partial: render_partial, remote_partial_params: remote_partial_params, allow_destroy_if: allow_destroy_if } } do
4
+ = link_to_add_association form, attribute_name, wrap_object: proc { with_inverse_association_for(submodel.new, attribute_name, form.object) }, partial: find_partial_for(model, 'nested_many/container', partial_dir: 'inputs'), form_name: 'form', class: "btn btn-shadow add-button nested-many-inset-add-button #{add_button_class}", data: { :'association-insertion-node' => "##{ dom_identifier }", :'association-insertion-method' => 'append' }, render_options: { nested_attribute_name: attribute_name, orderable: orderable, track_attribute_mappings: render_partial, locals: { model: submodel, nested_locals: nested_locals, inset: inset, uncollapsed: uncollapsed, render_partial: render_partial, remote_partial_params: remote_partial_params, allow_destroy_if: allow_destroy_if } } do
5
5
  = add_button_label
6
6
  - else
7
7
  .add-button.nested-many-inset-add-button.dropdown
@@ -11,5 +11,5 @@
11
11
  %ul.dropdown-menu
12
12
  - subclasses.each do |submodel|
13
13
  %li
14
- = link_to_add_association form, attribute_name, wrap_object: proc { with_inverse_association_for(submodel.new, attribute_name, form.object) }, partial: find_partial_for(submodel, 'nested_many/container', partial_dir: 'inputs'), form_name: 'form', class: 'dropdown-link', data: { :'association-insertion-node' => "##{ dom_identifier }", :'association-insertion-method' => 'append' }, render_options: { nested_attribute_name: attribute_name, orderable: orderable, locals: { model: submodel, nested_locals: nested_locals, inset: inset, uncollapsed: uncollapsed, allow_destroy_if: allow_destroy_if, render_partial: render_partial, remote_partial_params: remote_partial_params } } do
14
+ = link_to_add_association form, attribute_name, wrap_object: proc { with_inverse_association_for(submodel.new, attribute_name, form.object) }, partial: find_partial_for(submodel, 'nested_many/container', partial_dir: 'inputs'), form_name: 'form', class: 'dropdown-link', data: { :'association-insertion-node' => "##{ dom_identifier }", :'association-insertion-method' => 'append' }, render_options: { nested_attribute_name: attribute_name, orderable: orderable, track_attribute_mappings: render_partial, locals: { model: submodel, nested_locals: nested_locals, inset: inset, uncollapsed: uncollapsed, allow_destroy_if: allow_destroy_if, render_partial: render_partial, remote_partial_params: remote_partial_params } } do
15
15
  = submodel.model_name.human
@@ -97,10 +97,7 @@ module Para
97
97
  # This is not the most optimized solution, but works well enough as if the
98
98
  # author's posts match previously cloned posts, they won't be cloned as they'll
99
99
  # exist in the cloned resources dictionary.
100
- next if path.length >= 4 &&
101
- path[-4] == path[-2] &&
102
- path[-2] == reflection_name &&
103
- path[-3] == path[-1]
100
+ next if circular_reference?(path, reflection_name)
104
101
 
105
102
  hash[reflection_name] = {}
106
103
 
@@ -140,6 +137,8 @@ module Para
140
137
  options = nested_resource.class.try(:cloneable_options)
141
138
  return reflection_options unless options
142
139
 
140
+ puts "Building cloneable options for #{nested_resource.class.name} at path #{path.join(' -> ')}"
141
+
143
142
  target_options = build_cloneable_options_tree(nested_resource, path)
144
143
  reflection_options.deep_merge!(target_options)
145
144
  end
@@ -191,6 +190,43 @@ module Para
191
190
 
192
191
  deep_relations.empty? ? shallow_relations : shallow_relations + [deep_relations]
193
192
  end
193
+
194
+ # Checks if adding reflection_name to the path would create a circular reference
195
+ # of 2 levels deep with a cycle length between 2 and 10.
196
+ #
197
+ # Examples of detected patterns:
198
+ #
199
+ # Length 2: [:a, :b, :a, :b]
200
+ # Length 3: [:a, :b, :c, :a, :b, :c]
201
+ # Length 4: [:a, :b, :c, :d, :a, :b, :c, :d]
202
+ #
203
+ def circular_reference?(path, reflection_name)
204
+ # Check for cycle lengths from 2 to 10
205
+ (2..10).each do |cycle_length|
206
+ # We need at least 2 * cycle_length elements in the path to detect a cycle
207
+ required_length = cycle_length * 2
208
+ next if path.length < required_length
209
+
210
+ # Check if the pattern repeats exactly twice
211
+ # The new reflection_name would be at position -cycle_length
212
+ match = true
213
+
214
+ # First, check if the element at -cycle_length position matches reflection_name
215
+ next unless path[-cycle_length] == reflection_name
216
+
217
+ # Then check if all other elements in the first cycle match the second cycle
218
+ (1...cycle_length).each do |offset|
219
+ if path[-(cycle_length + offset)] != path[-offset]
220
+ match = false
221
+ break
222
+ end
223
+ end
224
+
225
+ return true if match
226
+ end
227
+
228
+ false
229
+ end
194
230
  end
195
231
  end
196
232
  end
@@ -1,7 +1,7 @@
1
1
  module Para
2
2
  module FormBuilder
3
3
  module AttributesMappingsTracker
4
- def initialize(*) #:nodoc:
4
+ def initialize(*) # :nodoc:
5
5
  @attributes_mappings = {}
6
6
 
7
7
  super
@@ -22,10 +22,9 @@ module Para
22
22
  def fields_for(*args, &block)
23
23
  fields_options = args.extract_options!
24
24
 
25
- track_attribute_mappings = (
25
+ track_attribute_mappings =
26
26
  fields_options[:track_attribute_mappings] != false &&
27
27
  options[:track_attribute_mappings]
28
- )
29
28
 
30
29
  fields_options.reverse_merge!(
31
30
  track_attribute_mappings: track_attribute_mappings
@@ -42,7 +41,7 @@ module Para
42
41
  return unless options[:track_attribute_mappings]
43
42
 
44
43
  hidden_field :_attributes_mappings, value: @attributes_mappings.to_json,
45
- data: { :'attributes-mappings' => fields.options[:child_index] }
44
+ data: { 'attributes-mappings': fields.options[:child_index] }
46
45
  end
47
46
 
48
47
  private
@@ -51,11 +50,11 @@ module Para
51
50
  return unless options[:track_attribute_mappings]
52
51
 
53
52
  type = if input_options[:as]
54
- input_options[:as]
55
- else
56
- input = find_input(attribute_name, input_options, &block)
57
- input.class.name.demodulize.underscore.gsub(/_input\z/, '')
58
- end
53
+ input_options[:as]
54
+ else
55
+ input = find_input(attribute_name, input_options, &block)
56
+ input.class.name.demodulize.underscore.gsub(/_input\z/, '')
57
+ end
59
58
 
60
59
  @attributes_mappings[attribute_name] = type
61
60
  end
data/lib/para/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Para
4
- VERSION = '0.12.5'
4
+ VERSION = '0.12.7'
5
5
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: para
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.5
4
+ version: 0.12.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Valentin Ballestrino
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-02-10 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: active_decorator
@@ -777,7 +776,6 @@ homepage: http://github.com/glyph-fr/para
777
776
  licenses:
778
777
  - MIT
779
778
  metadata: {}
780
- post_install_message:
781
779
  rdoc_options: []
782
780
  require_paths:
783
781
  - lib
@@ -792,8 +790,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
792
790
  - !ruby/object:Gem::Version
793
791
  version: '0'
794
792
  requirements: []
795
- rubygems_version: 3.5.16
796
- signing_key:
793
+ rubygems_version: 3.6.9
797
794
  specification_version: 4
798
795
  summary: Rails admin engine
799
796
  test_files: []