acts-as-taggable-array-on 0.5.1 → 0.7.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
2
  SHA256:
3
- metadata.gz: 9f7a6cf023c1dd9dd7f1d8e77db2772f2f673b233d5f2ad625115c0d28677879
4
- data.tar.gz: 84d46e102ab941b3a1a99c85ed2897ef5b09785f1c40a65356365710d3f500cb
3
+ metadata.gz: 02127b9b3ed01db1bf067d182c677ec562e8c8030670019897f34af8ba44d231
4
+ data.tar.gz: 52feb971a781b61175d31b68b181fac94d2b60e8ad092cfcef0b2195ed6c6ce7
5
5
  SHA512:
6
- metadata.gz: 7e6efedde0a9883e69acad7fc544daca55f0c8cd6a447cd65cdc77ba4c47380c61d3b93eb51c9378b98bd753af086afa61b90375418acd93e98b77e7ef7ec1bb
7
- data.tar.gz: 84e04cfc82640c5137aa59cecb8fbe7bd55d357509ac9fc3b8ae60b7eca25339f2fc933be711026bcc5e0511fc3af7c95ed290b0edd02247088e9578ac82d6ba
6
+ metadata.gz: 54ed464914256f747d5bc784a237da30629ae5c5f57bc7dea2c40c48c19f427541cbc264a2b41da17dc49f394a3e7f0362b7ab7f00806f0a856ab32c1e22d900
7
+ data.tar.gz: dd87d5d2ff3272b4613a48fa79de16e70d8c7535b980cc6ddd2be7967725a761451273abb4dbc04c915481c2dba386ee6d1271f5054975c2a1f133d9cbebdbe8
@@ -0,0 +1,48 @@
1
+ name: "Running Tests"
2
+
3
+ on:
4
+ - pull_request
5
+
6
+ env:
7
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
8
+
9
+ jobs:
10
+ test:
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ # Due to https://github.com/actions/runner/issues/849, we have to use quotes for '3.0'
15
+ ruby: ['2.7', '3.0', '3.1', 'head']
16
+ runs-on: ubuntu-latest
17
+
18
+ services:
19
+ postgres:
20
+ image: postgres:11.6
21
+ env:
22
+ POSTGRES_USER: postgres
23
+ POSTGRES_PASSWORD: ""
24
+ POSTGRES_DB: postgres
25
+ ports: ["5432:5432"]
26
+ options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
27
+ env:
28
+ RAILS_ENV: test
29
+ PGHOST: localhost
30
+ PGUSER: postgres
31
+
32
+ steps:
33
+ - uses: actions/checkout@v2
34
+ - uses: ruby/setup-ruby@v1
35
+ with:
36
+ ruby-version: ${{ matrix.ruby }}
37
+ # runs 'bundle install' and caches installed gems automatically
38
+ bundler-cache: true
39
+
40
+ - name: Create a database
41
+ run: rake db:create
42
+
43
+ - name: Install citext extension
44
+ run: |
45
+ psql -U postgres -d "acts-as-taggable-array-on_test" -c "CREATE EXTENSION IF NOT EXISTS citext;"
46
+
47
+ - name: Running a test
48
+ run: bundle exec rspec
data/.gitignore CHANGED
@@ -16,3 +16,4 @@ spec/reports
16
16
  test/tmp
17
17
  test/version_tmp
18
18
  tmp
19
+ .idea
data/.travis.yml CHANGED
@@ -1,22 +1,22 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.10
4
- - 2.2.9
5
- - 2.3.6
6
- - 2.4.3
7
- - 2.4.3
8
- - 2.5.0
9
- addons:
10
- postgresql: 9.3
3
+ - 2.5.7
4
+ - 2.6.5
5
+ - 2.7.0
6
+ - 3.0.0
7
+ services:
8
+ - postgresql
11
9
  gemfile:
12
- - gemfiles/rails_4.gemfile
13
- - gemfiles/rails_5.gemfile
10
+ - gemfiles/rails_5_2.gemfile
11
+ - gemfiles/rails_6_0.gemfile
12
+ - gemfiles/rails_6_1.gemfile
14
13
  before_script:
14
+ - cp config/database.yml.travis config/database.yml
15
15
  - bundle exec rake db:create
16
16
  script:
17
17
  - bundle
18
18
  - bundle exec rspec
19
19
  matrix:
20
20
  exclude:
21
- - rvm: 2.1.10
22
- gemfile: gemfiles/rails_5.gemfile
21
+ - rvm: 3.0.0
22
+ gemfile: gemfiles/rails_5_2.gemfile
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## 0.7.0
2
+ - Standard linter used as a style guide
3
+ - Ruby 2.4 support dropped
4
+ - Support for Ruby 3.0 added
5
+ - Support for Rails 6.1 added
6
+ - Support for citext arrays added
7
+
8
+ ## 0.6
9
+ - Drop support for `EOL` versions of Ruby (below `2.4)`, and Rails (below `5.2`)
10
+ - Alias `acts_as_taggable_on` to `taggable_array`
11
+ - Stop rails 6 deprecation warnings
12
+
1
13
  ## 0.5.1
2
14
  - Don't fail during load time if DB is missing
3
15
 
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in acts-as-pgarray-taggable-on.gemspec
4
4
  gemspec
data/Guardfile CHANGED
@@ -1,5 +1,5 @@
1
- guard 'rspec', cmd: 'rspec --drb --color' do
1
+ guard "rspec", cmd: "rspec --drb --color" do
2
2
  watch(%r{^spec/.+_spec\.rb})
3
- watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
- watch('spec/spec_helper.rb') { "spec" }
3
+ watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
+ watch("spec/spec_helper.rb") { "spec" }
5
5
  end
data/README.md CHANGED
@@ -1,16 +1,14 @@
1
1
  # ActsAsTaggableArrayOn
2
2
  [![Build Status](https://travis-ci.org/tmiyamon/acts-as-taggable-array-on.svg?branch=master)](https://travis-ci.org/tmiyamon/acts-as-taggable-array-on)
3
3
 
4
- A simple implementation for tagging system with postgres array.
5
- So, this gem works only on postgres.
6
-
4
+ A simple implementation for tagging system based on a database array type. Only PostgreSQL Arrays are currently supported.
7
5
 
8
6
  ## Installation
9
7
 
10
8
  Add this line to your application's Gemfile:
11
9
 
12
10
  ```ruby
13
- gem 'acts-as-taggable-array-on'
11
+ gem "acts-as-taggable-array-on"
14
12
  ```
15
13
 
16
14
  And then execute:
@@ -21,152 +19,157 @@ bundle
21
19
 
22
20
 
23
21
  ## Setup
24
-
25
- To use it, you need to have an array column to act as taggable.
22
+ To use it, you need to have an array column to act as taggable - `tags`.
26
23
 
27
24
  ```ruby
28
25
  class CreateUser < ActiveRecord::Migration
29
26
  def change
30
27
  create_table :users do |t|
31
- t.string :tags, array: true, default: '{}'
28
+ t.string :tags, array: true, default: []
32
29
  t.timestamps
33
30
  end
34
- add_index :users, :tags, using: 'gin'
31
+ add_index :users, :tags, using: "gin"
35
32
  end
36
33
  end
37
34
  ```
38
35
 
39
- and bundle:
36
+ - You can change from `string` to any other type here. But in case of any doubt, `string` is a great default.
37
+ - Make sure not to lose `default: []`, it's important to always have empty array as default.
38
+
39
+ Run a migration:
40
40
 
41
41
  ```shell
42
42
  rake db:migrate
43
43
  ```
44
44
 
45
- then
45
+ Indicate that attribute is "taggable" in a Rails model, like this:
46
46
 
47
47
  ```ruby
48
48
  class User < ActiveRecord::Base
49
- acts_as_taggable_array_on :tags
49
+ taggable_array :tags
50
50
  end
51
- @user = User.new(:name => "Bobby")
52
51
  ```
53
52
 
54
- acts_as_taggable_array_on defines 4 scope and 2 class methods as below.
55
-
56
- ### types
57
-
58
- currently, these types supported
59
-
60
- - varchar[]
61
- - text[]
62
- - integer[]
53
+ ### Types
54
+ We currently tested only following types for underlying arrays:
63
55
 
64
- ### scopes
65
-
66
- - with_any_#{tag_name}
67
- - with_all_#{tag_name}
68
- - without_any_#{tag_name}
69
- - without_all_#{tag_name}
70
-
71
- ### class methods
72
-
73
- - all_#{tag_name}
74
- - #{tag_name}_cloud
56
+ - `varchar[]`
57
+ - `t.string :tags, array: true, default: []`
58
+ - `add_column :users, :tags, :string, array: true, default: []`
59
+ - `text[]`
60
+ - `t.text :tags, array: true, default: []`
61
+ - `add_column :users, :tags, :text, array: true, default: []`
62
+ - `integer[]`
63
+ - `t.integer :tags, array: true, default: []`
64
+ - `add_column :users, :tags, :integer, array: true, default: []`
75
65
 
76
66
 
77
67
  ## Usage
78
68
 
79
- Set, add and remove
80
-
81
69
  ```ruby
82
70
  #set
83
- @user.tags = ["awesome", "slick"]
84
- @user.tags = '{awesome,slick}'
71
+ user.tags = ["awesome", "slick"]
72
+ user.tags = "{awesome,slick}"
85
73
 
86
74
  #add
87
- @user.tags += ["awesome"]
88
- @user.tags += ["awesome", "slick"]
75
+ user.tags += ["awesome"]
76
+ user.tags += ["awesome", "slick"]
77
+ user.tags << "awesome"
89
78
 
90
79
  #remove
91
- @user.tags -= ["awesome"]
92
- @user.tags -= ["awesome", "slick"]
80
+ user.tags -= ["awesome"]
81
+ user.tags -= ["awesome", "slick"]
93
82
  ```
94
83
 
95
- ### Finding Tagged Objects
84
+ ### Scopes
85
+
86
+ #### `with_any_#{tag_name}`
96
87
 
97
88
  ```ruby
98
- class User < ActiveRecord::Base
99
- acts_as_taggable_array_on :tags
100
- scope :by_join_date, ->{order("created_at DESC")}
101
- end
89
+ # Find a user with any of the tags
90
+ User.with_any_tags("awesome, slick")
91
+ User.with_any_tags(["awesome", "slick"])
92
+ ```
93
+
94
+ #### `with_all_#{tag_name}`
102
95
 
96
+ ```ruby
103
97
  # Find a user with all of the tags
104
98
  User.with_all_tags("awesome, slick")
105
99
  User.with_all_tags(["awesome", "slick"])
100
+ ```
106
101
 
107
- # Find a user with any of the tags
108
- User.with_any_tags("awesome, slick")
109
- User.with_any_tags(["awesome", "slick"])
110
-
111
- # Find a user without all of the tags
112
- User.without_all_tags("awesome, slick")
113
- User.without_all_tags(["awesome", "slick"])
102
+ #### `without_any_#{tag_name}`
114
103
 
104
+ ```ruby
115
105
  # Find a user without any of the tags
116
106
  User.without_any_tags("awesome, slick")
117
107
  User.without_any_tags(["awesome", "slick"])
108
+ ```
118
109
 
119
- # Chain with the other scopes
120
- User.with_any_tags("awesome").without_any_tags("slick").by_join_date.paginate(:page => params[:page], :per_page => 20)
110
+ #### `without_all_#{tag_name}`
111
+
112
+ ```ruby
113
+ # Find a user without all of the tags
114
+ User.without_all_tags("awesome, slick")
115
+ User.without_all_tags(["awesome", "slick"])
121
116
  ```
122
117
 
123
- ### Tag cloud calculations
124
118
 
125
- Calculation to count for each tags is supported. Currently, it does not care its order.
119
+ ### Class methods
120
+
121
+ #### `all_#{tag_name}`
126
122
 
127
123
  ```ruby
128
- User.tags_cloud
129
- # [['awesome' => 1], ['slick' => 2]]
124
+ User.all_tags
125
+ # ["awesome", "slick"]
130
126
  ```
131
127
 
132
- Tag cloud calculation uses subquery internally. To add scopes to the query, use block.
128
+ You can use block to add scopes to the query.
133
129
 
134
130
  ```ruby
135
- User.tags_cloud { where name: ['ken', 'tom'] }
131
+ User.all_tags { where(name: ["ken", "tom"]) }
136
132
  ```
137
133
 
138
- To handle the result tags named 'tag' and 'count', prepend scopes.
134
+ Or simply use your existing scopes:
139
135
 
140
136
  ```ruby
141
- User.where('tag like ?', 'aws%').limit(10).order('count desc').tags_cloud { where name: ['ken', 'tom'] }
137
+ # scope :by_join_date, ->{order("created_at DESC")}
138
+ User.all_tags.by_join_date
142
139
  ```
143
140
 
144
- ### All Tags
145
-
146
- Can get all tags easily.
141
+ SQL field is named "tag" and you can use it to modify the query.
147
142
 
148
143
  ```ruby
149
- User.all_tags
150
- # ['awesome', 'slick']
144
+ User.where("tag like ?", "aws%").all_tags { where(name: ["ken", "tom"]) }
151
145
  ```
152
146
 
153
- As the same to tag cloud calculation, you can use block to add scopes to the query.
147
+ #### `#{tag_name}_cloud`
154
148
 
149
+ Calculates the number of occurrences of each tag.
155
150
 
156
151
  ```ruby
157
- User.all_tags { where name: ['ken', 'tom'] }
152
+ User.tags_cloud
153
+ # [["slick" => 2], ["awesome" => 1]]
158
154
  ```
159
155
 
160
- To handle the result tags named 'tag', prepend scopes.
156
+ You can use block to add scopes to the query.
161
157
 
162
158
  ```ruby
163
- User.where('tag like ?', 'aws%').all_tags { where name: ['ken', 'tom'] }
159
+ User.tags_cloud { where(name: ["ken", "tom"]) }
164
160
  ```
165
161
 
162
+ SQL fields are named "tag" and "count" and you can use them to modify the query.
163
+
164
+ ```ruby
165
+ User.where("tag like ?", "aws%").limit(10).order("count desc").tags_cloud { where(name: ["ken", "tom"]) }
166
+ ```
167
+
168
+
166
169
  ## Benchmark
167
- Based on the [article](https://adamnengland.wordpress.com/2014/02/19/benchmarks-acts-as-taggable-on-vs-postgresql-arrays/), I built [simple benchmark app](https://github.com/tmiyamon/acts-as-taggable-benchmark/) to compare only the main features acts-as-taggable-array-on has.
170
+ Based on the [article](https://adamnengland.wordpress.com/2014/02/19/benchmarks-acts-as-taggable-on-vs-postgresql-arrays/), I built [simple benchmark app](https://github.com/tmiyamon/acts-as-taggable-benchmark/) to compare only the main features ActsAsTaggableArrayOn has.
168
171
 
169
- This result does NOT insist acts-as-taggable-array-on is better than acts-as-taggable-on since it provides much more features than this gem.
172
+ This result does NOT insist ActsAsTaggableArrayOn is better than acts-as-taggable-on since it provides much more features than this gem.
170
173
  In the case you need simple tag functionality, acts-as-taggable-array-on may be helpful to improve its performance.
171
174
 
172
175
  ```bash
@@ -217,8 +220,10 @@ rake bench:write bench:find_by_id bench:find_by_tag 20.29s user 1.52s system 77
217
220
  ```
218
221
 
219
222
  ## Development
220
- To run testsuite you'll need to setup local PG database/user with `rake db:create`
223
+
224
+ - To run testsuite you'll need to setup local PG database/user with `rake db:create`
221
225
  After that just running `rspec` should work.
226
+ - Before submitting code for a review, please be sure to run `bundle exec standardrb --fix`
222
227
 
223
228
  ## Contributing
224
229
 
data/Rakefile CHANGED
@@ -1,9 +1,9 @@
1
1
  require "bundler/gem_tasks"
2
2
 
3
3
  namespace :db do
4
- desc "Create database for tests"
4
+ desc "Create database for tests"
5
5
  task :create do
6
- puts %x( createuser -d acts-as-taggable-array-on -U postgres )
7
- puts %x( createdb --username=acts-as-taggable-array-on acts-as-taggable-array-on_test )
6
+ puts `createuser -d acts-as-taggable-array-on -U postgres`
7
+ puts `createdb --username=acts-as-taggable-array-on acts-as-taggable-array-on_test`
8
8
  end
9
9
  end
@@ -1,31 +1,31 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path("../lib", __FILE__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'acts-as-taggable-array-on/version'
3
+ require "acts-as-taggable-array-on/version"
5
4
 
6
5
  Gem::Specification.new do |spec|
7
- spec.name = "acts-as-taggable-array-on"
8
- spec.version = ActsAsTagPgarray::VERSION
9
- spec.authors = ["Takuya Miyamoto"]
10
- spec.email = ["miyamototakuya@gmail.com"]
11
- spec.summary = %q{Simple tagging gem for Rails using postgres array.}
12
- spec.description = %q{Simple tagging gem for Rails using postgres array.}
13
- spec.homepage = "https://github.com/tmiyamon/acts-as-taggable-array-on"
14
- spec.license = "MIT"
6
+ spec.name = "acts-as-taggable-array-on"
7
+ spec.version = ActsAsTagPgarray::VERSION
8
+ spec.authors = ["Takuya Miyamoto"]
9
+ spec.email = ["miyamototakuya@gmail.com"]
10
+ spec.summary = "Simple tagging gem for Rails using postgres array."
11
+ spec.description = "Simple tagging gem for Rails using postgres array."
12
+ spec.homepage = "https://github.com/tmiyamon/acts-as-taggable-array-on"
13
+ spec.license = "MIT"
15
14
 
16
- spec.files = `git ls-files -z`.split("\x0")
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
18
  spec.require_paths = ["lib"]
20
19
 
21
- spec.add_runtime_dependency 'activerecord', ['>= 4']
22
- spec.add_runtime_dependency 'activesupport', ['>= 4']
20
+ spec.add_runtime_dependency "activerecord", [">= 5.2"]
21
+ spec.add_runtime_dependency "activesupport", [">= 5.2"]
23
22
 
24
- spec.add_development_dependency 'pg', '~> 0.18'
23
+ spec.add_development_dependency "pg", "~> 1.1"
25
24
 
26
- spec.add_development_dependency "bundler", "~> 1.5"
25
+ spec.add_development_dependency "bundler"
26
+ spec.add_development_dependency "guard-rspec"
27
+ spec.add_development_dependency "listen", "> 3.0"
27
28
  spec.add_development_dependency "rake"
28
29
  spec.add_development_dependency "rspec-rails"
29
- spec.add_development_dependency "guard-rspec"
30
- spec.add_development_dependency "listen", "~> 3.0.0"
30
+ spec.add_development_dependency "standard"
31
31
  end
@@ -0,0 +1,3 @@
1
+ test:
2
+ adapter: postgresql
3
+ database: travis_ci_test
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in acts-as-pgarray-taggable-on.gemspec
4
+ gemspec path: "../"
5
+
6
+ gem "activerecord", "~> 5.2.0"
7
+ gem "activesupport", "~> 5.2.0"
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in acts-as-taggable-array-on.gemspec
4
+ gemspec path: "../"
5
+
6
+ gem "activerecord", "~> 6.0.3.4"
7
+ gem "activesupport", "~> 6.0.3.4"
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in acts-as-taggable-array-on.gemspec
4
+ gemspec path: "../"
5
+
6
+ gem "activerecord", "~> 6.1.0"
7
+ gem "activesupport", "~> 6.1.0"
@@ -5,7 +5,7 @@ module ActsAsTaggableArrayOn
5
5
  def parse tags
6
6
  case tags
7
7
  when String
8
- tags.split(/[ ]*,[ ]*/)
8
+ tags.split(/ *, */)
9
9
  else
10
10
  tags
11
11
  end
@@ -6,7 +6,7 @@ module ActsAsTaggableArrayOn
6
6
  base.extend(ClassMethod)
7
7
  end
8
8
 
9
- TYPE_MATCHER = { string: 'varchar', text: 'text', integer: 'integer' }
9
+ TYPE_MATCHER = {string: "varchar", text: "text", integer: "integer", citext: "citext"}
10
10
 
11
11
  module ClassMethod
12
12
  def acts_as_taggable_array_on(tag_name, *)
@@ -22,18 +22,19 @@ module ActsAsTaggableArrayOn
22
22
  define_method :"all_#{tag_name}" do |options = {}, &block|
23
23
  subquery_scope = unscoped.select("unnest(#{table_name}.#{tag_name}) as tag").distinct
24
24
  subquery_scope = subquery_scope.instance_eval(&block) if block
25
-
26
- from(subquery_scope).pluck('tag')
25
+ # Remove the STI inheritance type from the outer query since it is in the subquery
26
+ unscope(where: :type).from(subquery_scope).pluck(:tag)
27
27
  end
28
28
 
29
29
  define_method :"#{tag_name}_cloud" do |options = {}, &block|
30
30
  subquery_scope = unscoped.select("unnest(#{table_name}.#{tag_name}) as tag")
31
31
  subquery_scope = subquery_scope.instance_eval(&block) if block
32
-
33
- from(subquery_scope).group('tag').order('tag').pluck('tag, count(*) as count')
32
+ # Remove the STI inheritance type from the outer query since it is in the subquery
33
+ unscope(where: :type).from(subquery_scope).group(:tag).order(:tag).count(:tag)
34
34
  end
35
35
  end
36
36
  end
37
+ alias_method :taggable_array, :acts_as_taggable_array_on
37
38
  end
38
39
  end
39
40
  end
@@ -1,3 +1,3 @@
1
1
  module ActsAsTagPgarray
2
- VERSION = "0.5.1"
2
+ VERSION = "0.7.0"
3
3
  end
@@ -1,4 +1,4 @@
1
- require 'active_record'
1
+ require "active_record"
2
2
 
3
3
  require "acts-as-taggable-array-on/version"
4
4
  require "acts-as-taggable-array-on/taggable"
@@ -1,22 +1,22 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe ActsAsTaggableArrayOn::Parser do
4
4
  let(:parser) { ActsAsTaggableArrayOn.parser }
5
5
 
6
- describe '#parse' do
6
+ describe "#parse" do
7
7
  it "return unprocessed tags if array" do
8
- tags = %w(red green)
8
+ tags = %w[red green]
9
9
  expect(parser.parse(tags)).to eq tags
10
10
  end
11
11
 
12
12
  it "return parsed tags if comma separated string" do
13
- tags = 'red,green'
14
- expect(parser.parse(tags)).to eq %w(red green)
13
+ tags = "red,green"
14
+ expect(parser.parse(tags)).to eq %w[red green]
15
15
  end
16
16
 
17
17
  it "return parsed tags if comma separated string including white spaces" do
18
- tags = 'red , gre en'
19
- expect(parser.parse(tags)).to eq ['red', 'gre en']
18
+ tags = "red , gre en"
19
+ expect(parser.parse(tags)).to eq ["red", "gre en"]
20
20
  end
21
21
  end
22
22
  end
@@ -1,16 +1,19 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe ActsAsTaggableArrayOn::Taggable do
4
4
  before do
5
- @user1 = User.create name: 'Tom', colors: ['red', 'blue'], sizes: ['medium', 'large'], codes: [456, 789]
6
- @user2 = User.create name: 'Ken', colors: ['black', 'white', 'red'], sizes: ['small', 'large'], codes: [123, 789]
7
- @user3 = User.create name: 'Joe', colors: ['black', 'blue'], sizes: ['small', 'medium', 'large'], codes: [123, 456, 789]
5
+ @user1 = User.create name: "Tom", colors: ["red", "blue"], sizes: ["medium", "large"], codes: [456, 789], roles: ["user"]
6
+ @user2 = User.create name: "Ken", colors: ["black", "white", "red"], sizes: ["small", "large"], codes: [123, 789], roles: ["User"]
7
+ @user3 = User.create name: "Joe", colors: ["black", "blue"], sizes: ["small", "medium", "large"], codes: [123, 456, 789], roles: ["login"]
8
+ @admin1 = Admin.create name: "Dick", colors: ["purple", "orange"], sizes: ["medium", "large"], codes: [123, 456, 789], roles: ["USER", "Admin"]
9
+ @admin2 = Admin.create name: "Harry", colors: ["white", "blue"], sizes: ["small", "large"], codes: [456, 123], roles: ["Admin"]
8
10
 
9
11
  User.acts_as_taggable_array_on :colors
10
12
  User.acts_as_taggable_array_on :sizes
11
- User.acts_as_taggable_array_on :codes
12
- end
13
+ User.acts_as_taggable_array_on :roles
14
+ User.taggable_array :codes
13
15
 
16
+ end
14
17
 
15
18
  context "without database table" do
16
19
  it "doesn't fail on class method call" do
@@ -34,109 +37,134 @@ describe ActsAsTaggableArrayOn::Taggable do
34
37
  end
35
38
  end
36
39
 
37
- it 'should define table name un-ambiguously' do
38
- sql = User.with_any_sizes(['small']).to_sql
40
+ describe "#taggable_array_on" do
41
+ it "defines named scope to match any tags" do
42
+ expect(User).to respond_to(:with_any_codes)
43
+ end
44
+ it "defines named scope to match all tags" do
45
+ expect(User).to respond_to(:with_all_codes)
46
+ end
47
+ it "defines named scope not to match any tags" do
48
+ expect(User).to respond_to(:without_any_codes)
49
+ end
50
+ it "defines named scope not to match all tags" do
51
+ expect(User).to respond_to(:without_all_codes)
52
+ end
53
+ end
54
+
55
+ it "should define table name un-ambiguously" do
56
+ sql = User.with_any_sizes(["small"]).to_sql
39
57
  expect(sql).to eql("SELECT \"users\".* FROM \"users\" WHERE (users.sizes && ARRAY['small']::text[])")
40
58
 
41
- sql = User.with_all_sizes(['small']).to_sql
59
+ sql = User.with_all_sizes(["small"]).to_sql
42
60
  expect(sql).to eql("SELECT \"users\".* FROM \"users\" WHERE (users.sizes @> ARRAY['small']::text[])")
43
61
 
44
- sql = User.without_any_sizes(['small']).to_sql
45
- expect(sql).to eql("SELECT \"users\".* FROM \"users\" WHERE (NOT (users.sizes && ARRAY['small']::text[]))")
62
+ sql = User.without_any_sizes(["small"]).to_sql
63
+ expect(sql).to eql("SELECT \"users\".* FROM \"users\" WHERE NOT (users.sizes && ARRAY['small']::text[])")
46
64
 
47
- sql = User.without_all_sizes(['small']).to_sql
48
- expect(sql).to eql("SELECT \"users\".* FROM \"users\" WHERE (NOT (users.sizes @> ARRAY['small']::text[]))")
65
+ sql = User.without_all_sizes(["small"]).to_sql
66
+ expect(sql).to eql("SELECT \"users\".* FROM \"users\" WHERE NOT (users.sizes @> ARRAY['small']::text[])")
49
67
  end
50
68
 
51
69
  it "should work with ::text typed array" do
52
- expect(User.with_any_sizes(['small'])).to match_array([@user2,@user3])
53
- expect(User.with_all_sizes(['small', 'large'])).to match_array([@user2,@user3])
54
- expect(User.without_any_sizes('medium')).to match_array([@user2])
55
- expect(User.without_all_sizes('medium')).to match_array([@user2])
70
+ expect(User.with_any_sizes(["small"])).to match_array([@user2, @user3, @admin2])
71
+ expect(User.with_all_sizes(["small", "large"])).to match_array([@user2, @user3, @admin2])
72
+ expect(User.without_any_sizes("medium")).to match_array([@user2, @admin2])
73
+ expect(User.without_all_sizes("medium")).to match_array([@user2, @admin2])
74
+ end
75
+
76
+ it "should work with ::citext typed array" do
77
+ expect(User.with_any_roles(["admin"])).to match_array([@admin1, @admin2])
78
+ expect(User.with_all_roles(["User", "Admin"])).to match_array([@admin1])
79
+ expect(User.without_any_roles("USER")).to match_array([@user3, @admin2])
80
+ expect(User.without_all_roles("UseR")).to match_array([@user3, @admin2])
56
81
  end
57
82
 
58
83
  it "should work with ::integer typed array" do
59
- expect(User.with_any_codes([123])).to match_array([@user2,@user3])
60
- expect(User.with_all_codes([123, 789])).to match_array([@user2,@user3])
84
+ expect(User.with_any_codes([123])).to match_array([@user2, @user3, @admin1, @admin2])
85
+ expect(User.with_all_codes([123, 789])).to match_array([@user2, @user3, @admin1])
61
86
  expect(User.without_any_codes(456)).to match_array([@user2])
62
87
  expect(User.without_all_codes(456)).to match_array([@user2])
63
88
  end
64
89
 
65
90
  describe "#with_any_tags" do
66
91
  it "returns users having any tags of args" do
67
- expect(User.with_any_colors(['red', 'blue'])).to match_array([@user1,@user2,@user3])
68
- expect(User.with_any_colors('red, blue')).to match_array([@user1,@user2,@user3])
92
+ expect(User.with_any_colors(["red", "blue"])).to match_array([@user1, @user2, @user3, @admin2])
93
+ expect(User.with_any_colors("red, blue")).to match_array([@user1, @user2, @user3, @admin2])
69
94
  end
70
95
  end
71
96
 
72
97
  describe "#with_all_tags" do
73
98
  it "returns users having all tags of args" do
74
- expect(User.with_all_colors(['red', 'blue'])).to match_array([@user1])
75
- expect(User.with_all_colors('red, blue')).to match_array([@user1])
99
+ expect(User.with_all_colors(["red", "blue"])).to match_array([@user1])
100
+ expect(User.with_all_colors("red, blue")).to match_array([@user1])
76
101
  end
77
102
  end
78
103
 
79
104
  describe "#without_any_tags" do
80
105
  it "returns users not having any tags of args" do
81
- expect(User.without_any_colors(['red', 'blue'])).to match_array([])
82
- expect(User.without_any_colors('red, blue')).to match_array([])
106
+ expect(User.without_any_colors(["red", "blue"])).to match_array([@admin1])
107
+ expect(User.without_any_colors("red, blue")).to match_array([@admin1])
83
108
  end
84
109
  end
85
110
 
86
111
  describe "#without_all_tags" do
87
112
  it "returns users not having all tags of args" do
88
- expect(User.without_all_colors(['red', 'blue'])).to match_array([@user2,@user3])
89
- expect(User.without_all_colors('red, blue')).to match_array([@user2,@user3])
113
+ expect(User.without_all_colors(["red", "blue"])).to match_array([@user2, @user3, @admin1, @admin2])
114
+ expect(User.without_all_colors("red, blue")).to match_array([@user2, @user3, @admin1, @admin2])
90
115
  end
91
116
  end
92
117
 
93
118
  describe "#all_colors" do
94
119
  it "returns all of tag_name" do
95
- expect(User.all_colors).to match_array([@user1,@user2,@user3].map(&:colors).flatten.uniq)
120
+ expect(User.all_colors).to match_array([@user1, @user2, @user3, @admin1, @admin2].map(&:colors).flatten.uniq)
121
+ expect(Admin.all_colors).to match_array([@admin1, @admin2].map(&:colors).flatten.uniq)
96
122
  end
97
123
 
98
124
  it "returns filtered tags for tag_name with block" do
99
- expect(User.all_colors{where(name: ["Ken", "Joe"])}).to match_array([@user2,@user3].map(&:colors).flatten.uniq)
125
+ expect(User.all_colors { where(name: ["Ken", "Joe"]) }).to match_array([@user2, @user3].map(&:colors).flatten.uniq)
126
+ expect(Admin.all_colors { where(name: ["Dick", "Harry"]) }).to match_array([@admin1, @admin2].map(&:colors).flatten.uniq)
100
127
  end
101
128
 
102
129
  it "returns filtered tags for tag_name with prepended scope" do
103
- expect(User.where('tag like ?', 'bl%').all_colors).to match_array([@user1,@user2,@user3].map(&:colors).flatten.uniq.select{|name| name.start_with? 'bl'})
130
+ expect(User.where("tag like ?", "bl%").all_colors).to match_array([@user1, @user2, @user3].map(&:colors).flatten.uniq.select { |name| name.start_with? "bl" })
131
+ expect(Admin.where("tag like ?", "bl%").all_colors).to match_array([@admin2].map(&:colors).flatten.uniq.select { |name| name.start_with? "bl" })
104
132
  end
105
133
 
106
134
  it "returns filtered tags for tag_name with prepended scope and bock" do
107
- expect(User.where('tag like ?', 'bl%').all_colors{where(name: ["Ken", "Joe"])}).to match_array([@user2,@user3].map(&:colors).flatten.uniq.select{|name| name.start_with? 'bl'})
135
+ expect(User.where("tag like ?", "bl%").all_colors { where(name: ["Ken", "Joe"]) }).to match_array([@user2, @user3].map(&:colors).flatten.uniq.select { |name| name.start_with? "bl" })
108
136
  end
109
137
  end
110
138
 
111
139
  describe "#colors_cloud" do
112
140
  it "returns tag cloud for tag_name" do
113
141
  expect(User.colors_cloud).to match_array(
114
- [@user1,@user2,@user3].map(&:colors).flatten.group_by(&:to_s).map{|k,v| [k,v.count]}
142
+ [@user1, @user2, @user3, @admin1, @admin2].map(&:colors).flatten.group_by(&:to_s).map { |k, v| [k, v.count] }
115
143
  )
116
144
  end
117
145
 
118
146
  it "returns filtered tag cloud for tag_name with block" do
119
- expect(User.colors_cloud{where(name: ["Ken", "Joe"])}).to match_array(
120
- [@user2,@user3].map(&:colors).flatten.group_by(&:to_s).map{|k,v| [k,v.count]}
147
+ expect(User.colors_cloud { where(name: ["Ken", "Joe"]) }).to match_array(
148
+ [@user2, @user3].map(&:colors).flatten.group_by(&:to_s).map { |k, v| [k, v.count] }
121
149
  )
122
150
  end
123
151
 
124
152
  it "returns filtered tag cloud for tag_name with prepended scope" do
125
- expect(User.where('tag like ?', 'bl%').colors_cloud).to match_array(
126
- [@user1,@user2,@user3].map(&:colors).flatten.group_by(&:to_s).map{|k,v| [k,v.count]}.select{|name,count| name.start_with? 'bl'}
153
+ expect(User.where("tag like ?", "bl%").colors_cloud).to match_array(
154
+ [@user1, @user2, @user3, @admin2].map(&:colors).flatten.group_by(&:to_s).map { |k, v| [k, v.count] }.select { |name, count| name.start_with? "bl" }
127
155
  )
128
156
  end
129
157
 
130
158
  it "returns filtered tag cloud for tag_name with prepended scope and block" do
131
- expect(User.where('tag like ?', 'bl%').colors_cloud{where(name: ["Ken", "Joe"])}).to match_array(
132
- [@user2,@user3].map(&:colors).flatten.group_by(&:to_s).map{|k,v| [k,v.count]}.select{|name,count| name.start_with? 'bl'}
159
+ expect(User.where("tag like ?", "bl%").colors_cloud { where(name: ["Ken", "Joe"]) }).to match_array(
160
+ [@user2, @user3].map(&:colors).flatten.group_by(&:to_s).map { |k, v| [k, v.count] }.select { |name, count| name.start_with? "bl" }
133
161
  )
134
162
  end
135
163
  end
136
164
 
137
165
  describe "with complex scope" do
138
166
  it "works properly" do
139
- expect(User.without_any_colors('white').with_any_colors('blue').order(:created_at).limit(10)).to eq [@user1, @user3]
167
+ expect(User.without_any_colors("white").with_any_colors("blue").order(:created_at).limit(10)).to eq [@user1, @user3]
140
168
  end
141
169
  end
142
170
  end
data/spec/spec_helper.rb CHANGED
@@ -1,23 +1,24 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
2
2
  $LOAD_PATH.unshift(File.dirname(__FILE__))
3
- require 'rspec'
4
- require 'active_record/railtie'
3
+ require "rspec"
4
+ require "active_record/railtie"
5
5
  ActiveRecord::Base.logger = Logger.new(STDERR)
6
6
  ActiveRecord::Base.logger.level = 3
7
7
 
8
- require 'acts-as-taggable-array-on'
8
+ require "acts-as-taggable-array-on"
9
9
 
10
- #Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
10
+ # Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
11
11
 
12
12
  ActiveRecord::Migration.verbose = false
13
13
 
14
14
  class User < ActiveRecord::Base; end
15
+ class Admin < User; end
15
16
 
16
17
  RSpec.configure do |config|
17
18
  config.before(:all) do
18
19
  ActiveRecord::Base.establish_connection(
19
20
  adapter: "postgresql",
20
- encoding: 'unicode',
21
+ encoding: "unicode",
21
22
  database: "acts-as-taggable-array-on_test",
22
23
  username: "acts-as-taggable-array-on"
23
24
  )
@@ -34,12 +35,16 @@ RSpec.configure do |config|
34
35
  end
35
36
 
36
37
  def create_database
37
- ActiveRecord::Schema.define(:version => 1) do
38
+ ActiveRecord::Schema.define(version: 1) do
39
+ enable_extension("citext") unless extensions.include?("citext")
40
+
38
41
  create_table :users do |t|
39
42
  t.string :name
43
+ t.string :type
40
44
  t.string :colors, array: true, default: []
41
- t.text :sizes, array:true, default: []
45
+ t.text :sizes, array: true, default: []
42
46
  t.integer :codes, array: true, default: []
47
+ t.citext :roles, array: true, default: []
43
48
  t.timestamps null: true
44
49
  end
45
50
  end
data/spec_helper.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'rubygems'
1
+ require "rubygems"
2
2
 
3
3
  RSpec::Matchers.define :my_matcher do |expected|
4
4
  match do |actual|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts-as-taggable-array-on
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Takuya Miyamoto
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-17 00:00:00.000000000 Z
11
+ date: 2023-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,58 +16,58 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4'
19
+ version: '5.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '4'
26
+ version: '5.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activesupport
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '4'
33
+ version: '5.2'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '4'
40
+ version: '5.2'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: pg
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0.18'
47
+ version: '1.1'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0.18'
54
+ version: '1.1'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '1.5'
61
+ version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '1.5'
68
+ version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rake
70
+ name: guard-rspec
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -81,7 +81,21 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: rspec-rails
84
+ name: listen
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - ">="
@@ -95,7 +109,7 @@ dependencies:
95
109
  - !ruby/object:Gem::Version
96
110
  version: '0'
97
111
  - !ruby/object:Gem::Dependency
98
- name: guard-rspec
112
+ name: rspec-rails
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
115
  - - ">="
@@ -109,19 +123,19 @@ dependencies:
109
123
  - !ruby/object:Gem::Version
110
124
  version: '0'
111
125
  - !ruby/object:Gem::Dependency
112
- name: listen
126
+ name: standard
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
- - - "~>"
129
+ - - ">="
116
130
  - !ruby/object:Gem::Version
117
- version: 3.0.0
131
+ version: '0'
118
132
  type: :development
119
133
  prerelease: false
120
134
  version_requirements: !ruby/object:Gem::Requirement
121
135
  requirements:
122
- - - "~>"
136
+ - - ">="
123
137
  - !ruby/object:Gem::Version
124
- version: 3.0.0
138
+ version: '0'
125
139
  description: Simple tagging gem for Rails using postgres array.
126
140
  email:
127
141
  - miyamototakuya@gmail.com
@@ -130,6 +144,7 @@ extensions: []
130
144
  extra_rdoc_files: []
131
145
  files:
132
146
  - ".editorconfig"
147
+ - ".github/workflows/tests.yml"
133
148
  - ".gitignore"
134
149
  - ".travis.yml"
135
150
  - CHANGELOG.md
@@ -139,8 +154,10 @@ files:
139
154
  - README.md
140
155
  - Rakefile
141
156
  - acts-as-taggable-array-on.gemspec
142
- - gemfiles/rails_4.gemfile
143
- - gemfiles/rails_5.gemfile
157
+ - config/database.yml.travis
158
+ - gemfiles/rails_5_2.gemfile
159
+ - gemfiles/rails_6_0.gemfile
160
+ - gemfiles/rails_6_1.gemfile
144
161
  - lib/acts-as-taggable-array-on.rb
145
162
  - lib/acts-as-taggable-array-on/parser.rb
146
163
  - lib/acts-as-taggable-array-on/taggable.rb
@@ -153,7 +170,7 @@ homepage: https://github.com/tmiyamon/acts-as-taggable-array-on
153
170
  licenses:
154
171
  - MIT
155
172
  metadata: {}
156
- post_install_message:
173
+ post_install_message:
157
174
  rdoc_options: []
158
175
  require_paths:
159
176
  - lib
@@ -168,9 +185,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
185
  - !ruby/object:Gem::Version
169
186
  version: '0'
170
187
  requirements: []
171
- rubyforge_project:
172
- rubygems_version: 2.7.6
173
- signing_key:
188
+ rubygems_version: 3.3.7
189
+ signing_key:
174
190
  specification_version: 4
175
191
  summary: Simple tagging gem for Rails using postgres array.
176
192
  test_files:
@@ -1,7 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in acts-as-pgarray-taggable-on.gemspec
4
- gemspec path: '../'
5
-
6
- gem 'activerecord', '>= 4', '< 5'
7
- gem 'activesupport', '>= 4', '< 5'
@@ -1,7 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in acts-as-pgarray-taggable-on.gemspec
4
- gemspec path: '../'
5
-
6
- gem 'activerecord', '~> 5.0.0'
7
- gem 'activesupport', '~> 5.0.0'