array_enum 1.0.1 → 1.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 +4 -4
- data/.github/workflows/ci-on-merge.yml +59 -0
- data/.github/workflows/ci.yml +56 -0
- data/Gemfile.lock +18 -19
- data/README.md +39 -5
- data/lib/array_enum/subset_validator.rb +4 -2
- data/lib/array_enum/version.rb +1 -1
- data/lib/array_enum.rb +20 -7
- metadata +8 -7
- data/.travis.yml +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d2df08c37b57f1ab526c97e96687aaa26d6f4cdbbd7cf189a1671b4fc2ad309
|
4
|
+
data.tar.gz: a4a87c06b773f5b8210d67e869372e99e838853962789a5d030bd8ec2fbc9a9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 153d73f33212247cba61d862b31948bd66c50c352f2984fbfbe00c71ce77a8086a8925e3256bfa03013a32050442a6be7014da888493a3c422256ac85d24108a
|
7
|
+
data.tar.gz: 273ababe94efae433b8577e872cc44f0a69e85b482b9deda86dc83b39f0440d973e2755ca2bc85b7e36ab90d2313b77e0ed0dc94e932a4b681a26eeaf592a908
|
@@ -0,0 +1,59 @@
|
|
1
|
+
name: BUILD
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
test:
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
strategy:
|
12
|
+
matrix:
|
13
|
+
ruby-version: [2.7, '3.0', 3.1]
|
14
|
+
|
15
|
+
services:
|
16
|
+
postgres:
|
17
|
+
image: postgres
|
18
|
+
ports:
|
19
|
+
- 5432:5432
|
20
|
+
env:
|
21
|
+
POSTGRES_PASSWORD: postgres
|
22
|
+
options: >-
|
23
|
+
--health-cmd pg_isready
|
24
|
+
--health-interval 10s
|
25
|
+
--health-timeout 5s
|
26
|
+
--health-retries 5
|
27
|
+
|
28
|
+
steps:
|
29
|
+
- name: Install libraries
|
30
|
+
run: |
|
31
|
+
sudo apt-get install -y libpq-dev postgresql-client
|
32
|
+
|
33
|
+
- name: Configure database
|
34
|
+
env:
|
35
|
+
PGPASSWORD: postgres
|
36
|
+
PGUSER: postgres
|
37
|
+
PGHOST: localhost
|
38
|
+
run: |
|
39
|
+
echo "Configuring PostgresSQL"
|
40
|
+
psql -c 'create database "array_enum_test";'
|
41
|
+
|
42
|
+
- name: Checkout code
|
43
|
+
uses: actions/checkout@v2
|
44
|
+
|
45
|
+
- name : Ruby Setup
|
46
|
+
uses: ruby/setup-ruby@v1
|
47
|
+
with:
|
48
|
+
ruby-version: ${{ matrix.ruby-version }}
|
49
|
+
bundler-cache: true
|
50
|
+
|
51
|
+
- name: Install dependencies
|
52
|
+
run: bundle install
|
53
|
+
|
54
|
+
- name: Run test
|
55
|
+
env:
|
56
|
+
PGPASSWORD: postgres
|
57
|
+
PGUSER: postgres
|
58
|
+
PGHOST: localhost
|
59
|
+
run: bundle exec rake -s test
|
@@ -0,0 +1,56 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on: [pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
strategy:
|
9
|
+
matrix:
|
10
|
+
ruby-version: [2.7, '3.0', 3.1]
|
11
|
+
|
12
|
+
services:
|
13
|
+
postgres:
|
14
|
+
image: postgres
|
15
|
+
ports:
|
16
|
+
- 5432:5432
|
17
|
+
env:
|
18
|
+
POSTGRES_PASSWORD: postgres
|
19
|
+
options: >-
|
20
|
+
--health-cmd pg_isready
|
21
|
+
--health-interval 10s
|
22
|
+
--health-timeout 5s
|
23
|
+
--health-retries 5
|
24
|
+
|
25
|
+
steps:
|
26
|
+
- name: Install libraries
|
27
|
+
run: |
|
28
|
+
sudo apt-get install -y libpq-dev postgresql-client
|
29
|
+
|
30
|
+
- name: Configure database
|
31
|
+
env:
|
32
|
+
PGPASSWORD: postgres
|
33
|
+
PGUSER: postgres
|
34
|
+
PGHOST: localhost
|
35
|
+
run: |
|
36
|
+
echo "Configuring PostgresSQL"
|
37
|
+
psql -c 'create database "array_enum_test";'
|
38
|
+
|
39
|
+
- name: Checkout code
|
40
|
+
uses: actions/checkout@v2
|
41
|
+
|
42
|
+
- name : Ruby Setup
|
43
|
+
uses: ruby/setup-ruby@v1
|
44
|
+
with:
|
45
|
+
ruby-version: ${{ matrix.ruby-version }}
|
46
|
+
bundler-cache: true
|
47
|
+
|
48
|
+
- name: Install dependencies
|
49
|
+
run: bundle install
|
50
|
+
|
51
|
+
- name: Run test
|
52
|
+
env:
|
53
|
+
PGPASSWORD: postgres
|
54
|
+
PGUSER: postgres
|
55
|
+
PGHOST: localhost
|
56
|
+
run: bundle exec rake -s test
|
data/Gemfile.lock
CHANGED
@@ -1,33 +1,32 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
array_enum (1.0
|
4
|
+
array_enum (1.4.0)
|
5
5
|
activemodel
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
activemodel (
|
11
|
-
activesupport (=
|
12
|
-
activerecord (
|
13
|
-
activemodel (=
|
14
|
-
activesupport (=
|
15
|
-
|
16
|
-
activesupport (5.2.2)
|
10
|
+
activemodel (6.1.3)
|
11
|
+
activesupport (= 6.1.3)
|
12
|
+
activerecord (6.1.3)
|
13
|
+
activemodel (= 6.1.3)
|
14
|
+
activesupport (= 6.1.3)
|
15
|
+
activesupport (6.1.3)
|
17
16
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
18
|
-
i18n (>=
|
19
|
-
minitest (
|
20
|
-
tzinfo (~>
|
21
|
-
|
22
|
-
concurrent-ruby (1.1.
|
23
|
-
i18n (1.
|
17
|
+
i18n (>= 1.6, < 2)
|
18
|
+
minitest (>= 5.1)
|
19
|
+
tzinfo (~> 2.0)
|
20
|
+
zeitwerk (~> 2.3)
|
21
|
+
concurrent-ruby (1.1.8)
|
22
|
+
i18n (1.8.9)
|
24
23
|
concurrent-ruby (~> 1.0)
|
25
24
|
minitest (5.11.3)
|
26
25
|
pg (1.1.4)
|
27
|
-
rake (12.3.
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
rake (12.3.3)
|
27
|
+
tzinfo (2.0.4)
|
28
|
+
concurrent-ruby (~> 1.0)
|
29
|
+
zeitwerk (2.4.2)
|
31
30
|
|
32
31
|
PLATFORMS
|
33
32
|
ruby
|
@@ -41,4 +40,4 @@ DEPENDENCIES
|
|
41
40
|
rake (>= 10.0)
|
42
41
|
|
43
42
|
BUNDLED WITH
|
44
|
-
|
43
|
+
2.2.3
|
data/README.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
[](https://badge.fury.io/rb/array_enum)
|
2
|
+
[](https://github.com/freeletics/array_enum/actions/workflows/ci-on-merge.yml)
|
3
|
+
|
4
|
+
|
1
5
|
# ArrayEnum
|
2
6
|
|
3
7
|
Extension for `ActiveRecord` that adds support for `PostgreSQL` array columns, mapping string values to integers.
|
@@ -11,7 +15,6 @@ Extension for `ActiveRecord` that adds support for `PostgreSQL` array columns, m
|
|
11
15
|
### ActiveRecord extension
|
12
16
|
|
13
17
|
Database will store integers that after reading will map to string values.
|
14
|
-
Additionally scope is generated with `with_` prefix that will query database for any matching passed value.
|
15
18
|
|
16
19
|
```ruby
|
17
20
|
ActiveRecord::Schema.define do
|
@@ -23,12 +26,43 @@ end
|
|
23
26
|
class User < ActiveRecord::Base
|
24
27
|
extend ArrayEnum
|
25
28
|
|
26
|
-
array_enum favourite_colors: {"red" => 1, "blue" => 2}
|
29
|
+
array_enum favourite_colors: {"red" => 1, "blue" => 2, "green" => 3}
|
27
30
|
end
|
28
31
|
|
29
32
|
user = User.create!(favourite_colors: ["red", "green"])
|
30
33
|
user.favourite_colors # => ["red", "green"]
|
31
|
-
User.
|
34
|
+
User.favourite_colors # => {"red" => 1, "blue" => 2, "green" => 3}
|
35
|
+
```
|
36
|
+
|
37
|
+
Several scopes are made available on your model to find records based on a value or an array of values:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
user1 = User.create!(favourite_colors: ["red", "green"])
|
41
|
+
user2 = User.create!(favourite_colors: ["red"])
|
42
|
+
|
43
|
+
# Find a record that has _all_ the provided values in the array enum attribute
|
44
|
+
User.with_favourite_colors("red") # => [user1, user2]
|
45
|
+
User.with_favourite_colors(%w[red green]) # => [user1]
|
46
|
+
User.with_favourite_colors(%w[red blue]) # => []
|
47
|
+
User.with_favourite_colors(%w[green blue]) # => []
|
48
|
+
|
49
|
+
# Find a record that has the provided values, and _only those values_, in the array enum attribute
|
50
|
+
User.only_with_favourite_colors("red") # => [user2]
|
51
|
+
User.only_with_favourite_colors(%w[red green]) # => [user1]
|
52
|
+
User.only_with_favourite_colors(%w[red blue]) # => []
|
53
|
+
User.only_with_favourite_colors(%w[green blue]) # => []
|
54
|
+
|
55
|
+
# Find a record that has _at least one_ of the provided values in the array enum attribute
|
56
|
+
User.with_any_of_favourite_colors("red") # => [user1, user2]
|
57
|
+
User.with_any_of_favourite_colors(%w[red green]) # => [user1, user2]
|
58
|
+
User.with_any_of_favourite_colors(%w[red blue]) # => [user1, user2]
|
59
|
+
User.with_any_of_favourite_colors(%w[green blue]) # => [user1]
|
60
|
+
```
|
61
|
+
|
62
|
+
Attempting to find a record with a value that is not in the enum will fail:
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
User.with_favourite_colors("yellow") # => ArgumentError["yellow is not a valid value for favourite_colors"]
|
32
66
|
```
|
33
67
|
|
34
68
|
### Subset Validator
|
@@ -42,6 +76,8 @@ class CreateUser
|
|
42
76
|
attr_accessor :favourite_colors
|
43
77
|
|
44
78
|
validates :favourite_colors, subset: ["green", "blue"]
|
79
|
+
# or:
|
80
|
+
# validates :favourite_colors, subset: { in: ->(record) { Color.pluck(:name) } }
|
45
81
|
end
|
46
82
|
|
47
83
|
CreateUser.new(favourite_colors: ["black"]).valid? # => false
|
@@ -49,8 +85,6 @@ CreateUser.new(favourite_colors: ["black"]).valid? # => false
|
|
49
85
|
|
50
86
|
## Development
|
51
87
|
|
52
|
-
[](https://travis-ci.com/freeletics/array_enum)
|
53
|
-
|
54
88
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
55
89
|
|
56
90
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
@@ -3,10 +3,12 @@ require "active_model/validator"
|
|
3
3
|
class ArrayEnum::SubsetValidator < ActiveModel::EachValidator
|
4
4
|
def validate_each(record, attribute, value)
|
5
5
|
wrapped_value = [value].flatten # Handles nil value
|
6
|
-
|
6
|
+
subset = delimiter.respond_to?(:call) ? delimiter.call(record) : delimiter
|
7
|
+
|
8
|
+
diff = wrapped_value.reject { |element| subset.include?(element) }
|
7
9
|
|
8
10
|
unless diff.empty?
|
9
|
-
record.errors.add(attribute, :inclusion, options.except(:in, :within).merge!(value: diff))
|
11
|
+
record.errors.add(attribute, :inclusion, **options.except(:in, :within).merge!(value: diff))
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
data/lib/array_enum/version.rb
CHANGED
data/lib/array_enum.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require "array_enum/version"
|
2
2
|
require "array_enum/subset_validator"
|
3
|
-
require "array_enum/railtie" if defined?(Rails)
|
3
|
+
require "array_enum/railtie" if defined?(Rails::Railtie)
|
4
|
+
require "active_support/hash_with_indifferent_access"
|
5
|
+
require "active_support/core_ext/string/inflections"
|
4
6
|
|
5
7
|
module ArrayEnum
|
6
8
|
MISSING_VALUE_MESSAGE = "%{value} is not a valid value for %{attr}".freeze
|
@@ -9,21 +11,32 @@ module ArrayEnum
|
|
9
11
|
def array_enum(definitions)
|
10
12
|
definitions.each do |attr_name, mapping|
|
11
13
|
attr_symbol = attr_name.to_sym
|
14
|
+
mapping_hash = ActiveSupport::HashWithIndifferentAccess.new(mapping)
|
12
15
|
|
13
|
-
define_singleton_method(
|
14
|
-
|
15
|
-
|
16
|
+
define_singleton_method(attr_name.to_s.pluralize) do
|
17
|
+
mapping_hash
|
18
|
+
end
|
19
|
+
|
20
|
+
{
|
21
|
+
"with_#{attr_name}" => '@>',
|
22
|
+
"only_with_#{attr_name}" => '=',
|
23
|
+
"with_any_of_#{attr_name}" => '&&'
|
24
|
+
}.each do |method_name, comparison_operator|
|
25
|
+
define_singleton_method(method_name.to_sym) do |values|
|
26
|
+
db_values = Array(values).map do |value|
|
27
|
+
mapping_hash[value] || raise(ArgumentError, MISSING_VALUE_MESSAGE % {value: value, attr: attr_name})
|
28
|
+
end
|
29
|
+
where("#{attr_name} #{comparison_operator} ARRAY[:db_values]", db_values: db_values)
|
16
30
|
end
|
17
|
-
where("#{attr_name} @> ARRAY[:db_values]", db_values: db_values)
|
18
31
|
end
|
19
32
|
|
20
33
|
define_method(attr_symbol) do
|
21
|
-
Array(self[attr_symbol]).map { |value|
|
34
|
+
Array(self[attr_symbol]).map { |value| mapping_hash.key(value) }
|
22
35
|
end
|
23
36
|
|
24
37
|
define_method("#{attr_name}=".to_sym) do |values|
|
25
38
|
self[attr_symbol] = Array(values).map do |value|
|
26
|
-
|
39
|
+
mapping_hash[value] || raise(ArgumentError, MISSING_VALUE_MESSAGE % {value: value, attr: attr_name})
|
27
40
|
end.uniq
|
28
41
|
end
|
29
42
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: array_enum
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wojciech Wnętrzak
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -103,8 +103,9 @@ executables: []
|
|
103
103
|
extensions: []
|
104
104
|
extra_rdoc_files: []
|
105
105
|
files:
|
106
|
+
- ".github/workflows/ci-on-merge.yml"
|
107
|
+
- ".github/workflows/ci.yml"
|
106
108
|
- ".gitignore"
|
107
|
-
- ".travis.yml"
|
108
109
|
- Gemfile
|
109
110
|
- Gemfile.lock
|
110
111
|
- LICENSE.txt
|
@@ -123,7 +124,7 @@ licenses:
|
|
123
124
|
metadata:
|
124
125
|
homepage_uri: https://github.com/freeletics/array_enum
|
125
126
|
source_code_uri: https://github.com/freeletics/array_enum
|
126
|
-
post_install_message:
|
127
|
+
post_install_message:
|
127
128
|
rdoc_options: []
|
128
129
|
require_paths:
|
129
130
|
- lib
|
@@ -138,8 +139,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
138
139
|
- !ruby/object:Gem::Version
|
139
140
|
version: '0'
|
140
141
|
requirements: []
|
141
|
-
rubygems_version: 3.
|
142
|
-
signing_key:
|
142
|
+
rubygems_version: 3.2.3
|
143
|
+
signing_key:
|
143
144
|
specification_version: 4
|
144
145
|
summary: String to integer mapping for PostgreSQL array columns.
|
145
146
|
test_files: []
|
data/.travis.yml
DELETED