snake-eyes 0.0.5 → 0.0.6

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
  SHA1:
3
- metadata.gz: 5fae63d42cba9d54bdc028a5faf8d63d7b48b238
4
- data.tar.gz: b0abda0615edcd1d1b266755015e2e249c41950d
3
+ metadata.gz: e864c134f12799380649a3f8e1ac71078a5da5f0
4
+ data.tar.gz: eeaeffe93ed1ab87c316167986230f6ce3a66409
5
5
  SHA512:
6
- metadata.gz: 377e94c1eb0a2f12c477a89a661eeda7529f38d86147814c5ca412847b64bedca2d36b78e857d73104a9e7f6980f0ea050d1b689ff828ed2d10b8281152d4a44
7
- data.tar.gz: 1f23f3f3a5661bb09b63c24f1b4ebaeb056884087fc666e93f805312450ba23c04c0f4dbca2976522ade9c17919b07dbe08f61c137d040284659d6d90bb6f6d9
6
+ metadata.gz: 8ce2f7325ff93e48f4eddb75beee3515ec16a94e3fc944fcbcb53a6ddd44e12925d31bdf8c43e4133329a915d36aec461325dcac586b5d37c252b58c6dfbdda8
7
+ data.tar.gz: ae13b1c19fe7b78909336fe32733443ddc0f486aea27359a223dd366fd6143544a4380a663c784d91b3b0d5877e741379b6e86bd63a5e1c8a5026cc2325953fb
data/README.md CHANGED
@@ -6,7 +6,7 @@ Automatically convert between camel case APIs to snake case for your Rails code
6
6
 
7
7
  🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧
8
8
 
9
- If you are using a version below `0.0.4`, please upgrade to avoid [potentially logging sensitive user information](https://github.com/greena13/snake-eyes/issues/1)
9
+ If you are using a version below `0.0.4`, please upgrade to avoid [potentially logging sensitive user information](https://github.com/greena13/snake-eyes/issues/1)
10
10
 
11
11
  ## Installation
12
12
 
@@ -45,8 +45,8 @@ Once `snake_eyes_params` has been enabled for a controllor, `params` accepts an
45
45
  # 'user' => {
46
46
  # 'name' => 'John Smith',
47
47
  # 'favouriteColor' => 'blue',
48
- # 'address' => { '123 street' },
49
- # 'billingAddress' => { '456 road' }
48
+ # 'address' => { line1: '123 street' },
49
+ # 'billingAddress' => { line1: '456 road' }
50
50
  # }
51
51
  #}
52
52
  end
@@ -61,8 +61,8 @@ Once `snake_eyes_params` has been enabled for a controllor, `params` accepts an
61
61
  # 'user_attributes' => {
62
62
  # 'name' => 'John Smith',
63
63
  # 'favourite_color' => 'blue',
64
- # 'address_attributes' => { '123 street' },
65
- # 'billing_address_attributes' => { '456 road' }
64
+ # 'address_attributes' => { line1: '123 street' },
65
+ # 'billing_address_attributes' => { line1: '456 road' }
66
66
  # }
67
67
  #}
68
68
  end
@@ -82,8 +82,8 @@ To specify nested objects that should not have the `_attributes` suffix (but con
82
82
  # 'user' => {
83
83
  # 'name' => 'John Smith',
84
84
  # 'favourite_color' => 'blue',
85
- # 'address_attributes' => { '123 street' },
86
- # 'billing_address_attributes' => { '456 road' }
85
+ # 'address_attributes' => { 'line1: 123 street' },
86
+ # 'billing_address_attributes' => { line1: '456 road' }
87
87
  # }
88
88
  #}
89
89
  end
@@ -3,49 +3,82 @@ module SnakeEyes
3
3
  def params(options = {})
4
4
  validate_options(options)
5
5
 
6
- untransformed_params = super()
6
+ original_params = super()
7
7
 
8
- traverse_positions = [
9
- untransformed_params
8
+ return original_params unless original_params.any?
9
+
10
+ # List of subtrees maintained to mark the depth-first traversal's position
11
+ # throughout the transformation of the original param's keys, whereby the
12
+ # last element is the traversal's current position and backtracking (going
13
+ # from child to parent) is achieved by popping off the last element.
14
+
15
+ original_params_sub_trees = [
16
+ original_params
10
17
  ]
11
18
 
12
- nested_attributes = nested_attributes_hash(options[:nested_attributes])
19
+ # Convert the relatively flat format used to specify the nested attributes
20
+ # (easier for specification) into a series of nested objects (easier for
21
+ # look-ups)
22
+
23
+ nested_schema = build_nested_schema(options[:nested_attributes] || {})
24
+
25
+ @previous_params ||= { }
13
26
 
14
- nested_attributes_positions = [
15
- nested_attributes
27
+ return @previous_params[nested_schema] if @previous_params[nested_schema]
28
+
29
+ # Similar to original_params_sub_trees, a list of subtrees used to maintain
30
+ # the traversal position of nested_schema. This is kept in sync with the
31
+ # traversal of original_params, to ensure the correct leaf of
32
+ # nested_schema is checked at each point in the traversal of original_params
33
+
34
+ nested_schema_sub_trees = [
35
+ nested_schema
16
36
  ]
17
37
 
18
- transformed_params = untransformed_params.deep_transform_keys do |key|
19
- underscored_key = key.underscore
38
+ transformed_params = original_params.deep_transform_keys do |original_key|
39
+ # The matching leaf of nested_schema for this point in the traversal
40
+ nested_schema_sub_tree = nested_schema_sub_trees.last
20
41
 
21
- nested_attributes_position = nested_attributes_positions.last
42
+ # Append the '_attributes' suffix if the original params key has the
43
+ # same name and is nested in the same place as one mentioned in the
44
+ # nested_attributes option
45
+
46
+ transformed_key_base = original_key.underscore
22
47
 
23
48
  transformed_key =
24
- if nested_attributes_position[underscored_key]
25
- underscored_key + '_attributes'
49
+ if nested_schema_sub_tree[transformed_key_base]
50
+ transformed_key_base + '_attributes'
26
51
  else
27
- underscored_key
52
+ transformed_key_base
28
53
  end
29
54
 
30
- while traverse_positions.length > 1 && traverse_positions.last[key].nil?
31
- traverse_positions.pop
32
- nested_attributes_positions.pop
55
+ # Synchronise the original params sub-tree with the current key being
56
+ # transformed. We can detect that the sub-tree is stale because the key
57
+ # being transformed does not appear amongst its own. When the sub-tree is
58
+ # indeed stale, move the position to its parent for the original params
59
+ # sub-tree and the nested schema sub-tree and repeat the check.
60
+
61
+ while original_params_sub_trees.length > 1 && original_params_sub_trees.last[original_key].nil?
62
+ original_params_sub_trees.pop
63
+ nested_schema_sub_trees.pop
33
64
  end
34
65
 
35
- current_position = traverse_positions.last[underscored_key]
66
+ original_params_sub_tree = original_params_sub_trees.last[transformed_key_base]
36
67
 
37
- if current_position.kind_of?(Hash)
38
- traverse_positions.push(current_position)
68
+ if original_params_sub_tree.kind_of?(Hash)
69
+ original_params_sub_trees.push(original_params_sub_tree)
39
70
 
40
- nested_attributes_positions.push(
41
- nested_attributes_position[underscored_key] || nested_attributes_position['_' + underscored_key] || {}
71
+ nested_schema_sub_trees.push(
72
+ nested_schema_sub_tree[transformed_key_base] ||
73
+ nested_schema_sub_tree['_' + transformed_key_base] ||
74
+ {}
42
75
  )
43
76
  end
44
77
 
45
78
  transformed_key
46
79
  end
47
80
 
48
- @snake_eyes_params = ActionController::Parameters.new(transformed_params)
81
+ @previous_params[nested_schema] = @snake_eyes_params = ActionController::Parameters.new(transformed_params)
49
82
 
50
83
  log_snakized_params
51
84
 
@@ -62,26 +95,34 @@ module SnakeEyes
62
95
 
63
96
  def log_snakized_params
64
97
  if SnakeEyes.log_snake_eyes_parameters
98
+
65
99
  ignored_params = ActionController::LogSubscriber::INTERNAL_PARAMS
66
100
  filtered_params = request.send(:parameter_filter).filter(@snake_eyes_params.except(*ignored_params))
101
+
67
102
  logger.info " SnakeEyes Parameters: #{filtered_params.inspect}"
68
103
  end
69
104
  end
70
105
 
71
- def nested_attributes_hash(attributes_list = [])
106
+ def build_nested_schema(attributes_list = [])
72
107
 
73
108
  if attributes_list.kind_of?(Array)
109
+
74
110
  attributes_list.inject({}) do |memo, nested_attribute|
75
- memo.merge(nested_attributes_hash(nested_attribute))
111
+ memo.merge(build_nested_schema(nested_attribute))
76
112
  end
113
+
77
114
  elsif attributes_list.kind_of?(Hash)
115
+
78
116
  attributes_list.inject({}) do |memo, key_and_value|
79
117
  key, value = key_and_value
80
- memo[key.to_s] = nested_attributes_hash(value)
118
+ memo[key.to_s] = build_nested_schema(value)
81
119
  memo
82
120
  end
121
+
83
122
  else
123
+
84
124
  { attributes_list.to_s.underscore => {} }
125
+
85
126
  end
86
127
 
87
128
  end
@@ -1,3 +1,3 @@
1
1
  module SnakeEyes
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snake-eyes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aleck Greenham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-08 00:00:00.000000000 Z
11
+ date: 2017-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler