merge_params 0.2.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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