merge_params 0.2.0 → 0.5.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
- SHA1:
3
- metadata.gz: 60f0644a975a59c156bcd0324be1f7a08e07d1bc
4
- data.tar.gz: d2bdd9e4ab258fabb6025bfd49415014a94aa818
2
+ SHA256:
3
+ metadata.gz: d43d9cf3df4fb81e7b97db8b9a4881983d93c76fd2a2c62da80afae6209cae95
4
+ data.tar.gz: b76c110bc2145c68e4f7d7eb33b39c5b2264a84e1dcf96828bb378c6e53d5251
5
5
  SHA512:
6
- metadata.gz: 575ceab7b08f14f19aa7609709f64299effeaf21925d0dc4cedbdf4a776542cc237dfacea2983864c30e98aae752825444c8a37184e7feec3033158851fb6725
7
- data.tar.gz: db13d502675945cad348f8ba5d0467c225a6abe513a8c89603ea47da9407bd2670ea2b2d81a5ada876603d5adf4da1ae5a1e39fe42f2adfb6310d925706eec17
6
+ metadata.gz: 1630b02c9715804035906a2c29994352f9cdbacfd61c398df1ed2c2afb0672d01fe7f5f442d2a5cda371cd98ae881207dd9126a61aaf0258dd11f93e80e17b2f
7
+ data.tar.gz: 82c2373090cd74310668114f6ea0b4742d66955d2c329b8c4c4f9377dce402aa377cd608eed8975b0ab2757db744b2ded9b35dc04fa3cc8347d965fb13cdea51
@@ -0,0 +1,54 @@
1
+ # Changelog
2
+
3
+ This project follows [semver 2.0.0](http://semver.org/spec/v2.0.0.html) and the
4
+ recommendations of [keepachangelog.com](http://keepachangelog.com/).
5
+
6
+ ## (Unreleased)
7
+
8
+ ## 0.5.0 (2020-08-25)
9
+ - Change the order of arguments for `add_params` to `add_params(url, query_params_to_add)`.
10
+ This feels more natural, since you are adding the new query params to the _end_ of the given URL.
11
+ It is also more consistent with the Rails route helpers, like `something_path(query_params_to_add)`.
12
+
13
+ ## 0.4.2 (2019-02-10)
14
+ - Fix `merge_url_for` to not pass on reserved options like only_path (which were only intended for
15
+ consumption by `url_for`) to `add_params`. It was adding it to the end of the URL, like
16
+ `only_path=true`.
17
+
18
+ ## 0.4.1 (2019-02-08)
19
+ - Fix issue with merge_params not merging nested hashes as expected (changed to
20
+ use `deep_merge` instead of `merge`)
21
+
22
+ ## 0.4.0 (2019-02-07)
23
+
24
+ ### Added/Changed
25
+ - Better support for nested hashes: Using `deep_symbolize_keys` instead of `symbolize_keys`.
26
+ - Allow keys in nested hashes to be deleted by setting their value to nil
27
+ - Add `params_from_url(url)` helper
28
+ - Allow a hash to be passed as an argument to `params_for_url_for`
29
+ - Add dependency on `facets` gem
30
+
31
+ ## 0.3.0 (2019-01-24)
32
+
33
+ ### Fixed
34
+ - Fix `merge_url_for` to not try to add a param as a query param if it's been recognized as a route
35
+ param (part of the route path). We don't want the same param to be passed both via the route path
36
+ *and* the query string.
37
+
38
+ ### Added
39
+ - `merge_url_for`: Allow keys that are currently in `query_params` to be deleted by setting their
40
+ value to `nil`.
41
+
42
+
43
+ ## 0.2.0 (2018-12-05)
44
+
45
+ ### Fixed
46
+ - Fix `add_params` to not inadvertently add a '?' to the end of the URI if there are no params to add
47
+
48
+ ### Added
49
+ - Add `slice_params` helper
50
+
51
+
52
+ ## 0.1.0 (2018-11-16)
53
+
54
+ Initial release
data/License CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2018 Tyler Rick
1
+ Copyright (c) 2020 Tyler Rick
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
4
4
  associated documentation files (the "Software"), to deal in the Software without restriction,
data/Readme.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # MergeParams
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/merge_params.svg)](https://badge.fury.io/rb/merge_params)
4
+
3
5
  ## Why do we need it?
4
6
 
5
7
  Have you ever wanted to take the current route and change just one parameter in the route to
@@ -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
+ deep_merge(new_params.deep_symbolize_keys)
55
62
  end
56
63
 
57
64
  # Easily extract just certain param keys.
@@ -79,26 +86,36 @@ module MergeParams::Helpers
79
86
 
80
87
  # Safely merges the given params with the params from the current request, then generates a route
81
88
  # from the merged params.
89
+ # You can remove a key by passing nil as the value, for example {key: nil}.
82
90
  def merge_url_for(new_params = {})
83
91
  url = url_for(merge_params(new_params))
84
92
 
85
- # Now pass along in the *query string* any params that we couldn't pass to url_for because they
86
- # were reserved options.
87
- query_params_already_added = parse_nested_query(URI(url).query || '')
88
- query_params_to_add = query_params.except(*query_params_already_added.keys)
89
- add_params(query_params_to_add, url)
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 = params_for_url_for(new_params).
102
+ recursively_comparing(params_already_added).graph { |k,v, other|
103
+ if v.is_a?(Hash) || v.nil? || other.nil?
104
+ [k, v]
105
+ end
106
+ }
107
+ add_params(url, query_params_to_add)
90
108
  end
91
109
 
92
110
  # Adds params to the query string
93
111
  # (Unlike url_for_merge, which tries to generate a route from the params.)
94
- # TODO: Should URL be first like https://libraries.io/github/jordanmaguire/uri_query_merger ?
95
- # UriQueryMerger.new("http://www.google.com?other=1", {jordan: "rules"}).merge
96
- # Can we make it work that way when a URL is supplied buth otherwise let the params be the first
97
- # and only argument (to optimize for that more common use case)?
98
- def add_params(params = {}, url = request.fullpath)
112
+ def add_params(url = request.fullpath, new_params = {})
99
113
  uri = URI(url)
100
- params = parse_nested_query(uri.query || '').merge(params)
101
- uri.query = Rack::Utils.build_nested_query(params) if params.present?
114
+ # Allow keys that are currently in query_params to be deleted by setting their value to nil in
115
+ # new_params (including in nested hashes).
116
+ merged_params = parse_nested_query(uri.query || '').
117
+ deep_merge(new_params).recurse(&:compact)
118
+ uri.query = Rack::Utils.build_nested_query(merged_params).presence
102
119
  uri.to_s
103
120
  end
104
121
 
@@ -112,9 +129,16 @@ module MergeParams::Helpers
112
129
  ) if respond_to?(:helper_method)
113
130
  end
114
131
 
115
- private
132
+ # Parsing helpers
133
+ def params_from_url(url)
134
+ query_params = parse_nested_query(URI(url).query || '')
135
+ route_params = Rails.application.routes.recognize_path(url.to_s)
136
+ params_for_url_for(
137
+ route_params.merge(query_params)
138
+ )
139
+ end
116
140
 
117
141
  def parse_nested_query(query)
118
- Rack::Utils.parse_nested_query(query || '').symbolize_keys
142
+ Rack::Utils.parse_nested_query(query || '').deep_symbolize_keys
119
143
  end
120
144
  end
@@ -1,5 +1,5 @@
1
1
  module MergeParams
2
2
  def self.version
3
- "0.2.0"
3
+ "0.5.0"
4
4
  end
5
5
  end
@@ -11,11 +11,11 @@ Gem::Specification.new do |spec|
11
11
 
12
12
  spec.summary = %q{Safely merge params for use with url_for or for the query string}
13
13
  spec.description = spec.summary
14
- spec.homepage = "http://github.com/TylerRick/merge_params"
14
+ spec.homepage = "https://github.com/TylerRick/merge_params"
15
15
 
16
16
  spec.metadata["homepage_uri"] = spec.homepage
17
17
  spec.metadata["source_code_uri"] = spec.homepage
18
- spec.metadata["changelog_uri"] = "TODO: Put your gem's Changelog.md URL here."
18
+ spec.metadata["changelog_uri"] = "#{spec.metadata["source_code_uri"]}/blob/master/Changelog.md"
19
19
 
20
20
  # Specify which files should be added to the gem when it is released.
21
21
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -29,8 +29,9 @@ 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
- spec.add_development_dependency "bundler", "~> 1.17"
34
+ spec.add_development_dependency "bundler", "~> 2"
34
35
  spec.add_development_dependency "rake", "~> 10.0"
35
36
  spec.add_development_dependency "rspec", "~> 3.0"
36
37
  end
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.2.0
4
+ version: 0.5.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: 2018-12-05 00:00:00.000000000 Z
11
+ date: 2020-08-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -50,20 +50,34 @@ 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
56
70
  requirements:
57
71
  - - "~>"
58
72
  - !ruby/object:Gem::Version
59
- version: '1.17'
73
+ version: '2'
60
74
  type: :development
61
75
  prerelease: false
62
76
  version_requirements: !ruby/object:Gem::Requirement
63
77
  requirements:
64
78
  - - "~>"
65
79
  - !ruby/object:Gem::Version
66
- version: '1.17'
80
+ version: '2'
67
81
  - !ruby/object:Gem::Dependency
68
82
  name: rake
69
83
  requirement: !ruby/object:Gem::Requirement
@@ -102,23 +116,25 @@ files:
102
116
  - ".gitignore"
103
117
  - ".rspec"
104
118
  - ".travis.yml"
119
+ - Changelog.md
105
120
  - Gemfile
106
121
  - License
107
122
  - Rakefile
108
123
  - Readme.md
109
124
  - bin/console
110
125
  - bin/setup
126
+ - lib/facets/hash/recursively_comparing.rb
111
127
  - lib/merge_params.rb
112
128
  - lib/merge_params/helpers.rb
113
129
  - lib/merge_params/version.rb
114
130
  - merge_params.gemspec
115
- homepage: http://github.com/TylerRick/merge_params
131
+ homepage: https://github.com/TylerRick/merge_params
116
132
  licenses:
117
133
  - MIT
118
134
  metadata:
119
- homepage_uri: http://github.com/TylerRick/merge_params
120
- source_code_uri: http://github.com/TylerRick/merge_params
121
- changelog_uri: 'TODO: Put your gem''s Changelog.md URL here.'
135
+ homepage_uri: https://github.com/TylerRick/merge_params
136
+ source_code_uri: https://github.com/TylerRick/merge_params
137
+ changelog_uri: https://github.com/TylerRick/merge_params/blob/master/Changelog.md
122
138
  post_install_message:
123
139
  rdoc_options: []
124
140
  require_paths:
@@ -134,8 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
134
150
  - !ruby/object:Gem::Version
135
151
  version: '0'
136
152
  requirements: []
137
- rubyforge_project:
138
- rubygems_version: 2.6.14.3
153
+ rubygems_version: 3.1.2
139
154
  signing_key:
140
155
  specification_version: 4
141
156
  summary: Safely merge params for use with url_for or for the query string