merge_params 0.3.0 → 0.4.0

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: d02292b14bbd8378da9306edaaf9ba131f54bf7a638ce247c96db14f10ef7e80
4
- data.tar.gz: f86ffa29a81b4d8d427f99757f18ee4b505727830c7fb8b8e3459bd8fe4e3d1b
3
+ metadata.gz: 50468b8b15c7c21253bc50acaaa50f423eb45f012373ec5d09e96d8477fa115d
4
+ data.tar.gz: a3733c9745be932c2c7792aee32966a8cb5b7c36a67785b63afe9094e8858a74
5
5
  SHA512:
6
- metadata.gz: f14c18536515ec20bc11ab826acb0eabf8b417ee485a844eb3cb9fbf9e0d7ee24428e146f2f42ca79f10281cb68d12c1d0faca6159869634c65e3b9292827cac
7
- data.tar.gz: e4c02db3a74fdb11ecc5b2ff4aa8a0ad65e0c2615af1c6338a6df4afc67e968391e1aa5a7f76b37c2f90f2b5f3e03e5aef8abe82ab8a005a53cbdea2acc0169f
6
+ metadata.gz: 458352f9fae2cc4f410886360880c8261466d1c1358bc52cbb40f6bc79268c1752a5a6962308ce34021da751eb392b6c46b4b78bfcc95a9ce53a6aecb2e6dfc4
7
+ data.tar.gz: da60236fa26260b6d227b7923b7562f455962256f247e6fff84fdbb1c5f6008f6d2b9f653f22452bc6df0472ce1463e97e8f61f247862d433d64636ab060e05b
@@ -5,6 +5,14 @@ recommendations of [keepachangelog.com](http://keepachangelog.com/).
5
5
 
6
6
  ## (Unreleased)
7
7
 
8
+ ## 0.4.0 (2019-02-07)
9
+
10
+ ### Added/Changed
11
+ - Better support for nested hashes: Using `deep_symbolize_keys` instead of `symbolize_keys`.
12
+ - Allow keys in nested hashes to be deleted by setting their value to nil
13
+ - Add `params_from_url(url)` helper
14
+ - Allow a hash to be passed as an argument to `params_for_url_for`
15
+ - Add dependency on `facets` gem
8
16
 
9
17
  ## 0.3.0 (2019-01-24)
10
18
 
@@ -0,0 +1,31 @@
1
+ require 'facets/hash/recursively'
2
+
3
+ class Hash
4
+ def recursively_comparing(other_enum, path: [], &block)
5
+ ComparingRecursor.new(self, other_enum, &block)
6
+ end
7
+
8
+ class ComparingRecursor < Enumerable::Recursor #:nodoc:
9
+ def initialize(enum, other_enum, *types, &block)
10
+ @other_enum = other_enum
11
+ super(enum, *types, &block)
12
+ end
13
+ def method_missing(op, &yld)
14
+ yld = yld || lambda{ |k,v| [k,v] } # ? to_enum
15
+ rec = @block || yld #lambda{ |k,v| [k,v] }
16
+ @enum.__send__(op) do |k,v|
17
+ other_v = @other_enum.dig(k)
18
+ #puts %(#{@enum.inspect}: k=#{k.inspect}, v=#{v.inspect}, other_v=#{other_v.inspect})
19
+ case v
20
+ when String # b/c of 1.8
21
+ yld.call(k, v, other_v)
22
+ when *@types
23
+ res = v.recursively_comparing(other_v, &@block).__send__(op,&yld)
24
+ rec.call(k, res, other_v)
25
+ else
26
+ yld.call(k, v, other_v)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,25 +1,30 @@
1
1
  require 'uri'
2
+ require 'facets/hash/deep_merge'
3
+ require 'facets/hash/recurse'
4
+ require 'facets/hash/recursively_comparing'
5
+ require 'facets/enumerable/graph'
6
+ require 'facets/hash/graph'
2
7
 
3
8
  module MergeParams::Helpers
4
9
  extend ActiveSupport::Concern
5
10
 
6
11
  # request.parameters but with symbolized keys.
7
12
  def request_params
8
- request.parameters.symbolize_keys
13
+ request.parameters.deep_symbolize_keys
9
14
  end
10
15
 
11
16
  # request.parameters (which also includes POST params) but with only those keys that would
12
17
  # normally be passed in a query string (without :controller, :action, :format) and with symbolized
13
18
  # keys.
14
19
  def query_params_from_request_params
15
- request.parameters.symbolize_keys.
16
- except(*request.path_parameters.symbolize_keys.keys)
20
+ request.parameters.deep_symbolize_keys.
21
+ except(*request.path_parameters.deep_symbolize_keys.keys)
17
22
  end
18
23
 
19
24
  # Returns a hash of params from the query string (https://en.wikipedia.org/wiki/Query_string),
20
25
  # with symbolized keys.
21
26
  def query_params
22
- request.query_parameters.symbolize_keys
27
+ request.query_parameters.deep_symbolize_keys
23
28
  end
24
29
 
25
30
  # Params that can safely be passed to url_for to build a route. (Used by merge_url_for.)
@@ -40,8 +45,9 @@ module MergeParams::Helpers
40
45
  # (And we don't even need to pass the path_parameters on to url_for because url_for already
41
46
  # includes those (from :_recall)
42
47
  #
43
- def params_for_url_for
44
- params.to_unsafe_h.symbolize_keys.except(
48
+ def params_for_url_for(params = params())
49
+ params = params.to_unsafe_h if params.respond_to?(:to_unsafe_h)
50
+ params.deep_symbolize_keys.except(
45
51
  *ActionDispatch::Routing::RouteSet::RESERVED_OPTIONS,
46
52
  :controller,
47
53
  :action,
@@ -51,7 +57,8 @@ module MergeParams::Helpers
51
57
 
52
58
  # Safely merges the given params with the params from the current request
53
59
  def merge_params(new_params = {})
54
- params_for_url_for.merge(new_params)
60
+ params_for_url_for.
61
+ merge(new_params.deep_symbolize_keys)
55
62
  end
56
63
 
57
64
  # Easily extract just certain param keys.
@@ -83,31 +90,31 @@ module MergeParams::Helpers
83
90
  def merge_url_for(new_params = {})
84
91
  url = url_for(merge_params(new_params))
85
92
 
86
- # Now pass along in the *query string* any params that we couldn't pass to url_for because they
87
- # were reserved options.
88
- query_params_already_added = parse_nested_query(URI(url).query || '')
89
- # Some params from new_params (like company_id) that we pass in may be recognized by a route and
90
- # therefore no longer be query params. We use recognize_path to find those params that ended up
91
- # as route params instead of query_params but are nonetheless aready added to the url.
92
- params_already_added = Rails.application.routes.recognize_path(url).merge(query_params_already_added)
93
- keys_already_added = params_already_added.keys
94
- # Allow keys that are currently in query_params to be deleted by setting their value to nil in
95
- # new_params.
96
- keys_to_delete = new_params.select {|k,v| v.nil?}.keys
97
- query_params_to_add = query_params.except(*keys_already_added + keys_to_delete)
93
+ # # Now pass along in the *query string* any params that we couldn't pass to url_for because they
94
+ # # were reserved options.
95
+ # query_params_already_added = parse_nested_query(URI(url).query || '')
96
+ # # Some params from new_params (like company_id) that we pass in may be recognized by a route and
97
+ # # therefore no longer be query params. We use recognize_path to find those params that ended up
98
+ # # as route params instead of query_params but are nonetheless already added to the url.
99
+ # params_already_added = Rails.application.routes.recognize_path(url).merge(query_params_already_added)
100
+ params_already_added = params_from_url(url)
101
+ query_params_to_add = new_params.recursively_comparing(params_already_added).graph { |k,v, other|
102
+ if v.is_a?(Hash) || v.nil? || other.nil?
103
+ [k, v]
104
+ end
105
+ }
98
106
  add_params(query_params_to_add, url)
99
107
  end
100
108
 
101
109
  # Adds params to the query string
102
110
  # (Unlike url_for_merge, which tries to generate a route from the params.)
103
- # TODO: Should URL be first like https://libraries.io/github/jordanmaguire/uri_query_merger ?
104
- # UriQueryMerger.new("http://www.google.com?other=1", {jordan: "rules"}).merge
105
- # Can we make it work that way when a URL is supplied buth otherwise let the params be the first
106
- # and only argument (to optimize for that more common use case)?
107
- def add_params(params = {}, url = request.fullpath)
111
+ def add_params(new_params = {}, url = request.fullpath)
108
112
  uri = URI(url)
109
- params = parse_nested_query(uri.query || '').merge(params)
110
- uri.query = Rack::Utils.build_nested_query(params) if params.present?
113
+ # Allow keys that are currently in query_params to be deleted by setting their value to nil in
114
+ # new_params (including in nested hashes).
115
+ merged_params = parse_nested_query(uri.query || '').
116
+ deep_merge(new_params).recurse(&:compact)
117
+ uri.query = Rack::Utils.build_nested_query(merged_params).presence
111
118
  uri.to_s
112
119
  end
113
120
 
@@ -121,9 +128,16 @@ module MergeParams::Helpers
121
128
  ) if respond_to?(:helper_method)
122
129
  end
123
130
 
124
- private
131
+ # Parsing helpers
132
+ def params_from_url(url)
133
+ query_params = parse_nested_query(URI(url).query || '')
134
+ route_params = Rails.application.routes.recognize_path(url.to_s)
135
+ params_for_url_for(
136
+ route_params.merge(query_params)
137
+ )
138
+ end
125
139
 
126
140
  def parse_nested_query(query)
127
- Rack::Utils.parse_nested_query(query || '').symbolize_keys
141
+ Rack::Utils.parse_nested_query(query || '').deep_symbolize_keys
128
142
  end
129
143
  end
@@ -1,5 +1,5 @@
1
1
  module MergeParams
2
2
  def self.version
3
- "0.3.0"
3
+ "0.4.0"
4
4
  end
5
5
  end
@@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
29
29
  spec.required_ruby_version = ">= 2.3.0"
30
30
  spec.add_dependency "activesupport", [">= 4.2", "< 5.3"]
31
31
  spec.add_dependency "actionpack", [">= 4.2", "< 5.3"]
32
+ spec.add_dependency "facets"
32
33
 
33
34
  spec.add_development_dependency "bundler", "~> 1.17"
34
35
  spec.add_development_dependency "rake", "~> 10.0"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: merge_params
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tyler Rick
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-01-25 00:00:00.000000000 Z
11
+ date: 2019-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -50,6 +50,20 @@ dependencies:
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
52
  version: '5.3'
53
+ - !ruby/object:Gem::Dependency
54
+ name: facets
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ type: :runtime
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
53
67
  - !ruby/object:Gem::Dependency
54
68
  name: bundler
55
69
  requirement: !ruby/object:Gem::Requirement
@@ -109,6 +123,7 @@ files:
109
123
  - Readme.md
110
124
  - bin/console
111
125
  - bin/setup
126
+ - lib/facets/hash/recursively_comparing.rb
112
127
  - lib/merge_params.rb
113
128
  - lib/merge_params/helpers.rb
114
129
  - lib/merge_params/version.rb