better_params 0.1.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +154 -0
- data/Rakefile +27 -0
- data/lib/better_params.rb +7 -0
- data/lib/better_params/base.rb +31 -0
- data/lib/better_params/base/add_destroy_info.rb +9 -0
- data/lib/better_params/base/booleans.rb +11 -0
- data/lib/better_params/base/convert_keys.rb +44 -0
- data/lib/better_params/base/datetimes.rb +9 -0
- data/lib/better_params/base/prepare_nested_attributes.rb +9 -0
- data/lib/better_params/base/remove_blanks.rb +9 -0
- data/lib/better_params/base/replace_blanks_by_nil.rb +9 -0
- data/lib/better_params/base/strip_values.rb +33 -0
- data/lib/better_params/base/transform_values_for_keys.rb +10 -0
- data/lib/better_params/converters.rb +12 -0
- data/lib/better_params/params_destroy_info.rb +74 -0
- data/lib/better_params/railtie.rb +4 -0
- data/lib/better_params/version.rb +3 -0
- data/lib/tasks/better_params_tasks.rake +4 -0
- metadata +97 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: af64b05bc75c0e695f916a16c20cd9b6aeea3037637e8254407210932af06c94
|
4
|
+
data.tar.gz: e43f0a8bf5b81b16ffe8e8f40eb5fdadc29e442d26896a0baa0b55c920860ac6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b400e185ed05996e1a3924b1018803b671dcf9d13ff1c4adf2b6f5e33fad915d81a03ef630b2a3990d543ff5d0c66e8103dcfeba96cb9df5a314fa7e6c131d03
|
7
|
+
data.tar.gz: 5737d14e62aab364364ef1c3481bcda2f2e203f3e216a130352e1b06e1051aaab24206a09a5060c84d4a03f9ceb0cef5111d2843ffae365ea145ae4abb03944f
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2020
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
# BetterParams
|
2
|
+
Adds useful methods to `ActionController::Parameters` for modifying parameters.
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
`ActionController::Parameters` has useful methods for modifying parameters.
|
6
|
+
|
7
|
+
### AddDestroyInfo
|
8
|
+
Adds the *_destroy* attribute to existing *has_many* associations that were not passed for modification.
|
9
|
+
The method accepts 2 parameters: an Active Record Object and a symbolic list of association names.
|
10
|
+
Supports nested lists.
|
11
|
+
```ruby
|
12
|
+
object.association_a.ids
|
13
|
+
# result
|
14
|
+
[1,2]
|
15
|
+
|
16
|
+
object.association_b.ids
|
17
|
+
# result
|
18
|
+
[1,2]
|
19
|
+
|
20
|
+
ActionController::Parameters.new(
|
21
|
+
a: 'a',
|
22
|
+
association_a: [
|
23
|
+
{ id: 1, name: 'X1' },
|
24
|
+
{ name: 'Y1' }
|
25
|
+
],
|
26
|
+
association_b: [
|
27
|
+
{ id: 1, name: 'X2' },
|
28
|
+
{ name: 'Y2' }
|
29
|
+
]
|
30
|
+
).add_destroy_info(object, :association_a)
|
31
|
+
# result
|
32
|
+
{
|
33
|
+
a: 'a',
|
34
|
+
association_a: [
|
35
|
+
{ id: 1, name: 'X1' },
|
36
|
+
{ id: 2, _destroy: true },
|
37
|
+
{ name: 'Y1' },
|
38
|
+
],
|
39
|
+
association_b: [
|
40
|
+
{ id: 1, name: 'X2' },
|
41
|
+
{ name: 'Y2' },
|
42
|
+
]
|
43
|
+
}
|
44
|
+
```
|
45
|
+
|
46
|
+
### Booleans
|
47
|
+
Converts a parameter to a Boolean value.
|
48
|
+
The method accepts 1 parameters: Symbolic list of attribute names.
|
49
|
+
Supports nested lists.
|
50
|
+
```ruby
|
51
|
+
ActionController::Parameters.new(a: 'true', b: 'false', c: 'not_bool', d: 'true')
|
52
|
+
.booleans(:a, :b, :c)
|
53
|
+
# result
|
54
|
+
{ a: true, b: false, c: false, d: 'true' }
|
55
|
+
```
|
56
|
+
|
57
|
+
### Datetimes
|
58
|
+
Converts a parameter to a Time value.
|
59
|
+
The method accepts 1 parameters: Symbolic list of attribute names.
|
60
|
+
Supports nested lists.
|
61
|
+
```ruby
|
62
|
+
ActionController::Parameters.new(a: '2020-01-01', b: '2020-01-01')
|
63
|
+
.datetimes(:a)
|
64
|
+
# result
|
65
|
+
{ a: 2020-01-01 00:00:00 +0700, b: '2020-01-01' }
|
66
|
+
```
|
67
|
+
|
68
|
+
### PrepareNestedAttributes
|
69
|
+
Adds the *_attributes* Postfix to nested parameters, which allows creating a group of related entities using the `assign_attributes` method.
|
70
|
+
The method accepts 1 parameters: Symbolic list of association names.
|
71
|
+
Supports nested lists.
|
72
|
+
```ruby
|
73
|
+
ActionController::Parameters.new(
|
74
|
+
a: 'a',
|
75
|
+
association_a: [{ a: 'a' }],
|
76
|
+
association_b: [
|
77
|
+
{
|
78
|
+
b: 'b',
|
79
|
+
association_b_a: [{ ba: 'b_a' }]
|
80
|
+
}
|
81
|
+
]
|
82
|
+
).prepare_nested_attributes(
|
83
|
+
:association_a,
|
84
|
+
association_b: [:association_b_a]
|
85
|
+
)
|
86
|
+
# result
|
87
|
+
{
|
88
|
+
a: 'a',
|
89
|
+
association_a_attributes: [{ a: 'a' }],
|
90
|
+
association_b_attributes: [
|
91
|
+
{
|
92
|
+
b: 'b',
|
93
|
+
association_b_a_attributes: [{ ba: 'ba' }]
|
94
|
+
}
|
95
|
+
]
|
96
|
+
}
|
97
|
+
```
|
98
|
+
|
99
|
+
### RemoveBlanks
|
100
|
+
Deletes keys with empty values.
|
101
|
+
Not supports nested lists.
|
102
|
+
```ruby
|
103
|
+
ActionController::Parameters.new(a: 'a', b: '')
|
104
|
+
.remove_blanks
|
105
|
+
# result
|
106
|
+
{ a: 'a' }
|
107
|
+
```
|
108
|
+
|
109
|
+
### ReplaceBlanksByNil
|
110
|
+
Replaces blanks by nil.
|
111
|
+
The method accepts 1 parameters: Symbolic list of attribute names.
|
112
|
+
Supports nested lists.
|
113
|
+
```ruby
|
114
|
+
ActionController::Parameters.new(a: '', b: '')
|
115
|
+
.replace_blanks_by_nil(:a)
|
116
|
+
# result
|
117
|
+
{ a: nil, b: '' }
|
118
|
+
```
|
119
|
+
|
120
|
+
### StripValues
|
121
|
+
Removes leading and trailing spaces.
|
122
|
+
The method accepts 1 parameters: Symbolic list of attribute names.
|
123
|
+
Supports nested lists.
|
124
|
+
```ruby
|
125
|
+
ActionController::Parameters.new(a: ' a ', b: ' b ')
|
126
|
+
.strip_values(:a)
|
127
|
+
# result
|
128
|
+
{ a: 'a', b: ' b ' }
|
129
|
+
```
|
130
|
+
|
131
|
+
Note: For all parameters, you must make a permit
|
132
|
+
|
133
|
+
## Installation
|
134
|
+
Add this line to your application's Gemfile:
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
gem 'better_params'
|
138
|
+
```
|
139
|
+
|
140
|
+
And then execute:
|
141
|
+
```bash
|
142
|
+
$ bundle
|
143
|
+
```
|
144
|
+
|
145
|
+
Or install it yourself as:
|
146
|
+
```bash
|
147
|
+
$ gem install better_params
|
148
|
+
```
|
149
|
+
|
150
|
+
## Contributing
|
151
|
+
Contribution directions go here.
|
152
|
+
|
153
|
+
## License
|
154
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'BetterParams'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'bundler/gem_tasks'
|
18
|
+
|
19
|
+
require 'rake/testtask'
|
20
|
+
|
21
|
+
Rake::TestTask.new(:test) do |t|
|
22
|
+
t.libs << 'test'
|
23
|
+
t.pattern = 'test/**/*_test.rb'
|
24
|
+
t.verbose = false
|
25
|
+
end
|
26
|
+
|
27
|
+
task default: :test
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'better_params/converters'
|
2
|
+
require 'better_params/params_destroy_info'
|
3
|
+
|
4
|
+
require 'better_params/base/convert_keys'
|
5
|
+
require 'better_params/base/transform_values_for_keys'
|
6
|
+
|
7
|
+
require 'better_params/base/add_destroy_info'
|
8
|
+
require 'better_params/base/booleans'
|
9
|
+
require 'better_params/base/datetimes'
|
10
|
+
require 'better_params/base/prepare_nested_attributes'
|
11
|
+
require 'better_params/base/remove_blanks'
|
12
|
+
require 'better_params/base/replace_blanks_by_nil'
|
13
|
+
require 'better_params/base/strip_values'
|
14
|
+
|
15
|
+
module BetterParams
|
16
|
+
# The module depends on the 'params' controller instance variable
|
17
|
+
module Base
|
18
|
+
extend ActiveSupport::Concern
|
19
|
+
|
20
|
+
include ConvertKeys
|
21
|
+
include TransformValuesForKeys
|
22
|
+
|
23
|
+
include AddDestroyInfo
|
24
|
+
include Booleans
|
25
|
+
include Datetimes
|
26
|
+
include PrepareNestedAttributes
|
27
|
+
include RemoveBlanks
|
28
|
+
include ReplaceBlanksByNil
|
29
|
+
include StripValues
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module BetterParams
|
2
|
+
module Base
|
3
|
+
module ConvertKeys
|
4
|
+
# Not used directly
|
5
|
+
def convert_keys(keys, &block)
|
6
|
+
merge_attributes = ->(params, key, attributes) do
|
7
|
+
params.merge(block.call(key) => attributes).except(key)
|
8
|
+
end
|
9
|
+
|
10
|
+
params = self
|
11
|
+
keys.each do |key|
|
12
|
+
if key.is_a? Hash
|
13
|
+
key.each do |nested_key, key_from_key|
|
14
|
+
nested_params = params[nested_key]
|
15
|
+
next if nested_params.nil?
|
16
|
+
|
17
|
+
nested_attributes =
|
18
|
+
if nested_params.is_a?(Array)
|
19
|
+
nested_params.map do |item|
|
20
|
+
item.convert_keys(key_from_key, &block)
|
21
|
+
end
|
22
|
+
else
|
23
|
+
nested_params.convert_keys(key_from_key, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
params = merge_attributes.call(
|
27
|
+
params,
|
28
|
+
nested_key,
|
29
|
+
nested_attributes
|
30
|
+
)
|
31
|
+
end
|
32
|
+
else
|
33
|
+
attributes = params[key]
|
34
|
+
next if attributes.nil?
|
35
|
+
|
36
|
+
params = merge_attributes.call(params, key, attributes)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
params
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module BetterParams
|
2
|
+
module Base
|
3
|
+
module StripValues
|
4
|
+
def strip_values(*keys)
|
5
|
+
keys.reduce(self) do |result, key|
|
6
|
+
if key.is_a?(Hash)
|
7
|
+
key.reduce(result) do |hash_result, (hash_key, hash_value)|
|
8
|
+
next hash_result unless hash_result.key?(hash_key)
|
9
|
+
|
10
|
+
nested = hash_result[hash_key]
|
11
|
+
next hash_result if nested.nil?
|
12
|
+
|
13
|
+
nested =
|
14
|
+
if nested.is_a?(Array)
|
15
|
+
nested.map do |nested_object|
|
16
|
+
nested_object.strip_values(*hash_value)
|
17
|
+
end
|
18
|
+
else
|
19
|
+
nested.strip_values(*hash_value)
|
20
|
+
end
|
21
|
+
|
22
|
+
hash_result.merge(hash_key => nested)
|
23
|
+
end
|
24
|
+
else
|
25
|
+
next result unless result.key?(key)
|
26
|
+
|
27
|
+
result.merge(key => result[key]&.strip)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module BetterParams
|
2
|
+
# Auxiliary class for converting values
|
3
|
+
class Converters
|
4
|
+
# Converts to a Boolean value
|
5
|
+
def self.to_b(value)
|
6
|
+
return true if value.is_a? TrueClass
|
7
|
+
return false if value.is_a? FalseClass
|
8
|
+
|
9
|
+
value.to_s.downcase == 'true'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module BetterParams
|
2
|
+
class ParamsDestroyInfo
|
3
|
+
def self.add(*args)
|
4
|
+
new.add(*args)
|
5
|
+
end
|
6
|
+
|
7
|
+
# For all has_many relations from a keys array adds information
|
8
|
+
# about destroying objects by an algorythm:
|
9
|
+
# If a nested object doesn't exists in a passed object it will be destroyed.
|
10
|
+
def add(original_params, object, *keys)
|
11
|
+
return original_params if object.nil?
|
12
|
+
|
13
|
+
# Process every key and merge updated information to params
|
14
|
+
prepare_keys(keys).reduce(original_params) do |params, (key, nested_keys)|
|
15
|
+
# Don't needs to process key if params is not passed
|
16
|
+
nested_params = params[key]
|
17
|
+
next params if nested_params.nil?
|
18
|
+
|
19
|
+
# Can't process key if a nested object doesn't exists
|
20
|
+
relation = object.public_send(key)
|
21
|
+
next params if relation.nil?
|
22
|
+
|
23
|
+
if relation.is_a? Enumerable
|
24
|
+
# If a relation is a has_many, needs to add information about destroying
|
25
|
+
nested_params = add_destroy_info(nested_params, relation)
|
26
|
+
|
27
|
+
# Needs to go deeper to the every object in an array if has nested keys
|
28
|
+
unless nested_keys.nil?
|
29
|
+
nested_params = add_nested_destroy_info(
|
30
|
+
nested_params, relation, nested_keys
|
31
|
+
)
|
32
|
+
end
|
33
|
+
else
|
34
|
+
# If a relation is a single object we needs to go deeper
|
35
|
+
nested_params = add(nested_params, relation, *nested_keys)
|
36
|
+
end
|
37
|
+
|
38
|
+
next params.merge(key => nested_params)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
|
44
|
+
# Converts all keys to the same format -
|
45
|
+
# hash with array values where value can be nil
|
46
|
+
def prepare_keys(keys)
|
47
|
+
keys.reduce({}) do |hash, key|
|
48
|
+
hash.merge(key.is_a?(Hash) ? key : { key => nil })
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Adds { id: 1, _destroy: true } objects to an array if an object with id
|
53
|
+
# is not exists in the array but exists in a relation
|
54
|
+
def add_destroy_info(params_array, relation)
|
55
|
+
existed_ids = relation.map(&:id)
|
56
|
+
passed_ids = params_array.map { |attributes| attributes[:id] }.compact
|
57
|
+
ids_to_destroy = existed_ids - passed_ids
|
58
|
+
params_array + ids_to_destroy.map do |id|
|
59
|
+
ActionController::Parameters.new(id: id, _destroy: true).permit!
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def add_nested_destroy_info(params_array, relation, nested_keys)
|
64
|
+
nested_objects_by_id = relation.group_by(&:id).transform_values(&:first)
|
65
|
+
params_array.map do |attributes|
|
66
|
+
id = attributes[:id]
|
67
|
+
nested_object = nested_objects_by_id[id]
|
68
|
+
next attributes if nested_object.nil?
|
69
|
+
|
70
|
+
add(attributes, nested_object, *nested_keys)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: better_params
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Bazov Peter
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-07-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5.0'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '7'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '5.0'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '7'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: sqlite3
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
description: Extension for default Rails params with useful features.
|
48
|
+
email:
|
49
|
+
- petr@sequenia.com
|
50
|
+
- sb.truefalse@gmail.com
|
51
|
+
executables: []
|
52
|
+
extensions: []
|
53
|
+
extra_rdoc_files: []
|
54
|
+
files:
|
55
|
+
- MIT-LICENSE
|
56
|
+
- README.md
|
57
|
+
- Rakefile
|
58
|
+
- lib/better_params.rb
|
59
|
+
- lib/better_params/base.rb
|
60
|
+
- lib/better_params/base/add_destroy_info.rb
|
61
|
+
- lib/better_params/base/booleans.rb
|
62
|
+
- lib/better_params/base/convert_keys.rb
|
63
|
+
- lib/better_params/base/datetimes.rb
|
64
|
+
- lib/better_params/base/prepare_nested_attributes.rb
|
65
|
+
- lib/better_params/base/remove_blanks.rb
|
66
|
+
- lib/better_params/base/replace_blanks_by_nil.rb
|
67
|
+
- lib/better_params/base/strip_values.rb
|
68
|
+
- lib/better_params/base/transform_values_for_keys.rb
|
69
|
+
- lib/better_params/converters.rb
|
70
|
+
- lib/better_params/params_destroy_info.rb
|
71
|
+
- lib/better_params/railtie.rb
|
72
|
+
- lib/better_params/version.rb
|
73
|
+
- lib/tasks/better_params_tasks.rake
|
74
|
+
homepage: http://sequenia.com/
|
75
|
+
licenses:
|
76
|
+
- MIT
|
77
|
+
metadata: {}
|
78
|
+
post_install_message:
|
79
|
+
rdoc_options: []
|
80
|
+
require_paths:
|
81
|
+
- lib
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
requirements: []
|
93
|
+
rubygems_version: 3.0.3
|
94
|
+
signing_key:
|
95
|
+
specification_version: 4
|
96
|
+
summary: Better Params
|
97
|
+
test_files: []
|