acts-as-taggable-on 8.1.0 → 9.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/spec.yml +15 -34
- data/Appraisals +13 -13
- data/CHANGELOG.md +13 -3
- data/README.md +6 -6
- data/acts-as-taggable-on.gemspec +2 -2
- data/db/migrate/1_acts_as_taggable_on_migration.rb +5 -7
- data/db/migrate/2_add_missing_unique_indices.rb +6 -8
- data/db/migrate/3_add_taggings_counter_cache_to_tags.rb +3 -6
- data/db/migrate/4_add_missing_taggable_index.rb +5 -7
- data/db/migrate/5_change_collation_for_tag_names.rb +4 -6
- data/db/migrate/6_add_missing_indexes_on_taggings.rb +15 -13
- data/db/migrate/7_add_tenant_to_taggings.rb +7 -10
- data/docker-compose.yml +15 -0
- data/gemfiles/activerecord_6.0.gemfile +5 -8
- data/gemfiles/activerecord_6.1.gemfile +3 -8
- data/gemfiles/{activerecord_5.0.gemfile → activerecord_7.0.gemfile} +6 -9
- data/lib/acts_as_taggable_on/default_parser.rb +8 -10
- data/lib/acts_as_taggable_on/engine.rb +2 -0
- data/lib/acts_as_taggable_on/generic_parser.rb +2 -0
- data/lib/acts_as_taggable_on/tag.rb +30 -30
- data/lib/acts_as_taggable_on/tag_list.rb +8 -11
- data/lib/acts_as_taggable_on/taggable/cache.rb +64 -62
- data/lib/acts_as_taggable_on/taggable/collection.rb +178 -142
- data/lib/acts_as_taggable_on/taggable/core.rb +248 -244
- data/lib/acts_as_taggable_on/taggable/ownership.rb +110 -98
- data/lib/acts_as_taggable_on/taggable/related.rb +60 -47
- data/lib/acts_as_taggable_on/taggable/tag_list_type.rb +6 -2
- data/lib/acts_as_taggable_on/taggable/tagged_with_query/all_tags_query.rb +110 -106
- data/lib/acts_as_taggable_on/taggable/tagged_with_query/any_tags_query.rb +57 -53
- data/lib/acts_as_taggable_on/taggable/tagged_with_query/exclude_tags_query.rb +63 -60
- data/lib/acts_as_taggable_on/taggable/tagged_with_query/query_base.rb +54 -46
- data/lib/acts_as_taggable_on/taggable/tagged_with_query.rb +14 -8
- data/lib/acts_as_taggable_on/taggable.rb +14 -14
- data/lib/acts_as_taggable_on/tagger.rb +9 -5
- data/lib/acts_as_taggable_on/tagging.rb +6 -4
- data/lib/acts_as_taggable_on/tags_helper.rb +3 -1
- data/lib/acts_as_taggable_on/utils.rb +4 -2
- data/lib/acts_as_taggable_on/version.rb +3 -1
- data/spec/support/database.rb +36 -26
- metadata +13 -14
- data/gemfiles/activerecord_5.1.gemfile +0 -21
- data/gemfiles/activerecord_5.2.gemfile +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f5bbdb5779f5a9c0feb7bda9b83f6bb581d8804e07beda16b7fea7dfda45a1b
|
4
|
+
data.tar.gz: 6feeaec2428cbab344f795f92fb3b48e2ab06f0fd0fbceb211b845bd214fb157
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a81076cf61cf23c3a2f8ae17dc6be030bc120cc0464994ca190ded1407c2e8bc50dc78ca2a0742b85c4c6c5d996255af4267493eb3708d9abc4693da28881a61
|
7
|
+
data.tar.gz: 36f2d2c63c87e0f6e4086b6ec692d846d2d8a04948b485073b351968411fbb62405730e06c535279434955ddcfbfa2dc30e8a40f62cc39cb3f46515eca9e2889
|
data/.github/workflows/spec.yml
CHANGED
@@ -12,49 +12,30 @@ jobs:
|
|
12
12
|
strategy:
|
13
13
|
matrix:
|
14
14
|
ruby:
|
15
|
-
-
|
16
|
-
- 2.4
|
17
|
-
- 2.5
|
18
|
-
- 2.6
|
15
|
+
- "3.0"
|
19
16
|
- 2.7
|
20
|
-
-
|
21
|
-
-
|
17
|
+
- 2.6
|
18
|
+
- 2.5
|
22
19
|
gemfile:
|
23
|
-
- gemfiles/activerecord_5.0.gemfile
|
24
|
-
- gemfiles/activerecord_5.2.gemfile
|
25
|
-
- gemfiles/activerecord_5.1.gemfile
|
26
20
|
- gemfiles/activerecord_6.0.gemfile
|
27
21
|
- gemfiles/activerecord_6.1.gemfile
|
22
|
+
- gemfiles/activerecord_7.0.gemfile
|
28
23
|
db:
|
29
24
|
- mysql
|
30
25
|
- postgresql
|
31
26
|
- sqlite3
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
db: mysql
|
36
|
-
# Exclude ActiveRecord 6.x for Ruby < 2.5
|
37
|
-
- ruby: 2.3
|
38
|
-
gemfile: gemfiles/activerecord_6.0.gemfile
|
39
|
-
- ruby: 2.3
|
40
|
-
gemfile: gemfiles/activerecord_6.1.gemfile
|
41
|
-
- ruby: 2.4
|
42
|
-
gemfile: gemfiles/activerecord_6.0.gemfile
|
43
|
-
- ruby: 2.4
|
27
|
+
include:
|
28
|
+
- ruby: truffleruby-head
|
29
|
+
db: postgresql
|
44
30
|
gemfile: gemfiles/activerecord_6.1.gemfile
|
45
|
-
|
46
|
-
|
47
|
-
gemfile: gemfiles/
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
gemfile: gemfiles/activerecord_5.0.gemfile
|
54
|
-
- ruby: head
|
55
|
-
gemfile: gemfiles/activerecord_5.1.gemfile
|
56
|
-
- ruby: head
|
57
|
-
gemfile: gemfiles/activerecord_5.2.gemfile
|
31
|
+
- ruby: truffleruby-head
|
32
|
+
db: postgresql
|
33
|
+
gemfile: gemfiles/activerecord_7.0.gemfile
|
34
|
+
exclude:
|
35
|
+
- ruby: 2.5
|
36
|
+
gemfile: gemfiles/activerecord_7.0.gemfile
|
37
|
+
- ruby: 2.6
|
38
|
+
gemfile: gemfiles/activerecord_7.0.gemfile
|
58
39
|
|
59
40
|
services:
|
60
41
|
postgres:
|
data/Appraisals
CHANGED
@@ -1,19 +1,19 @@
|
|
1
|
-
|
2
|
-
gem 'activerecord', '~> 5.2.0'
|
3
|
-
end
|
4
|
-
|
5
|
-
appraise 'activerecord-5.1' do
|
6
|
-
gem 'activerecord', "~> 5.1.1"
|
7
|
-
end
|
8
|
-
|
9
|
-
appraise 'activerecord-5.0' do
|
10
|
-
gem 'activerecord', "~> 5.0.3"
|
11
|
-
end
|
1
|
+
# frozen_string_literal: true
|
12
2
|
|
13
3
|
appraise 'activerecord-6.0' do
|
14
|
-
gem 'activerecord',
|
4
|
+
gem 'activerecord', '~> 6.0.0'
|
5
|
+
gem 'pg'
|
6
|
+
gem 'mysql2', '~> 0.5'
|
15
7
|
end
|
16
8
|
|
17
9
|
appraise 'activerecord-6.1' do
|
18
|
-
gem 'activerecord',
|
10
|
+
gem 'activerecord', '~> 6.1.0'
|
11
|
+
gem 'pg'
|
12
|
+
gem 'mysql2', '~> 0.5'
|
13
|
+
end
|
14
|
+
|
15
|
+
appraise 'activerecord-7.0' do
|
16
|
+
gem 'activerecord', '~> 7.0.0'
|
17
|
+
gem 'pg'
|
18
|
+
gem 'mysql2', '~> 0.5'
|
19
19
|
end
|
data/CHANGELOG.md
CHANGED
@@ -10,6 +10,16 @@ Each change should fall into categories that would affect whether the release is
|
|
10
10
|
|
11
11
|
As such, _Breaking Changes_ are major. _Features_ would map to either major or minor. _Fixes_, _Performance_, and _Misc_ are either minor or patch, the difference being kind of fuzzy for the purposes of history. Adding _Documentation_ (including tests) would be patch level.
|
12
12
|
|
13
|
+
### [v9.0.0) / 2022-01-04](https://github.com/mbleigh/acts-as-taggable-on/compare/v8.1.0...v9.0.0)
|
14
|
+
* Fixes
|
15
|
+
* Support activerecord-7.0.0
|
16
|
+
* Support postgis adapter
|
17
|
+
* Fix migration syntax
|
18
|
+
* Features
|
19
|
+
* [@moliver-hemasystems Add support for a list of taggable IDs in tagging conditions](https://github.com/mbleigh/acts-as-taggable-on/pull/1053)
|
20
|
+
* Misc
|
21
|
+
* Add docker-compose.yml for local development
|
22
|
+
|
13
23
|
### [v8.1.0) / 2021-06-19](https://github.com/mbleigh/acts-as-taggable-on/compare/v8.0.0...v8.1.0)
|
14
24
|
* Fixes
|
15
25
|
* [@ngouy Fix rollbackable tenant migrations](https://github.com/mbleigh/acts-as-taggable-on/pull/1038)
|
@@ -20,13 +30,13 @@ As such, _Breaking Changes_ are major. _Features_ would map to either major or m
|
|
20
30
|
* [@lunaru Support tenants for taggings](https://github.com/mbleigh/acts-as-taggable-on/pull/1000)
|
21
31
|
* Fixes
|
22
32
|
* [@gr-eg Use none? instead of count.zero?](https://github.com/mbleigh/acts-as-taggable-on/pull/1030)
|
23
|
-
|
33
|
+
|
24
34
|
### [v7.0.0) / 2020-12-31](https://github.com/mbleigh/acts-as-taggable-on/compare/v6.5.0...v7.0.0)
|
25
35
|
* Features
|
26
36
|
* [@kvokka Rails 6.1 support](https://github.com/mbleigh/acts-as-taggable-on/pull/1013)
|
27
37
|
* Fixes
|
28
|
-
* [@nbulaj Add support for Ruby 2.7 and it's kwargs](https://github.com/mbleigh/acts-as-taggable-on/pull/910)
|
29
|
-
* [@Andythurlow @endorfin case sensitivity fix for tagged_with](https://github.com/mbleigh/acts-as-taggable-on/pull/965)
|
38
|
+
* [@nbulaj Add support for Ruby 2.7 and it's kwargs](https://github.com/mbleigh/acts-as-taggable-on/pull/910)
|
39
|
+
* [@Andythurlow @endorfin case sensitivity fix for tagged_with](https://github.com/mbleigh/acts-as-taggable-on/pull/965)
|
30
40
|
|
31
41
|
### [6.5.0 / 2019-11-07](https://github.com/mbleigh/acts-as-taggable-on/compare/v6.0.0...v6.5.0)
|
32
42
|
|
data/README.md
CHANGED
@@ -57,7 +57,7 @@ was used.
|
|
57
57
|
To use it, add it to your Gemfile:
|
58
58
|
|
59
59
|
```ruby
|
60
|
-
gem 'acts-as-taggable-on', '~>
|
60
|
+
gem 'acts-as-taggable-on', '~> 9.0'
|
61
61
|
```
|
62
62
|
|
63
63
|
and bundle:
|
@@ -555,12 +555,11 @@ Versions >= 4.x are compatible with Ruby 2.0.0+ and Rails 4 and 5.
|
|
555
555
|
|
556
556
|
Versions >= 7.x are compatible with Ruby 2.3.7+ and Rails 5 and 6.
|
557
557
|
|
558
|
-
|
558
|
+
Versions >= 8.x are compatible with Ruby 2.3.7+ and Rails 5 and 6.
|
559
559
|
|
560
|
-
|
560
|
+
Versions >= 9.x are compatible with Ruby 2.5.0 and Rails 6 and 7.
|
561
561
|
|
562
|
-
-
|
563
|
-
- Resolve concurrency issues
|
562
|
+
For an up-to-date roadmap, see https://github.com/mbleigh/acts-as-taggable-on/milestones
|
564
563
|
|
565
564
|
## Testing
|
566
565
|
|
@@ -572,7 +571,8 @@ bundle
|
|
572
571
|
rake spec
|
573
572
|
```
|
574
573
|
|
575
|
-
You can run all the tests across all the Rails versions by running `rake appraise`.
|
574
|
+
You can run all the tests across all the Rails versions by running `rake appraise`.
|
575
|
+
If you'd also like to [run the tests across all rubies and databases as configured for Github Actions, install and run `wwtd`](https://github.com/grosser/wwtd).
|
576
576
|
|
577
577
|
|
578
578
|
## License
|
data/acts-as-taggable-on.gemspec
CHANGED
@@ -16,13 +16,13 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.files = `git ls-files`.split($/)
|
17
17
|
gem.test_files = gem.files.grep(%r{^spec/})
|
18
18
|
gem.require_paths = ['lib']
|
19
|
-
gem.required_ruby_version = '>= 2.
|
19
|
+
gem.required_ruby_version = '>= 2.5.0'
|
20
20
|
|
21
21
|
if File.exist?('UPGRADING.md')
|
22
22
|
gem.post_install_message = File.read('UPGRADING.md')
|
23
23
|
end
|
24
24
|
|
25
|
-
gem.add_runtime_dependency 'activerecord', '>=
|
25
|
+
gem.add_runtime_dependency 'activerecord', '>= 6.0', '< 7.1'
|
26
26
|
|
27
27
|
gem.add_development_dependency 'rspec-rails'
|
28
28
|
gem.add_development_dependency 'rspec-its'
|
@@ -1,9 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
class ActsAsTaggableOnMigration < ActiveRecord::Migration; end
|
5
|
-
end
|
6
|
-
ActsAsTaggableOnMigration.class_eval do
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class ActsAsTaggableOnMigration < ActiveRecord::Migration[6.0]
|
7
4
|
def self.up
|
8
5
|
create_table ActsAsTaggableOn.tags_table do |t|
|
9
6
|
t.string :name
|
@@ -26,7 +23,8 @@ ActsAsTaggableOnMigration.class_eval do
|
|
26
23
|
end
|
27
24
|
|
28
25
|
add_index ActsAsTaggableOn.taggings_table, :tag_id
|
29
|
-
add_index ActsAsTaggableOn.taggings_table, [
|
26
|
+
add_index ActsAsTaggableOn.taggings_table, %i[taggable_id taggable_type context],
|
27
|
+
name: 'taggings_taggable_context_idx'
|
30
28
|
end
|
31
29
|
|
32
30
|
def self.down
|
@@ -1,16 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
class AddMissingUniqueIndices < ActiveRecord::Migration; end
|
5
|
-
end
|
6
|
-
AddMissingUniqueIndices.class_eval do
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddMissingUniqueIndices < ActiveRecord::Migration[6.0]
|
7
4
|
def self.up
|
8
5
|
add_index ActsAsTaggableOn.tags_table, :name, unique: true
|
9
6
|
|
10
7
|
remove_index ActsAsTaggableOn.taggings_table, :tag_id if index_exists?(ActsAsTaggableOn.taggings_table, :tag_id)
|
11
8
|
remove_index ActsAsTaggableOn.taggings_table, name: 'taggings_taggable_context_idx'
|
12
9
|
add_index ActsAsTaggableOn.taggings_table,
|
13
|
-
[
|
10
|
+
%i[tag_id taggable_id taggable_type context tagger_id tagger_type],
|
14
11
|
unique: true, name: 'taggings_idx'
|
15
12
|
end
|
16
13
|
|
@@ -20,6 +17,7 @@ AddMissingUniqueIndices.class_eval do
|
|
20
17
|
remove_index ActsAsTaggableOn.taggings_table, name: 'taggings_idx'
|
21
18
|
|
22
19
|
add_index ActsAsTaggableOn.taggings_table, :tag_id unless index_exists?(ActsAsTaggableOn.taggings_table, :tag_id)
|
23
|
-
add_index ActsAsTaggableOn.taggings_table, [
|
20
|
+
add_index ActsAsTaggableOn.taggings_table, %i[taggable_id taggable_type context],
|
21
|
+
name: 'taggings_taggable_context_idx'
|
24
22
|
end
|
25
23
|
end
|
@@ -1,9 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
class AddTaggingsCounterCacheToTags < ActiveRecord::Migration; end
|
5
|
-
end
|
6
|
-
AddTaggingsCounterCacheToTags.class_eval do
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddTaggingsCounterCacheToTags < ActiveRecord::Migration[6.0]
|
7
4
|
def self.up
|
8
5
|
add_column ActsAsTaggableOn.tags_table, :taggings_count, :integer, default: 0
|
9
6
|
|
@@ -1,11 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
class AddMissingTaggableIndex < ActiveRecord::Migration; end
|
5
|
-
end
|
6
|
-
AddMissingTaggableIndex.class_eval do
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddMissingTaggableIndex < ActiveRecord::Migration[6.0]
|
7
4
|
def self.up
|
8
|
-
add_index ActsAsTaggableOn.taggings_table, [
|
5
|
+
add_index ActsAsTaggableOn.taggings_table, %i[taggable_id taggable_type context],
|
6
|
+
name: 'taggings_taggable_context_idx'
|
9
7
|
end
|
10
8
|
|
11
9
|
def self.down
|
@@ -1,11 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This migration is added to circumvent issue #623 and have special characters
|
2
4
|
# work properly
|
3
|
-
|
4
|
-
|
5
|
-
else
|
6
|
-
class ChangeCollationForTagNames < ActiveRecord::Migration; end
|
7
|
-
end
|
8
|
-
ChangeCollationForTagNames.class_eval do
|
5
|
+
|
6
|
+
class ChangeCollationForTagNames < ActiveRecord::Migration[6.0]
|
9
7
|
def up
|
10
8
|
if ActsAsTaggableOn::Utils.using_mysql?
|
11
9
|
execute("ALTER TABLE #{ActsAsTaggableOn.tags_table} MODIFY name varchar(255) CHARACTER SET utf8 COLLATE utf8_bin;")
|
@@ -1,22 +1,24 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
class AddMissingIndexesOnTaggings < ActiveRecord::Migration; end
|
5
|
-
end
|
6
|
-
AddMissingIndexesOnTaggings.class_eval do
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddMissingIndexesOnTaggings < ActiveRecord::Migration[6.0]
|
7
4
|
def change
|
8
5
|
add_index ActsAsTaggableOn.taggings_table, :tag_id unless index_exists? ActsAsTaggableOn.taggings_table, :tag_id
|
9
|
-
add_index ActsAsTaggableOn.taggings_table, :taggable_id unless index_exists? ActsAsTaggableOn.taggings_table,
|
10
|
-
|
11
|
-
add_index ActsAsTaggableOn.taggings_table, :
|
6
|
+
add_index ActsAsTaggableOn.taggings_table, :taggable_id unless index_exists? ActsAsTaggableOn.taggings_table,
|
7
|
+
:taggable_id
|
8
|
+
add_index ActsAsTaggableOn.taggings_table, :taggable_type unless index_exists? ActsAsTaggableOn.taggings_table,
|
9
|
+
:taggable_type
|
10
|
+
add_index ActsAsTaggableOn.taggings_table, :tagger_id unless index_exists? ActsAsTaggableOn.taggings_table,
|
11
|
+
:tagger_id
|
12
12
|
add_index ActsAsTaggableOn.taggings_table, :context unless index_exists? ActsAsTaggableOn.taggings_table, :context
|
13
13
|
|
14
|
-
unless index_exists? ActsAsTaggableOn.taggings_table, [
|
15
|
-
add_index ActsAsTaggableOn.taggings_table, [
|
14
|
+
unless index_exists? ActsAsTaggableOn.taggings_table, %i[tagger_id tagger_type]
|
15
|
+
add_index ActsAsTaggableOn.taggings_table, %i[tagger_id tagger_type]
|
16
16
|
end
|
17
17
|
|
18
|
-
unless index_exists? ActsAsTaggableOn.taggings_table, [
|
19
|
-
|
18
|
+
unless index_exists? ActsAsTaggableOn.taggings_table, %i[taggable_id taggable_type tagger_id context],
|
19
|
+
name: 'taggings_idy'
|
20
|
+
add_index ActsAsTaggableOn.taggings_table, %i[taggable_id taggable_type tagger_id context],
|
21
|
+
name: 'taggings_idy'
|
20
22
|
end
|
21
23
|
end
|
22
24
|
end
|
@@ -1,16 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
class AddTenantToTaggings < ActiveRecord::Migration; end
|
5
|
-
end
|
6
|
-
AddTenantToTaggings.class_eval do
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddTenantToTaggings < ActiveRecord::Migration[6.0]
|
7
4
|
def self.up
|
8
|
-
add_column
|
9
|
-
add_index
|
5
|
+
add_column ActsAsTaggableOn.taggings_table, :tenant, :string, limit: 128
|
6
|
+
add_index ActsAsTaggableOn.taggings_table, :tenant unless index_exists? ActsAsTaggableOn.taggings_table, :tenant
|
10
7
|
end
|
11
8
|
|
12
9
|
def self.down
|
13
|
-
remove_index
|
14
|
-
remove_column
|
10
|
+
remove_index ActsAsTaggableOn.taggings_table, :tenant
|
11
|
+
remove_column ActsAsTaggableOn.taggings_table, :tenant
|
15
12
|
end
|
16
13
|
end
|
data/docker-compose.yml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
version: '3.9'
|
2
|
+
services:
|
3
|
+
postgres:
|
4
|
+
image: postgres:10
|
5
|
+
environment:
|
6
|
+
POSTGRES_USER: postgres
|
7
|
+
POSTGRES_DB: acts_as_taggable_on
|
8
|
+
POSTGRES_PASSWORD: postgres
|
9
|
+
ports: ['5432:5432']
|
10
|
+
mysql:
|
11
|
+
image: mysql:8
|
12
|
+
environment:
|
13
|
+
MYSQL_ALLOW_EMPTY_PASSWORD: true
|
14
|
+
MYSQL_DATABASE: acts_as_taggable_on
|
15
|
+
ports: ['3306:3306']
|
@@ -1,20 +1,17 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
1
3
|
source "https://rubygems.org"
|
2
4
|
|
3
5
|
gem "activerecord", "~> 6.0.0"
|
4
|
-
|
5
|
-
|
6
|
-
gem 'pg'
|
7
|
-
when "mysql"
|
8
|
-
gem 'mysql2', '~> 0.4'
|
9
|
-
else
|
10
|
-
gem 'sqlite3'
|
11
|
-
end
|
6
|
+
gem "pg"
|
7
|
+
gem "mysql2", "~> 0.5"
|
12
8
|
|
13
9
|
group :local_development do
|
14
10
|
gem "guard"
|
15
11
|
gem "guard-rspec"
|
16
12
|
gem "appraisal"
|
17
13
|
gem "rake"
|
14
|
+
gem "sqlite3"
|
18
15
|
gem "byebug", platforms: [:mri]
|
19
16
|
end
|
20
17
|
|
@@ -3,20 +3,15 @@
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
5
|
gem "activerecord", "~> 6.1.0"
|
6
|
-
|
7
|
-
|
8
|
-
gem 'pg'
|
9
|
-
when "mysql"
|
10
|
-
gem 'mysql2', '~> 0.5'
|
11
|
-
else
|
12
|
-
gem 'sqlite3'
|
13
|
-
end
|
6
|
+
gem "pg"
|
7
|
+
gem "mysql2", "~> 0.5"
|
14
8
|
|
15
9
|
group :local_development do
|
16
10
|
gem "guard"
|
17
11
|
gem "guard-rspec"
|
18
12
|
gem "appraisal"
|
19
13
|
gem "rake"
|
14
|
+
gem "sqlite3"
|
20
15
|
gem "byebug", platforms: [:mri]
|
21
16
|
end
|
22
17
|
|
@@ -1,20 +1,17 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
1
3
|
source "https://rubygems.org"
|
2
4
|
|
3
|
-
gem "activerecord", "~>
|
4
|
-
|
5
|
-
|
6
|
-
gem 'pg'
|
7
|
-
when "mysql"
|
8
|
-
gem 'mysql2', '~> 0.3'
|
9
|
-
else
|
10
|
-
gem "sqlite3", "~> 1.3", "< 1.4"
|
11
|
-
end
|
5
|
+
gem "activerecord", "~> 7.0.0"
|
6
|
+
gem "pg"
|
7
|
+
gem "mysql2", "~> 0.5"
|
12
8
|
|
13
9
|
group :local_development do
|
14
10
|
gem "guard"
|
15
11
|
gem "guard-rspec"
|
16
12
|
gem "appraisal"
|
17
13
|
gem "rake"
|
14
|
+
gem "sqlite3"
|
18
15
|
gem "byebug", platforms: [:mri]
|
19
16
|
end
|
20
17
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActsAsTaggableOn
|
2
4
|
##
|
3
5
|
# Returns a new TagList using the given tag string.
|
@@ -6,7 +8,6 @@ module ActsAsTaggableOn
|
|
6
8
|
# tag_list = ActsAsTaggableOn::DefaultParser.parse("One , Two, Three")
|
7
9
|
# tag_list # ["One", "Two", "Three"]
|
8
10
|
class DefaultParser < GenericParser
|
9
|
-
|
10
11
|
def parse
|
11
12
|
string = @tag_list
|
12
13
|
|
@@ -14,33 +15,32 @@ module ActsAsTaggableOn
|
|
14
15
|
TagList.new.tap do |tag_list|
|
15
16
|
string = string.to_s.dup
|
16
17
|
|
17
|
-
string.gsub!(double_quote_pattern)
|
18
|
+
string.gsub!(double_quote_pattern) do
|
18
19
|
# Append the matched tag to the tag list
|
19
20
|
tag_list << Regexp.last_match[2]
|
20
21
|
# Return the matched delimiter ($3) to replace the matched items
|
21
22
|
''
|
22
|
-
|
23
|
+
end
|
23
24
|
|
24
|
-
string.gsub!(single_quote_pattern)
|
25
|
+
string.gsub!(single_quote_pattern) do
|
25
26
|
# Append the matched tag ($2) to the tag list
|
26
27
|
tag_list << Regexp.last_match[2]
|
27
28
|
# Return an empty string to replace the matched items
|
28
29
|
''
|
29
|
-
|
30
|
+
end
|
30
31
|
|
31
32
|
# split the string by the delimiter
|
32
33
|
# and add to the tag_list
|
33
|
-
tag_list.add(string.split(Regexp.new
|
34
|
+
tag_list.add(string.split(Regexp.new(delimiter)))
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
37
|
-
|
38
38
|
# private
|
39
39
|
def delimiter
|
40
40
|
# Parse the quoted tags
|
41
41
|
d = ActsAsTaggableOn.delimiter
|
42
42
|
# Separate multiple delimiters by bitwise operator
|
43
|
-
d = d.join('|') if d.
|
43
|
+
d = d.join('|') if d.is_a?(Array)
|
44
44
|
d
|
45
45
|
end
|
46
46
|
|
@@ -73,7 +73,5 @@ module ActsAsTaggableOn
|
|
73
73
|
def single_quote_pattern
|
74
74
|
/(\A|#{delimiter})\s*'(.*?)'\s*(?=#{delimiter}\s*|\z)/
|
75
75
|
end
|
76
|
-
|
77
76
|
end
|
78
|
-
|
79
77
|
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module ActsAsTaggableOn
|
3
4
|
class Tag < ::ActiveRecord::Base
|
4
5
|
self.table_name = ActsAsTaggableOn.tags_table
|
@@ -31,41 +32,43 @@ module ActsAsTaggableOn
|
|
31
32
|
end
|
32
33
|
|
33
34
|
def self.named_any(list)
|
34
|
-
clause = list.map
|
35
|
+
clause = list.map do |tag|
|
35
36
|
sanitize_sql_for_named_any(tag).force_encoding('BINARY')
|
36
|
-
|
37
|
+
end.join(' OR ')
|
37
38
|
where(clause)
|
38
39
|
end
|
39
40
|
|
40
41
|
def self.named_like(name)
|
41
|
-
clause = ["name #{ActsAsTaggableOn::Utils.like_operator} ? ESCAPE '!'",
|
42
|
+
clause = ["name #{ActsAsTaggableOn::Utils.like_operator} ? ESCAPE '!'",
|
43
|
+
"%#{ActsAsTaggableOn::Utils.escape_like(name)}%"]
|
42
44
|
where(clause)
|
43
45
|
end
|
44
46
|
|
45
47
|
def self.named_like_any(list)
|
46
|
-
clause = list.map
|
47
|
-
sanitize_sql(["name #{ActsAsTaggableOn::Utils.like_operator} ? ESCAPE '!'",
|
48
|
-
|
48
|
+
clause = list.map do |tag|
|
49
|
+
sanitize_sql(["name #{ActsAsTaggableOn::Utils.like_operator} ? ESCAPE '!'",
|
50
|
+
"%#{ActsAsTaggableOn::Utils.escape_like(tag.to_s)}%"])
|
51
|
+
end.join(' OR ')
|
49
52
|
where(clause)
|
50
53
|
end
|
51
54
|
|
52
55
|
def self.for_context(context)
|
53
|
-
joins(:taggings)
|
54
|
-
where(["#{ActsAsTaggableOn.taggings_table}.context = ?", context])
|
55
|
-
select("DISTINCT #{ActsAsTaggableOn.tags_table}.*")
|
56
|
+
joins(:taggings)
|
57
|
+
.where(["#{ActsAsTaggableOn.taggings_table}.context = ?", context])
|
58
|
+
.select("DISTINCT #{ActsAsTaggableOn.tags_table}.*")
|
56
59
|
end
|
57
60
|
|
58
61
|
def self.for_tenant(tenant)
|
59
|
-
joins(:taggings)
|
60
|
-
where("#{ActsAsTaggableOn.taggings_table}.tenant = ?", tenant.to_s)
|
61
|
-
select("DISTINCT #{ActsAsTaggableOn.tags_table}.*")
|
62
|
+
joins(:taggings)
|
63
|
+
.where("#{ActsAsTaggableOn.taggings_table}.tenant = ?", tenant.to_s)
|
64
|
+
.select("DISTINCT #{ActsAsTaggableOn.tags_table}.*")
|
62
65
|
end
|
63
66
|
|
64
67
|
### CLASS METHODS:
|
65
68
|
|
66
69
|
def self.find_or_create_with_like_by_name(name)
|
67
70
|
if ActsAsTaggableOn.strict_case_match
|
68
|
-
|
71
|
+
find_or_create_all_with_like_by_name([name]).first
|
69
72
|
else
|
70
73
|
named_like(name).first || create(name: name)
|
71
74
|
end
|
@@ -78,27 +81,25 @@ module ActsAsTaggableOn
|
|
78
81
|
|
79
82
|
existing_tags = named_any(list)
|
80
83
|
list.map do |tag_name|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
retry
|
91
|
-
end
|
92
|
-
|
93
|
-
raise DuplicateTagError.new("'#{tag_name}' has already been taken")
|
84
|
+
tries ||= 3
|
85
|
+
comparable_tag_name = comparable_name(tag_name)
|
86
|
+
existing_tag = existing_tags.find { |tag| comparable_name(tag.name) == comparable_tag_name }
|
87
|
+
existing_tag || create(name: tag_name)
|
88
|
+
rescue ActiveRecord::RecordNotUnique
|
89
|
+
if (tries -= 1).positive?
|
90
|
+
ActiveRecord::Base.connection.execute 'ROLLBACK'
|
91
|
+
existing_tags = named_any(list)
|
92
|
+
retry
|
94
93
|
end
|
94
|
+
|
95
|
+
raise DuplicateTagError, "'#{tag_name}' has already been taken"
|
95
96
|
end
|
96
97
|
end
|
97
98
|
|
98
99
|
### INSTANCE METHODS:
|
99
100
|
|
100
|
-
def ==(
|
101
|
-
super || (
|
101
|
+
def ==(other)
|
102
|
+
super || (other.is_a?(Tag) && name == other.name)
|
102
103
|
end
|
103
104
|
|
104
105
|
def to_s
|
@@ -110,7 +111,6 @@ module ActsAsTaggableOn
|
|
110
111
|
end
|
111
112
|
|
112
113
|
class << self
|
113
|
-
|
114
114
|
private
|
115
115
|
|
116
116
|
def comparable_name(str)
|