acts-as-taggable-array-on 0.6.0 → 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 +4 -4
- data/.github/workflows/tests.yml +48 -0
- data/.gitignore +1 -0
- data/.travis.yml +5 -3
- data/CHANGELOG.md +7 -0
- data/Gemfile +1 -1
- data/Guardfile +3 -3
- data/README.md +78 -72
- data/Rakefile +3 -3
- data/acts-as-taggable-array-on.gemspec +19 -19
- data/gemfiles/rails_5_2.gemfile +4 -4
- data/gemfiles/rails_6_0.gemfile +5 -5
- data/gemfiles/rails_6_1.gemfile +7 -0
- data/lib/acts-as-taggable-array-on/parser.rb +1 -1
- data/lib/acts-as-taggable-array-on/taggable.rb +6 -6
- data/lib/acts-as-taggable-array-on/version.rb +1 -1
- data/lib/acts-as-taggable-array-on.rb +1 -1
- data/spec/acts_as_tag_pgarray/parser_spec.rb +7 -7
- data/spec/acts_as_tag_pgarray/taggable_spec.rb +49 -36
- data/spec/spec_helper.rb +13 -8
- data/spec_helper.rb +1 -1
- metadata +30 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 02127b9b3ed01db1bf067d182c677ec562e8c8030670019897f34af8ba44d231
|
4
|
+
data.tar.gz: 52feb971a781b61175d31b68b181fac94d2b60e8ad092cfcef0b2195ed6c6ce7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
data/.travis.yml
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 2.4.8
|
4
3
|
- 2.5.7
|
5
4
|
- 2.6.5
|
5
|
+
- 2.7.0
|
6
|
+
- 3.0.0
|
6
7
|
services:
|
7
8
|
- postgresql
|
8
9
|
gemfile:
|
9
10
|
- gemfiles/rails_5_2.gemfile
|
10
11
|
- gemfiles/rails_6_0.gemfile
|
12
|
+
- gemfiles/rails_6_1.gemfile
|
11
13
|
before_script:
|
12
14
|
- cp config/database.yml.travis config/database.yml
|
13
15
|
- bundle exec rake db:create
|
@@ -16,5 +18,5 @@ script:
|
|
16
18
|
- bundle exec rspec
|
17
19
|
matrix:
|
18
20
|
exclude:
|
19
|
-
- rvm:
|
20
|
-
gemfile: gemfiles/
|
21
|
+
- rvm: 3.0.0
|
22
|
+
gemfile: gemfiles/rails_5_2.gemfile
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
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
|
+
|
1
8
|
## 0.6
|
2
9
|
- Drop support for `EOL` versions of Ruby (below `2.4)`, and Rails (below `5.2`)
|
3
10
|
- Alias `acts_as_taggable_on` to `taggable_array`
|
data/Gemfile
CHANGED
data/Guardfile
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
guard
|
1
|
+
guard "rspec", cmd: "rspec --drb --color" do
|
2
2
|
watch(%r{^spec/.+_spec\.rb})
|
3
|
-
watch(%r{^lib/(.+)\.rb})
|
4
|
-
watch(
|
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,15 +1,14 @@
|
|
1
1
|
# ActsAsTaggableArrayOn
|
2
2
|
[](https://travis-ci.org/tmiyamon/acts-as-taggable-array-on)
|
3
3
|
|
4
|
-
A simple implementation for tagging system
|
5
|
-
|
4
|
+
A simple implementation for tagging system based on a database array type. Only PostgreSQL Arrays are currently supported.
|
6
5
|
|
7
6
|
## Installation
|
8
7
|
|
9
8
|
Add this line to your application's Gemfile:
|
10
9
|
|
11
10
|
```ruby
|
12
|
-
gem
|
11
|
+
gem "acts-as-taggable-array-on"
|
13
12
|
```
|
14
13
|
|
15
14
|
And then execute:
|
@@ -20,152 +19,157 @@ bundle
|
|
20
19
|
|
21
20
|
|
22
21
|
## Setup
|
23
|
-
|
24
|
-
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`.
|
25
23
|
|
26
24
|
```ruby
|
27
25
|
class CreateUser < ActiveRecord::Migration
|
28
26
|
def change
|
29
27
|
create_table :users do |t|
|
30
|
-
t.string :tags, array: true, default:
|
28
|
+
t.string :tags, array: true, default: []
|
31
29
|
t.timestamps
|
32
30
|
end
|
33
|
-
add_index :users, :tags, using:
|
31
|
+
add_index :users, :tags, using: "gin"
|
34
32
|
end
|
35
33
|
end
|
36
34
|
```
|
37
35
|
|
38
|
-
|
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:
|
39
40
|
|
40
41
|
```shell
|
41
42
|
rake db:migrate
|
42
43
|
```
|
43
44
|
|
44
|
-
|
45
|
+
Indicate that attribute is "taggable" in a Rails model, like this:
|
45
46
|
|
46
47
|
```ruby
|
47
48
|
class User < ActiveRecord::Base
|
48
49
|
taggable_array :tags
|
49
50
|
end
|
50
|
-
@user = User.new(:name => "Bobby")
|
51
51
|
```
|
52
52
|
|
53
|
-
|
54
|
-
|
55
|
-
### types
|
56
|
-
|
57
|
-
currently, these types supported
|
58
|
-
|
59
|
-
- varchar[]
|
60
|
-
- text[]
|
61
|
-
- integer[]
|
53
|
+
### Types
|
54
|
+
We currently tested only following types for underlying arrays:
|
62
55
|
|
63
|
-
|
64
|
-
|
65
|
-
-
|
66
|
-
-
|
67
|
-
-
|
68
|
-
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
- all_#{tag_name}
|
73
|
-
- #{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: []`
|
74
65
|
|
75
66
|
|
76
67
|
## Usage
|
77
68
|
|
78
|
-
Set, add and remove
|
79
|
-
|
80
69
|
```ruby
|
81
70
|
#set
|
82
|
-
|
83
|
-
|
71
|
+
user.tags = ["awesome", "slick"]
|
72
|
+
user.tags = "{awesome,slick}"
|
84
73
|
|
85
74
|
#add
|
86
|
-
|
87
|
-
|
75
|
+
user.tags += ["awesome"]
|
76
|
+
user.tags += ["awesome", "slick"]
|
77
|
+
user.tags << "awesome"
|
88
78
|
|
89
79
|
#remove
|
90
|
-
|
91
|
-
|
80
|
+
user.tags -= ["awesome"]
|
81
|
+
user.tags -= ["awesome", "slick"]
|
92
82
|
```
|
93
83
|
|
94
|
-
###
|
84
|
+
### Scopes
|
85
|
+
|
86
|
+
#### `with_any_#{tag_name}`
|
95
87
|
|
96
88
|
```ruby
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
89
|
+
# Find a user with any of the tags
|
90
|
+
User.with_any_tags("awesome, slick")
|
91
|
+
User.with_any_tags(["awesome", "slick"])
|
92
|
+
```
|
101
93
|
|
94
|
+
#### `with_all_#{tag_name}`
|
95
|
+
|
96
|
+
```ruby
|
102
97
|
# Find a user with all of the tags
|
103
98
|
User.with_all_tags("awesome, slick")
|
104
99
|
User.with_all_tags(["awesome", "slick"])
|
100
|
+
```
|
105
101
|
|
106
|
-
#
|
107
|
-
User.with_any_tags("awesome, slick")
|
108
|
-
User.with_any_tags(["awesome", "slick"])
|
109
|
-
|
110
|
-
# Find a user without all of the tags
|
111
|
-
User.without_all_tags("awesome, slick")
|
112
|
-
User.without_all_tags(["awesome", "slick"])
|
102
|
+
#### `without_any_#{tag_name}`
|
113
103
|
|
104
|
+
```ruby
|
114
105
|
# Find a user without any of the tags
|
115
106
|
User.without_any_tags("awesome, slick")
|
116
107
|
User.without_any_tags(["awesome", "slick"])
|
108
|
+
```
|
117
109
|
|
118
|
-
#
|
119
|
-
|
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"])
|
120
116
|
```
|
121
117
|
|
122
|
-
### Tag cloud calculations
|
123
118
|
|
124
|
-
|
119
|
+
### Class methods
|
120
|
+
|
121
|
+
#### `all_#{tag_name}`
|
125
122
|
|
126
123
|
```ruby
|
127
|
-
User.
|
128
|
-
# [
|
124
|
+
User.all_tags
|
125
|
+
# ["awesome", "slick"]
|
129
126
|
```
|
130
127
|
|
131
|
-
|
128
|
+
You can use block to add scopes to the query.
|
132
129
|
|
133
130
|
```ruby
|
134
|
-
User.
|
131
|
+
User.all_tags { where(name: ["ken", "tom"]) }
|
135
132
|
```
|
136
133
|
|
137
|
-
|
134
|
+
Or simply use your existing scopes:
|
138
135
|
|
139
136
|
```ruby
|
140
|
-
|
137
|
+
# scope :by_join_date, ->{order("created_at DESC")}
|
138
|
+
User.all_tags.by_join_date
|
141
139
|
```
|
142
140
|
|
143
|
-
|
144
|
-
|
145
|
-
Can get all tags easily.
|
141
|
+
SQL field is named "tag" and you can use it to modify the query.
|
146
142
|
|
147
143
|
```ruby
|
148
|
-
User.all_tags
|
149
|
-
# ['awesome', 'slick']
|
144
|
+
User.where("tag like ?", "aws%").all_tags { where(name: ["ken", "tom"]) }
|
150
145
|
```
|
151
146
|
|
152
|
-
|
147
|
+
#### `#{tag_name}_cloud`
|
153
148
|
|
149
|
+
Calculates the number of occurrences of each tag.
|
154
150
|
|
155
151
|
```ruby
|
156
|
-
User.
|
152
|
+
User.tags_cloud
|
153
|
+
# [["slick" => 2], ["awesome" => 1]]
|
157
154
|
```
|
158
155
|
|
159
|
-
|
156
|
+
You can use block to add scopes to the query.
|
160
157
|
|
161
158
|
```ruby
|
162
|
-
User.
|
159
|
+
User.tags_cloud { where(name: ["ken", "tom"]) }
|
163
160
|
```
|
164
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
|
+
|
165
169
|
## Benchmark
|
166
|
-
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
|
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.
|
167
171
|
|
168
|
-
This result does NOT insist
|
172
|
+
This result does NOT insist ActsAsTaggableArrayOn is better than acts-as-taggable-on since it provides much more features than this gem.
|
169
173
|
In the case you need simple tag functionality, acts-as-taggable-array-on may be helpful to improve its performance.
|
170
174
|
|
171
175
|
```bash
|
@@ -216,8 +220,10 @@ rake bench:write bench:find_by_id bench:find_by_tag 20.29s user 1.52s system 77
|
|
216
220
|
```
|
217
221
|
|
218
222
|
## Development
|
219
|
-
|
223
|
+
|
224
|
+
- To run testsuite you'll need to setup local PG database/user with `rake db:create`
|
220
225
|
After that just running `rspec` should work.
|
226
|
+
- Before submitting code for a review, please be sure to run `bundle exec standardrb --fix`
|
221
227
|
|
222
228
|
## Contributing
|
223
229
|
|
data/Rakefile
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
|
3
3
|
namespace :db do
|
4
|
-
|
4
|
+
desc "Create database for tests"
|
5
5
|
task :create do
|
6
|
-
puts
|
7
|
-
puts
|
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
|
-
|
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
|
3
|
+
require "acts-as-taggable-array-on/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
8
|
-
spec.version
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
11
|
-
spec.summary
|
12
|
-
spec.description
|
13
|
-
spec.homepage
|
14
|
-
spec.license
|
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
|
17
|
-
spec.executables
|
18
|
-
spec.test_files
|
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
|
22
|
-
spec.add_runtime_dependency
|
20
|
+
spec.add_runtime_dependency "activerecord", [">= 5.2"]
|
21
|
+
spec.add_runtime_dependency "activesupport", [">= 5.2"]
|
23
22
|
|
24
|
-
spec.add_development_dependency
|
23
|
+
spec.add_development_dependency "pg", "~> 1.1"
|
25
24
|
|
26
25
|
spec.add_development_dependency "bundler"
|
27
|
-
spec.add_development_dependency "rake"
|
28
|
-
spec.add_development_dependency "rspec-rails"
|
29
26
|
spec.add_development_dependency "guard-rspec"
|
30
27
|
spec.add_development_dependency "listen", "> 3.0"
|
28
|
+
spec.add_development_dependency "rake"
|
29
|
+
spec.add_development_dependency "rspec-rails"
|
30
|
+
spec.add_development_dependency "standard"
|
31
31
|
end
|
data/gemfiles/rails_5_2.gemfile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
source
|
1
|
+
source "https://rubygems.org"
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in acts-as-pgarray-taggable-on.gemspec
|
4
|
-
gemspec path:
|
4
|
+
gemspec path: "../"
|
5
5
|
|
6
|
-
gem
|
7
|
-
gem
|
6
|
+
gem "activerecord", "~> 5.2.0"
|
7
|
+
gem "activesupport", "~> 5.2.0"
|
data/gemfiles/rails_6_0.gemfile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
source
|
1
|
+
source "https://rubygems.org"
|
2
2
|
|
3
|
-
# Specify your gem's dependencies in acts-as-
|
4
|
-
gemspec path:
|
3
|
+
# Specify your gem's dependencies in acts-as-taggable-array-on.gemspec
|
4
|
+
gemspec path: "../"
|
5
5
|
|
6
|
-
gem
|
7
|
-
gem
|
6
|
+
gem "activerecord", "~> 6.0.3.4"
|
7
|
+
gem "activesupport", "~> 6.0.3.4"
|
@@ -6,7 +6,7 @@ module ActsAsTaggableArrayOn
|
|
6
6
|
base.extend(ClassMethod)
|
7
7
|
end
|
8
8
|
|
9
|
-
TYPE_MATCHER = {
|
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,19 +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(
|
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(
|
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
|
-
|
37
|
+
alias_method :taggable_array, :acts_as_taggable_array_on
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
@@ -1,22 +1,22 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe ActsAsTaggableArrayOn::Parser do
|
4
4
|
let(:parser) { ActsAsTaggableArrayOn.parser }
|
5
5
|
|
6
|
-
describe
|
6
|
+
describe "#parse" do
|
7
7
|
it "return unprocessed tags if array" do
|
8
|
-
tags = %w
|
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 =
|
14
|
-
expect(parser.parse(tags)).to eq %w
|
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 =
|
19
|
-
expect(parser.parse(tags)).to eq [
|
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
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe ActsAsTaggableArrayOn::Taggable do
|
4
4
|
before do
|
5
|
-
@user1 = User.create name:
|
6
|
-
@user2 = User.create name:
|
7
|
-
@user3 = User.create name:
|
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
|
13
|
+
User.acts_as_taggable_array_on :roles
|
11
14
|
User.taggable_array :codes
|
12
|
-
end
|
13
15
|
|
16
|
+
end
|
14
17
|
|
15
18
|
context "without database table" do
|
16
19
|
it "doesn't fail on class method call" do
|
@@ -49,109 +52,119 @@ describe ActsAsTaggableArrayOn::Taggable do
|
|
49
52
|
end
|
50
53
|
end
|
51
54
|
|
52
|
-
it
|
53
|
-
sql = User.with_any_sizes([
|
55
|
+
it "should define table name un-ambiguously" do
|
56
|
+
sql = User.with_any_sizes(["small"]).to_sql
|
54
57
|
expect(sql).to eql("SELECT \"users\".* FROM \"users\" WHERE (users.sizes && ARRAY['small']::text[])")
|
55
58
|
|
56
|
-
sql = User.with_all_sizes([
|
59
|
+
sql = User.with_all_sizes(["small"]).to_sql
|
57
60
|
expect(sql).to eql("SELECT \"users\".* FROM \"users\" WHERE (users.sizes @> ARRAY['small']::text[])")
|
58
61
|
|
59
|
-
sql = User.without_any_sizes([
|
62
|
+
sql = User.without_any_sizes(["small"]).to_sql
|
60
63
|
expect(sql).to eql("SELECT \"users\".* FROM \"users\" WHERE NOT (users.sizes && ARRAY['small']::text[])")
|
61
64
|
|
62
|
-
sql = User.without_all_sizes([
|
65
|
+
sql = User.without_all_sizes(["small"]).to_sql
|
63
66
|
expect(sql).to eql("SELECT \"users\".* FROM \"users\" WHERE NOT (users.sizes @> ARRAY['small']::text[])")
|
64
67
|
end
|
65
68
|
|
66
69
|
it "should work with ::text typed array" do
|
67
|
-
expect(User.with_any_sizes([
|
68
|
-
expect(User.with_all_sizes([
|
69
|
-
expect(User.without_any_sizes(
|
70
|
-
expect(User.without_all_sizes(
|
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])
|
71
81
|
end
|
72
82
|
|
73
83
|
it "should work with ::integer typed array" do
|
74
|
-
expect(User.with_any_codes([123])).to match_array([@user2
|
75
|
-
expect(User.with_all_codes([123, 789])).to match_array([@user2
|
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])
|
76
86
|
expect(User.without_any_codes(456)).to match_array([@user2])
|
77
87
|
expect(User.without_all_codes(456)).to match_array([@user2])
|
78
88
|
end
|
79
89
|
|
80
90
|
describe "#with_any_tags" do
|
81
91
|
it "returns users having any tags of args" do
|
82
|
-
expect(User.with_any_colors([
|
83
|
-
expect(User.with_any_colors(
|
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])
|
84
94
|
end
|
85
95
|
end
|
86
96
|
|
87
97
|
describe "#with_all_tags" do
|
88
98
|
it "returns users having all tags of args" do
|
89
|
-
expect(User.with_all_colors([
|
90
|
-
expect(User.with_all_colors(
|
99
|
+
expect(User.with_all_colors(["red", "blue"])).to match_array([@user1])
|
100
|
+
expect(User.with_all_colors("red, blue")).to match_array([@user1])
|
91
101
|
end
|
92
102
|
end
|
93
103
|
|
94
104
|
describe "#without_any_tags" do
|
95
105
|
it "returns users not having any tags of args" do
|
96
|
-
expect(User.without_any_colors([
|
97
|
-
expect(User.without_any_colors(
|
106
|
+
expect(User.without_any_colors(["red", "blue"])).to match_array([@admin1])
|
107
|
+
expect(User.without_any_colors("red, blue")).to match_array([@admin1])
|
98
108
|
end
|
99
109
|
end
|
100
110
|
|
101
111
|
describe "#without_all_tags" do
|
102
112
|
it "returns users not having all tags of args" do
|
103
|
-
expect(User.without_all_colors([
|
104
|
-
expect(User.without_all_colors(
|
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])
|
105
115
|
end
|
106
116
|
end
|
107
117
|
|
108
118
|
describe "#all_colors" do
|
109
119
|
it "returns all of tag_name" do
|
110
|
-
expect(User.all_colors).to match_array([@user1
|
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)
|
111
122
|
end
|
112
123
|
|
113
124
|
it "returns filtered tags for tag_name with block" do
|
114
|
-
expect(User.all_colors{where(name: ["Ken", "Joe"])}).to match_array([@user2
|
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)
|
115
127
|
end
|
116
128
|
|
117
129
|
it "returns filtered tags for tag_name with prepended scope" do
|
118
|
-
expect(User.where(
|
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" })
|
119
132
|
end
|
120
133
|
|
121
134
|
it "returns filtered tags for tag_name with prepended scope and bock" do
|
122
|
-
expect(User.where(
|
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" })
|
123
136
|
end
|
124
137
|
end
|
125
138
|
|
126
139
|
describe "#colors_cloud" do
|
127
140
|
it "returns tag cloud for tag_name" do
|
128
141
|
expect(User.colors_cloud).to match_array(
|
129
|
-
[@user1
|
142
|
+
[@user1, @user2, @user3, @admin1, @admin2].map(&:colors).flatten.group_by(&:to_s).map { |k, v| [k, v.count] }
|
130
143
|
)
|
131
144
|
end
|
132
145
|
|
133
146
|
it "returns filtered tag cloud for tag_name with block" do
|
134
|
-
expect(User.colors_cloud{where(name: ["Ken", "Joe"])}).to match_array(
|
135
|
-
[@user2
|
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] }
|
136
149
|
)
|
137
150
|
end
|
138
151
|
|
139
152
|
it "returns filtered tag cloud for tag_name with prepended scope" do
|
140
|
-
expect(User.where(
|
141
|
-
[@user1
|
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" }
|
142
155
|
)
|
143
156
|
end
|
144
157
|
|
145
158
|
it "returns filtered tag cloud for tag_name with prepended scope and block" do
|
146
|
-
expect(User.where(
|
147
|
-
[@user2
|
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" }
|
148
161
|
)
|
149
162
|
end
|
150
163
|
end
|
151
164
|
|
152
165
|
describe "with complex scope" do
|
153
166
|
it "works properly" do
|
154
|
-
expect(User.without_any_colors(
|
167
|
+
expect(User.without_any_colors("white").with_any_colors("blue").order(:created_at).limit(10)).to eq [@user1, @user3]
|
155
168
|
end
|
156
169
|
end
|
157
170
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,23 +1,24 @@
|
|
1
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__),
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
|
2
2
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
-
require
|
4
|
-
require
|
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
|
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:
|
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(:
|
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
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.
|
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:
|
11
|
+
date: 2023-04-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
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:
|
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:
|
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:
|
126
|
+
name: standard
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
114
128
|
requirements:
|
115
|
-
- - "
|
129
|
+
- - ">="
|
116
130
|
- !ruby/object:Gem::Version
|
117
|
-
version: '
|
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: '
|
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
|
@@ -142,6 +157,7 @@ files:
|
|
142
157
|
- config/database.yml.travis
|
143
158
|
- gemfiles/rails_5_2.gemfile
|
144
159
|
- gemfiles/rails_6_0.gemfile
|
160
|
+
- gemfiles/rails_6_1.gemfile
|
145
161
|
- lib/acts-as-taggable-array-on.rb
|
146
162
|
- lib/acts-as-taggable-array-on/parser.rb
|
147
163
|
- lib/acts-as-taggable-array-on/taggable.rb
|
@@ -154,7 +170,7 @@ homepage: https://github.com/tmiyamon/acts-as-taggable-array-on
|
|
154
170
|
licenses:
|
155
171
|
- MIT
|
156
172
|
metadata: {}
|
157
|
-
post_install_message:
|
173
|
+
post_install_message:
|
158
174
|
rdoc_options: []
|
159
175
|
require_paths:
|
160
176
|
- lib
|
@@ -169,8 +185,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
169
185
|
- !ruby/object:Gem::Version
|
170
186
|
version: '0'
|
171
187
|
requirements: []
|
172
|
-
rubygems_version: 3.
|
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:
|