array_enum 1.0.1 → 1.4.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
2
  SHA256:
3
- metadata.gz: afc3f9133c5efe0de0320c4b83e650969ab9b647b29b242f2d44dfb58d2a726f
4
- data.tar.gz: 9a9ee4607992a52138f6fea70e0eb329554b50e675b37f8e700305b04ff161b9
3
+ metadata.gz: 5d2df08c37b57f1ab526c97e96687aaa26d6f4cdbbd7cf189a1671b4fc2ad309
4
+ data.tar.gz: a4a87c06b773f5b8210d67e869372e99e838853962789a5d030bd8ec2fbc9a9e
5
5
  SHA512:
6
- metadata.gz: 3f96c19d50fac52b7bc2041d4983c9880807944226074132ce3c16b3a7ad99a1f00648f501d5535b8edaba1a932216ff0fb6196531dae7c9d09e3eb0bb06f6b9
7
- data.tar.gz: 43e71fc9ba6e47fd70b4fadad42d6b901d03f5e92238201e6e157338212db3d710ffcbffbb10fa8be0cf5be444a4c584de6c09d2272d42ace912d32087224321
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.1)
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 (5.2.2)
11
- activesupport (= 5.2.2)
12
- activerecord (5.2.2)
13
- activemodel (= 5.2.2)
14
- activesupport (= 5.2.2)
15
- arel (>= 9.0)
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 (>= 0.7, < 2)
19
- minitest (~> 5.1)
20
- tzinfo (~> 1.1)
21
- arel (9.0.0)
22
- concurrent-ruby (1.1.4)
23
- i18n (1.5.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.2)
28
- thread_safe (0.3.6)
29
- tzinfo (1.2.5)
30
- thread_safe (~> 0.1)
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
- 1.17.3
43
+ 2.2.3
data/README.md CHANGED
@@ -1,3 +1,7 @@
1
+ [![Gem Version](https://badge.fury.io/rb/array_enum.svg)](https://badge.fury.io/rb/array_enum)
2
+ [![BUILD](https://github.com/freeletics/array_enum/actions/workflows/ci-on-merge.yml/badge.svg)](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.with_favourite_colors("red") # => [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
- [![Build Status](https://travis-ci.com/freeletics/array_enum.svg?branch=master)](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
- diff = wrapped_value.reject { |element| delimiter.include?(element) }
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
 
@@ -1,3 +1,3 @@
1
1
  module ArrayEnum
2
- VERSION = "1.0.1"
2
+ VERSION = "1.4.0"
3
3
  end
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("with_#{attr_name}".to_sym) do |values|
14
- db_values = Array(values).map do |value|
15
- mapping[value.to_s] || raise(ArgumentError, MISSING_VALUE_MESSAGE % {value: value, attr: attr_name})
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| mapping.key(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
- mapping[value.to_s] || raise(ArgumentError, MISSING_VALUE_MESSAGE % {value: value, attr: attr_name})
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.1
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: 2019-01-10 00:00:00.000000000 Z
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.0.2
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
@@ -1,16 +0,0 @@
1
- dist: xenial
2
- language: ruby
3
- cache: bundler
4
- rvm:
5
- - 2.6.0
6
-
7
- addons:
8
- postgresql: "10"
9
-
10
- before_script:
11
- - psql -c 'create database "array_enum_test";' -U postgres
12
-
13
- script: "bundle exec rake"
14
-
15
- notifications:
16
- disabled: true