acts-as-taggable-on 9.0.0 → 11.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/spec.yml +12 -14
  3. data/Appraisals +10 -7
  4. data/CHANGELOG.md +22 -3
  5. data/CONTRIBUTING.md +3 -3
  6. data/Gemfile +0 -1
  7. data/README.md +16 -4
  8. data/acts-as-taggable-on.gemspec +5 -5
  9. data/db/migrate/1_acts_as_taggable_on_migration.rb +0 -1
  10. data/gemfiles/activerecord_7.0.gemfile +2 -2
  11. data/gemfiles/{activerecord_6.0.gemfile → activerecord_7.1.gemfile} +2 -2
  12. data/gemfiles/{activerecord_6.1.gemfile → activerecord_7.2.gemfile} +2 -2
  13. data/lib/{acts_as_taggable_on → acts-as-taggable-on}/tag.rb +4 -3
  14. data/lib/acts-as-taggable-on/taggable/caching.rb +46 -0
  15. data/lib/{acts_as_taggable_on → acts-as-taggable-on}/taggable/collection.rb +5 -4
  16. data/lib/{acts_as_taggable_on → acts-as-taggable-on}/taggable/core.rb +4 -6
  17. data/lib/{acts_as_taggable_on → acts-as-taggable-on}/taggable/ownership.rb +5 -7
  18. data/lib/{acts_as_taggable_on → acts-as-taggable-on}/taggable/tagged_with_query/query_base.rb +11 -2
  19. data/lib/{acts_as_taggable_on → acts-as-taggable-on}/taggable.rb +8 -8
  20. data/lib/{acts_as_taggable_on → acts-as-taggable-on}/tagger.rb +5 -13
  21. data/lib/{acts_as_taggable_on → acts-as-taggable-on}/tagging.rb +1 -1
  22. data/lib/{acts_as_taggable_on → acts-as-taggable-on}/utils.rb +0 -4
  23. data/lib/{acts_as_taggable_on → acts-as-taggable-on}/version.rb +1 -1
  24. data/lib/acts-as-taggable-on.rb +14 -29
  25. data/lib/tasks/example/acts-as-taggable-on.rb.example +8 -0
  26. data/lib/tasks/install_initializer.rake +23 -0
  27. data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +5 -10
  28. data/spec/acts_as_taggable_on/acts_as_tagger_spec.rb +2 -2
  29. data/spec/acts_as_taggable_on/caching_spec.rb +0 -4
  30. data/spec/acts_as_taggable_on/tag_list_spec.rb +3 -3
  31. data/spec/acts_as_taggable_on/tag_spec.rb +45 -2
  32. data/spec/acts_as_taggable_on/taggable_spec.rb +51 -44
  33. data/spec/acts_as_taggable_on/tagger_spec.rb +8 -8
  34. data/spec/acts_as_taggable_on/tagging_spec.rb +28 -2
  35. data/spec/support/database.rb +3 -11
  36. data/spec/support/database_cleaner.rb +4 -0
  37. metadata +57 -36
  38. data/lib/acts_as_taggable_on/taggable/cache.rb +0 -92
  39. data/lib/acts_as_taggable_on.rb +0 -6
  40. /data/lib/{acts_as_taggable_on → acts-as-taggable-on}/default_parser.rb +0 -0
  41. /data/lib/{acts_as_taggable_on → acts-as-taggable-on}/engine.rb +0 -0
  42. /data/lib/{acts_as_taggable_on → acts-as-taggable-on}/generic_parser.rb +0 -0
  43. /data/lib/{acts_as_taggable_on → acts-as-taggable-on}/tag_list.rb +0 -0
  44. /data/lib/{acts_as_taggable_on → acts-as-taggable-on}/taggable/related.rb +0 -0
  45. /data/lib/{acts_as_taggable_on → acts-as-taggable-on}/taggable/tag_list_type.rb +0 -0
  46. /data/lib/{acts_as_taggable_on → acts-as-taggable-on}/taggable/tagged_with_query/all_tags_query.rb +0 -0
  47. /data/lib/{acts_as_taggable_on → acts-as-taggable-on}/taggable/tagged_with_query/any_tags_query.rb +0 -0
  48. /data/lib/{acts_as_taggable_on → acts-as-taggable-on}/taggable/tagged_with_query/exclude_tags_query.rb +0 -0
  49. /data/lib/{acts_as_taggable_on → acts-as-taggable-on}/taggable/tagged_with_query.rb +0 -0
  50. /data/lib/{acts_as_taggable_on → acts-as-taggable-on}/tags_helper.rb +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5f5bbdb5779f5a9c0feb7bda9b83f6bb581d8804e07beda16b7fea7dfda45a1b
4
- data.tar.gz: 6feeaec2428cbab344f795f92fb3b48e2ab06f0fd0fbceb211b845bd214fb157
3
+ metadata.gz: e13692b84fcccf9821c3f37ce992c07452df045dc2c20c58a47ab704ed8bdd36
4
+ data.tar.gz: 85bdcb03c9666c61efd92329f243e51bd4acf1941f32238dfecd50aaf8decf9f
5
5
  SHA512:
6
- metadata.gz: a81076cf61cf23c3a2f8ae17dc6be030bc120cc0464994ca190ded1407c2e8bc50dc78ca2a0742b85c4c6c5d996255af4267493eb3708d9abc4693da28881a61
7
- data.tar.gz: 36f2d2c63c87e0f6e4086b6ec692d846d2d8a04948b485073b351968411fbb62405730e06c535279434955ddcfbfa2dc30e8a40f62cc39cb3f46515eca9e2889
6
+ metadata.gz: 52f08142695e549389e407a214eafc2003ccba07a62e659acaf8c02f44d4a533ec6aef149e77900d344227b4453b8eac1ded100758e543cb7437f9391b3817f6
7
+ data.tar.gz: f82dfcbee2386842ab6f3319598f144fce5a59905fa2f5e92cfc07eb6d986e0283b666132226b824f13d52a51d92f10d010543691776f7a138a96ad8e50c39de
@@ -10,15 +10,15 @@ jobs:
10
10
  DB: ${{ matrix.db }}
11
11
  BUNDLE_GEMFILE: ${{ matrix.gemfile }}
12
12
  strategy:
13
+ fail-fast: false
13
14
  matrix:
14
15
  ruby:
15
- - "3.0"
16
- - 2.7
17
- - 2.6
18
- - 2.5
16
+ - 3.3
17
+ - 3.2
18
+ - 3.1
19
19
  gemfile:
20
- - gemfiles/activerecord_6.0.gemfile
21
- - gemfiles/activerecord_6.1.gemfile
20
+ - gemfiles/activerecord_7.2.gemfile
21
+ - gemfiles/activerecord_7.1.gemfile
22
22
  - gemfiles/activerecord_7.0.gemfile
23
23
  db:
24
24
  - mysql
@@ -27,15 +27,13 @@ jobs:
27
27
  include:
28
28
  - ruby: truffleruby-head
29
29
  db: postgresql
30
- gemfile: gemfiles/activerecord_6.1.gemfile
30
+ gemfile: gemfiles/activerecord_7.0.gemfile
31
31
  - ruby: truffleruby-head
32
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
33
+ gemfile: gemfiles/activerecord_7.1.gemfile
34
+ - ruby: truffleruby-head
35
+ db: postgresql
36
+ gemfile: gemfiles/activerecord_7.2.gemfile
39
37
 
40
38
  services:
41
39
  postgres:
@@ -61,7 +59,7 @@ jobs:
61
59
  --health-timeout 5s
62
60
  --health-retries 5
63
61
  steps:
64
- - uses: actions/checkout@v2
62
+ - uses: actions/checkout@v4
65
63
  - name: Set up Ruby
66
64
  uses: ruby/setup-ruby@v1
67
65
  with:
data/Appraisals CHANGED
@@ -1,19 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- appraise 'activerecord-6.0' do
4
- gem 'activerecord', '~> 6.0.0'
3
+ appraise 'activerecord-7.0' do
4
+ gem 'activerecord', '~> 7.0.1'
5
5
  gem 'pg'
6
+ gem 'sqlite3', '~> 1.4'
6
7
  gem 'mysql2', '~> 0.5'
7
8
  end
8
9
 
9
- appraise 'activerecord-6.1' do
10
- gem 'activerecord', '~> 6.1.0'
10
+ appraise 'activerecord-7.1' do
11
+ gem 'activerecord', '~> 7.1.0'
11
12
  gem 'pg'
13
+ gem 'sqlite3', '~> 1.4'
12
14
  gem 'mysql2', '~> 0.5'
13
15
  end
14
16
 
15
- appraise 'activerecord-7.0' do
16
- gem 'activerecord', '~> 7.0.0'
17
+ appraise 'activerecord-7.2' do
18
+ gem 'activerecord', '~> 7.2.0'
17
19
  gem 'pg'
20
+ gem 'sqlite3', '~> 1.4'
18
21
  gem 'mysql2', '~> 0.5'
19
- end
22
+ end
data/CHANGELOG.md CHANGED
@@ -10,6 +10,25 @@ 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
+ ### [v11.0.0) / 2024-08-23](https://github.com/mbleigh/acts-as-taggable-on/compare/v10.0.0...v11.0.0)
14
+ - Removed support for Ruby 2.7
15
+ - Removed support for Rails 6.1
16
+ - Added support for Ruby 3.2 and 3.3
17
+ - Added support for Rails 7.2
18
+ - Remove legacy code
19
+ - Renamed gem folder from acts_as_taggable_on to acts-as-taggable-on
20
+ - Removed legacy autoloading and replaced it with zeitwerk
21
+
22
+ ### [v10.0.0) / 2023-10-15](https://github.com/mbleigh/acts-as-taggable-on/compare/v9.0.1...v10.0.0)
23
+ * Features
24
+ * [@glampr Add support for prefix and suffix searches alongside previously supported containment (wildcard) searches](https://github.com/mbleigh/acts-as-taggable-on/pull/1082)
25
+ * [@donquxiote Add support for horizontally sharded databases](https://github.com/mbleigh/acts-as-taggable-on/pull/1079)
26
+ * [aovertus Remove restriction around ActiveRecord 7.x versions allowing support until next major is released](https://github.com/mbleigh/acts-as-taggable-on/pull/1110)
27
+
28
+ ### [v9.0.1) / 2022-01-07](https://github.com/mbleigh/acts-as-taggable-on/compare/v9.0.0..v9.0.1)
29
+ * Fixes
30
+ * Fix migration that generate default index
31
+
13
32
  ### [v9.0.0) / 2022-01-04](https://github.com/mbleigh/acts-as-taggable-on/compare/v8.1.0...v9.0.0)
14
33
  * Fixes
15
34
  * Support activerecord-7.0.0
@@ -35,7 +54,7 @@ As such, _Breaking Changes_ are major. _Features_ would map to either major or m
35
54
  * Features
36
55
  * [@kvokka Rails 6.1 support](https://github.com/mbleigh/acts-as-taggable-on/pull/1013)
37
56
  * Fixes
38
- * [@nbulaj Add support for Ruby 2.7 and it's kwargs](https://github.com/mbleigh/acts-as-taggable-on/pull/910)
57
+ * [@nbulaj Add support for Ruby 2.7 and it's kwargs](https://github.com/mbleigh/acts-as-taggable-on/pull/999)
39
58
  * [@Andythurlow @endorfin case sensitivity fix for tagged_with](https://github.com/mbleigh/acts-as-taggable-on/pull/965)
40
59
 
41
60
  ### [6.5.0 / 2019-11-07](https://github.com/mbleigh/acts-as-taggable-on/compare/v6.0.0...v6.5.0)
@@ -111,7 +130,7 @@ As such, _Breaking Changes_ are major. _Features_ would map to either major or m
111
130
 
112
131
  * Fixes
113
132
  * [@rikettsie #623 collation parameter is ignored if it generates an exception](https://github.com/mbleigh/acts-as-taggable-on/pull/650)
114
- * [@bwvoss References working parser in deprectation warning](https://github.com/mbleigh/acts-as-taggable-on/pull/659)
133
+ * [@bwvoss References working parser in deprecation warning](https://github.com/mbleigh/acts-as-taggable-on/pull/659)
115
134
  * [@jh125486 Updated tagging_contexts to include dynamic contexts](https://github.com/mbleigh/acts-as-taggable-on/pull/660)
116
135
  * [@jh125486 Fixed wildcard test (postgres returning rows with unexpected order)](https://github.com/mbleigh/acts-as-taggable-on/pull/660)
117
136
  * [@FlowerWrong Add rails 5.0.0 alpha support, not hack rails <5](https://github.com/mbleigh/acts-as-taggable-on/pull/673)
@@ -132,7 +151,7 @@ As such, _Breaking Changes_ are major. _Features_ would map to either major or m
132
151
  * [@seuros Remove more deprecations](https://github.com/mbleigh/acts-as-taggable-on/commit/05794170f64f8bf250b34d2d594e368721009278)
133
152
  * [@lukeasrodgers Bugfix `TagList#concat` with non-duplicates.](https://github.com/mbleigh/acts-as-taggable-on/commit/2c6214f0ddf8c6440ab81eec04d1fbf9d97c8826)
134
153
  * [@seuros clean! should return self.](https://github.com/mbleigh/acts-as-taggable-on/commit/c739422f56f8ff37e3f321235e74997422a1c980)
135
- * [@rbritom renable appraisals](https://github.com/mbleigh/acts-as-taggable-on/commit/0ca1f1c5b059699c683a28b522e86a3d5cd7639e)
154
+ * [@rbritom re-enable appraisals](https://github.com/mbleigh/acts-as-taggable-on/commit/0ca1f1c5b059699c683a28b522e86a3d5cd7639e)
136
155
  * [@rbritom remove index conditionally on up method.](https://github.com/mbleigh/acts-as-taggable-on/commit/9cc580e7f88164634eb10c8826e5b30ea0e00544)
137
156
  * [@rbritom add index on down method . ](https://github.com/mbleigh/acts-as-taggable-on/pull/767)
138
157
  * [@rbritom remove index conditionally on up method](https://github.com/mbleigh/acts-as-taggable-on/commit/9cc580e7f88164634eb10c8826e5b30ea0e00544)
data/CONTRIBUTING.md CHANGED
@@ -29,7 +29,7 @@
29
29
  * Use well-described, small (atomic) commits.
30
30
  * Include links to any relevant github issues.
31
31
  * *Don't* change the VERSION file.
32
- 6. Extra Credit: [Confirm it runs and tests pass on the rubies specified in the travis config](.travis.yml). I will otherwise confirm it runs on these.
32
+ 6. Extra Credit: [Confirm it runs and tests pass on the rubies specified in the Github Actions config](.github/workflows/spec.yml). I will otherwise confirm it runs on these.
33
33
 
34
34
  How I handle pull requests:
35
35
 
@@ -44,13 +44,13 @@ How I handle pull requests:
44
44
 
45
45
  * [A Note About Git Commit Messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
46
46
  * [http://stopwritingramblingcommitmessages.com/](http://stopwritingramblingcommitmessages.com/)
47
- * [ThoughtBot style guide](https://github.com/thoughtbot/guides/tree/master/style#git)
47
+ * [ThoughtBot style guide](https://github.com/thoughtbot/guides/tree/main/git)
48
48
 
49
49
  ### About Pull Requests (PR's)
50
50
 
51
51
  * [All Your Open Source Code Are Belong To Us](http://www.benjaminfleischer.com/2013/07/30/all-your-open-source-code-are-belong-to-us/)
52
52
  * [Using Pull Requests](https://help.github.com/articles/using-pull-requests)
53
- * [Github pull requests made easy](http://www.element84.com/github-pull-requests-made-easy.html)
53
+ * [Github pull requests made easy](https://www.element84.com/blog/github-pull-requests-made-easy)
54
54
 
55
55
  ## Documentation
56
56
 
data/Gemfile CHANGED
@@ -7,6 +7,5 @@ group :local_development do
7
7
  gem 'guard-rspec'
8
8
  gem 'appraisal'
9
9
  gem 'rake'
10
- gem 'sqlite3'
11
10
  gem 'byebug', platforms: [:mri]
12
11
  end
data/README.md CHANGED
@@ -22,7 +22,6 @@
22
22
  - [Upgrading](#upgrading)
23
23
  - [Contributors](#contributors)
24
24
  - [Compatibility](#compatibility)
25
- - [TODO](#todo)
26
25
  - [Testing](#testing)
27
26
  - [License](#license)
28
27
 
@@ -57,7 +56,7 @@ was used.
57
56
  To use it, add it to your Gemfile:
58
57
 
59
58
  ```ruby
60
- gem 'acts-as-taggable-on', '~> 9.0'
59
+ gem 'acts-as-taggable-on'
61
60
  ```
62
61
 
63
62
  and bundle:
@@ -255,7 +254,11 @@ User.tagged_with(["awesome", "cool"], :exclude => true)
255
254
  User.tagged_with(['awesome', 'cool'], :on => :tags, :any => true).tagged_with(['smart', 'shy'], :on => :skills, :any => true)
256
255
  ```
257
256
 
258
- You can also use `:wild => true` option along with `:any` or `:exclude` option. It will be looking for `%awesome%` and `%cool%` in SQL.
257
+ #### Wildcard tag search
258
+ You now have the following options for prefix, suffix and containment search, along with `:any` or `:exclude` option.
259
+ Use `wild: :suffix` to place a wildcard at the end of the tag. It will be looking for `awesome%` and `cool%` in SQL.
260
+ Use `wild: :prefix` to place a wildcard at the beginning of the tag. It will be looking for `%awesome` and `%cool` in SQL.
261
+ Use `wild: true` to place a wildcard both at the beginning and the end of the tag. It will be looking for `%awesome%` and `%cool%` in SQL.
259
262
 
260
263
  __Tip:__ `User.tagged_with([])` or `User.tagged_with('')` will return `[]`, an empty set of records.
261
264
 
@@ -296,6 +299,15 @@ to allow for dynamic tag contexts (this could be user generated tag contexts!)
296
299
  User.tagged_with("same", :on => :customs) # => [@user]
297
300
  ```
298
301
 
302
+ ### Finding tags based on context
303
+
304
+ You can find tags for a specific context by using the ```for_context``` scope:
305
+
306
+ ```ruby
307
+ ActsAsTaggableOn::Tag.for_context(:tags)
308
+ ActsAsTaggableOn::Tag.for_context(:skills)
309
+ ```
310
+
299
311
  ### Tag Parsers
300
312
 
301
313
  If you want to change how tags are parsed, you can define your own implementation:
@@ -364,7 +376,7 @@ Note that `tag_list` only returns tags whose taggings do not have an owner. Cont
364
376
  To retrieve all tags of an object (regardless of ownership) or if only one owner can tag the object, use `all_tags_list`.
365
377
 
366
378
  ##### Adding owned tags
367
- Note that **owned tags** are added all at once, in the form of ***comma seperated tags*** in string.
379
+ Note that **owned tags** are added all at once, in the form of ***comma separated tags*** in string.
368
380
  Also, when you try to add **owned tags** again, it simply overwrites the previous set of **owned tags**.
369
381
  So to append tags in previously existing **owned tags** list, go as follows:
370
382
  ```ruby
@@ -1,7 +1,6 @@
1
1
  # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'acts_as_taggable_on/version'
2
+
3
+ require_relative 'lib/acts-as-taggable-on/version'
5
4
 
6
5
  Gem::Specification.new do |gem|
7
6
  gem.name = 'acts-as-taggable-on'
@@ -16,13 +15,14 @@ Gem::Specification.new do |gem|
16
15
  gem.files = `git ls-files`.split($/)
17
16
  gem.test_files = gem.files.grep(%r{^spec/})
18
17
  gem.require_paths = ['lib']
19
- gem.required_ruby_version = '>= 2.5.0'
18
+ gem.required_ruby_version = '>= 3.0.0'
20
19
 
21
20
  if File.exist?('UPGRADING.md')
22
21
  gem.post_install_message = File.read('UPGRADING.md')
23
22
  end
24
23
 
25
- gem.add_runtime_dependency 'activerecord', '>= 6.0', '< 7.1'
24
+ gem.add_runtime_dependency 'activerecord', '>= 7.0', '< 8.0'
25
+ gem.add_runtime_dependency 'zeitwerk', '>= 2.4', '< 3.0'
26
26
 
27
27
  gem.add_development_dependency 'rspec-rails'
28
28
  gem.add_development_dependency 'rspec-its'
@@ -22,7 +22,6 @@ class ActsAsTaggableOnMigration < ActiveRecord::Migration[6.0]
22
22
  t.datetime :created_at
23
23
  end
24
24
 
25
- add_index ActsAsTaggableOn.taggings_table, :tag_id
26
25
  add_index ActsAsTaggableOn.taggings_table, %i[taggable_id taggable_type context],
27
26
  name: 'taggings_taggable_context_idx'
28
27
  end
@@ -2,8 +2,9 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activerecord", "~> 7.0.0"
5
+ gem "activerecord", "~> 7.0.1"
6
6
  gem "pg"
7
+ gem "sqlite3", "~> 1.4"
7
8
  gem "mysql2", "~> 0.5"
8
9
 
9
10
  group :local_development do
@@ -11,7 +12,6 @@ group :local_development do
11
12
  gem "guard-rspec"
12
13
  gem "appraisal"
13
14
  gem "rake"
14
- gem "sqlite3"
15
15
  gem "byebug", platforms: [:mri]
16
16
  end
17
17
 
@@ -2,8 +2,9 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activerecord", "~> 6.0.0"
5
+ gem "activerecord", "~> 7.1.0"
6
6
  gem "pg"
7
+ gem "sqlite3", "~> 1.4"
7
8
  gem "mysql2", "~> 0.5"
8
9
 
9
10
  group :local_development do
@@ -11,7 +12,6 @@ group :local_development do
11
12
  gem "guard-rspec"
12
13
  gem "appraisal"
13
14
  gem "rake"
14
- gem "sqlite3"
15
15
  gem "byebug", platforms: [:mri]
16
16
  end
17
17
 
@@ -2,8 +2,9 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activerecord", "~> 6.1.0"
5
+ gem "activerecord", "~> 7.2.0"
6
6
  gem "pg"
7
+ gem "sqlite3", "~> 1.4"
7
8
  gem "mysql2", "~> 0.5"
8
9
 
9
10
  group :local_development do
@@ -11,7 +12,6 @@ group :local_development do
11
12
  gem "guard-rspec"
12
13
  gem "appraisal"
13
14
  gem "rake"
14
- gem "sqlite3"
15
15
  gem "byebug", platforms: [:mri]
16
16
  end
17
17
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActsAsTaggableOn
4
- class Tag < ::ActiveRecord::Base
4
+ class Tag < ActsAsTaggableOn.base_class.constantize
5
5
  self.table_name = ActsAsTaggableOn.tags_table
6
6
 
7
7
  ### ASSOCIATIONS:
@@ -84,10 +84,11 @@ module ActsAsTaggableOn
84
84
  tries ||= 3
85
85
  comparable_tag_name = comparable_name(tag_name)
86
86
  existing_tag = existing_tags.find { |tag| comparable_name(tag.name) == comparable_tag_name }
87
- existing_tag || create(name: tag_name)
87
+ next existing_tag if existing_tag
88
+
89
+ transaction(requires_new: true) { create(name: tag_name) }
88
90
  rescue ActiveRecord::RecordNotUnique
89
91
  if (tries -= 1).positive?
90
- ActiveRecord::Base.connection.execute 'ROLLBACK'
91
92
  existing_tags = named_any(list)
92
93
  retry
93
94
  end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActsAsTaggableOn
4
+ module Taggable
5
+ module Caching
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ initialize_tags_cache
10
+ before_save :save_cached_tag_list
11
+ end
12
+
13
+ class_methods do
14
+ def initialize_tags_cache
15
+ tag_types.map(&:to_s).each do |tag_type|
16
+ define_singleton_method("caching_#{tag_type.singularize}_list?") do
17
+ caching_tag_list_on?(tag_type)
18
+ end
19
+ end
20
+ end
21
+
22
+ def acts_as_taggable_on(*args)
23
+ super(*args)
24
+ initialize_tags_cache
25
+ end
26
+
27
+ def caching_tag_list_on?(context)
28
+ column_names.include?("cached_#{context.to_s.singularize}_list")
29
+ end
30
+ end
31
+
32
+ def save_cached_tag_list
33
+ tag_types.map(&:to_s).each do |tag_type|
34
+ next unless self.class.respond_to?("caching_#{tag_type.singularize}_list?")
35
+ if self.class.send("caching_#{tag_type.singularize}_list?") && tag_list_cache_set_on(tag_type)
36
+ list = tag_list_cache_on(tag_type).to_a.flatten.compact.join("#{ActsAsTaggableOn.delimiter} ")
37
+ self["cached_#{tag_type.singularize}_list"] = list
38
+ end
39
+ end
40
+
41
+ true
42
+ end
43
+ end
44
+ end
45
+ end
46
+
@@ -3,12 +3,13 @@
3
3
  module ActsAsTaggableOn
4
4
  module Taggable
5
5
  module Collection
6
- def self.included(base)
7
- base.extend ActsAsTaggableOn::Taggable::Collection::ClassMethods
8
- base.initialize_acts_as_taggable_on_collection
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ initialize_acts_as_taggable_on_collection
9
10
  end
10
11
 
11
- module ClassMethods
12
+ class_methods do
12
13
  def initialize_acts_as_taggable_on_collection
13
14
  tag_types.map(&:to_s).each do |tag_type|
14
15
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
@@ -6,19 +6,17 @@ require_relative 'tag_list_type'
6
6
  module ActsAsTaggableOn
7
7
  module Taggable
8
8
  module Core
9
- def self.included(base)
10
- base.extend ActsAsTaggableOn::Taggable::Core::ClassMethods
9
+ extend ActiveSupport::Concern
11
10
 
12
- base.class_eval do
11
+ included do
13
12
  attr_writer :custom_contexts
14
13
 
15
14
  after_save :save_tags
16
- end
17
15
 
18
- base.initialize_acts_as_taggable_on_core
16
+ initialize_acts_as_taggable_on_core
19
17
  end
20
18
 
21
- module ClassMethods
19
+ class_methods do
22
20
  def initialize_acts_as_taggable_on_core
23
21
  include taggable_mixin
24
22
  tag_types.map(&:to_s).each do |tags_type|
@@ -3,17 +3,15 @@
3
3
  module ActsAsTaggableOn
4
4
  module Taggable
5
5
  module Ownership
6
- def self.included(base)
7
- base.extend ActsAsTaggableOn::Taggable::Ownership::ClassMethods
6
+ extend ActiveSupport::Concern
8
7
 
9
- base.class_eval do
10
- after_save :save_owned_tags
11
- end
8
+ included do
9
+ after_save :save_owned_tags
12
10
 
13
- base.initialize_acts_as_taggable_on_ownership
11
+ initialize_acts_as_taggable_on_ownership
14
12
  end
15
13
 
16
- module ClassMethods
14
+ class_methods do
17
15
  def acts_as_taggable_on(*args)
18
16
  initialize_acts_as_taggable_on_ownership
19
17
  super(*args)
@@ -33,7 +33,7 @@ module ActsAsTaggableOn
33
33
  matches_attribute = matches_attribute.lower unless ActsAsTaggableOn.strict_case_match
34
34
 
35
35
  if options[:wild].present?
36
- matches_attribute.matches("%#{escaped_tag(tag)}%", '!', ActsAsTaggableOn.strict_case_match)
36
+ matches_attribute.matches(wildcard_escaped_tag(tag), '!', ActsAsTaggableOn.strict_case_match)
37
37
  else
38
38
  matches_attribute.matches(escaped_tag(tag), '!', ActsAsTaggableOn.strict_case_match)
39
39
  end
@@ -45,7 +45,7 @@ module ActsAsTaggableOn
45
45
 
46
46
  if options[:wild].present?
47
47
  matches_attribute.matches_any(tag_list.map do |tag|
48
- "%#{escaped_tag(tag)}%"
48
+ wildcard_escaped_tag(tag)
49
49
  end, '!', ActsAsTaggableOn.strict_case_match)
50
50
  else
51
51
  matches_attribute.matches_any(tag_list.map do |tag|
@@ -59,6 +59,15 @@ module ActsAsTaggableOn
59
59
  ActsAsTaggableOn::Utils.escape_like(tag)
60
60
  end
61
61
 
62
+ def wildcard_escaped_tag(tag)
63
+ case options[:wild]
64
+ when :suffix then "#{escaped_tag(tag)}%"
65
+ when :prefix then "%#{escaped_tag(tag)}"
66
+ when true then "%#{escaped_tag(tag)}%"
67
+ else escaped_tag(tag)
68
+ end
69
+ end
70
+
62
71
  def adjust_taggings_alias(taggings_alias)
63
72
  taggings_alias = "taggings_alias_#{Digest::SHA1.hexdigest(taggings_alias)}" if taggings_alias.size > 75
64
73
  taggings_alias
@@ -66,7 +66,7 @@ module ActsAsTaggableOn
66
66
  # called on each call of taggable_on
67
67
  include Core
68
68
  include Collection
69
- include Cache
69
+ include Caching
70
70
  include Ownership
71
71
  include Related
72
72
  end
@@ -91,13 +91,13 @@ module ActsAsTaggableOn
91
91
  self.tag_types = (self.tag_types + tag_types).uniq
92
92
  self.preserve_tag_order = preserve_tag_order
93
93
  else
94
- class_attribute :tag_types
95
- self.tag_types = tag_types
96
- class_attribute :preserve_tag_order
97
- self.preserve_tag_order = preserve_tag_order
98
- class_attribute :tenant_column
99
-
100
94
  class_eval do
95
+ class_attribute :tag_types
96
+ class_attribute :preserve_tag_order
97
+ class_attribute :tenant_column
98
+ self.tag_types = tag_types
99
+ self.preserve_tag_order = preserve_tag_order
100
+
101
101
  has_many :taggings, as: :taggable, dependent: :destroy, class_name: '::ActsAsTaggableOn::Tagging'
102
102
  has_many :base_tags, through: :taggings, source: :tag, class_name: '::ActsAsTaggableOn::Tag'
103
103
 
@@ -111,7 +111,7 @@ module ActsAsTaggableOn
111
111
  # called on each call of taggable_on
112
112
  include Core
113
113
  include Collection
114
- include Cache
114
+ include Caching
115
115
  include Ownership
116
116
  include Related
117
117
  end
@@ -2,11 +2,9 @@
2
2
 
3
3
  module ActsAsTaggableOn
4
4
  module Tagger
5
- def self.included(base)
6
- base.extend ClassMethods
7
- end
5
+ extend ActiveSupport::Concern
8
6
 
9
- module ClassMethods
7
+ class_methods do
10
8
  ##
11
9
  # Make a model a tagger. This allows an instance of a model to claim ownership
12
10
  # of tags.
@@ -40,9 +38,7 @@ module ActsAsTaggableOn
40
38
  false
41
39
  end
42
40
 
43
- def is_tagger?
44
- tagger?
45
- end
41
+ alias is_tagger? tagger?
46
42
  end
47
43
 
48
44
  module InstanceMethods
@@ -75,9 +71,7 @@ module ActsAsTaggableOn
75
71
  self.class.is_tagger?
76
72
  end
77
73
 
78
- def is_tagger?
79
- tagger?
80
- end
74
+ alias is_tagger? tagger?
81
75
  end
82
76
 
83
77
  module SingletonMethods
@@ -85,9 +79,7 @@ module ActsAsTaggableOn
85
79
  true
86
80
  end
87
81
 
88
- def is_tagger?
89
- tagger?
90
- end
82
+ alias is_tagger? tagger?
91
83
  end
92
84
  end
93
85
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActsAsTaggableOn
4
- class Tagging < ::ActiveRecord::Base # :nodoc:
4
+ class Tagging < ActsAsTaggableOn.base_class.constantize # :nodoc:
5
5
  self.table_name = ActsAsTaggableOn.taggings_table
6
6
 
7
7
  DEFAULT_CONTEXT = 'tags'
@@ -26,10 +26,6 @@ module ActsAsTaggableOn
26
26
  using_postgresql? ? 'ILIKE' : 'LIKE'
27
27
  end
28
28
 
29
- def legacy_activerecord?
30
- ActiveRecord.version <= Gem::Version.new('5.3.0')
31
- end
32
-
33
29
  # escape _ and % characters in strings, since these are wildcards in SQL.
34
30
  def escape_like(str)
35
31
  str.gsub(/[!%_]/) { |x| "!#{x}" }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActsAsTaggableOn
4
- VERSION = '9.0.0'
4
+ VERSION = '11.0.0'
5
5
  end