acts-as-taggable-on 3.2.1 → 4.0.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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +25 -12
  4. data/Appraisals +9 -12
  5. data/CHANGELOG.md +120 -10
  6. data/Gemfile +2 -1
  7. data/README.md +163 -27
  8. data/Rakefile +2 -0
  9. data/UPGRADING.md +2 -7
  10. data/acts-as-taggable-on.gemspec +4 -6
  11. data/db/migrate/2_add_missing_unique_indices.rb +3 -2
  12. data/db/migrate/4_add_missing_taggable_index.rb +9 -0
  13. data/db/migrate/5_change_collation_for_tag_names.rb +9 -0
  14. data/db/migrate/6_add_missing_indexes.rb +12 -0
  15. data/gemfiles/activerecord_4.0.gemfile +3 -2
  16. data/gemfiles/activerecord_4.1.gemfile +3 -2
  17. data/gemfiles/{activerecord_3.2.gemfile → activerecord_4.2.gemfile} +2 -2
  18. data/gemfiles/{activerecord_edge.gemfile → activerecord_5.0.gemfile} +2 -3
  19. data/lib/acts-as-taggable-on.rb +79 -23
  20. data/lib/acts_as_taggable_on/default_parser.rb +79 -0
  21. data/lib/acts_as_taggable_on/engine.rb +0 -1
  22. data/lib/acts_as_taggable_on/generic_parser.rb +19 -0
  23. data/lib/acts_as_taggable_on/tag.rb +25 -15
  24. data/lib/acts_as_taggable_on/tag_list.rb +11 -81
  25. data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/cache.rb +6 -1
  26. data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/collection.rb +9 -4
  27. data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/core.rb +103 -61
  28. data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/ownership.rb +5 -5
  29. data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/related.rb +7 -7
  30. data/lib/acts_as_taggable_on/taggable.rb +9 -10
  31. data/lib/acts_as_taggable_on/tagger.rb +12 -11
  32. data/lib/acts_as_taggable_on/tagging.rb +14 -14
  33. data/lib/acts_as_taggable_on/tags_helper.rb +2 -2
  34. data/lib/acts_as_taggable_on/utils.rb +25 -50
  35. data/lib/acts_as_taggable_on/version.rb +1 -1
  36. data/lib/tasks/tags_collate_utf8.rake +21 -0
  37. data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +27 -2
  38. data/spec/acts_as_taggable_on/acts_as_tagger_spec.rb +2 -1
  39. data/spec/acts_as_taggable_on/caching_spec.rb +29 -0
  40. data/spec/acts_as_taggable_on/default_parser_spec.rb +47 -0
  41. data/spec/acts_as_taggable_on/generic_parser_spec.rb +14 -0
  42. data/spec/acts_as_taggable_on/related_spec.rb +10 -0
  43. data/spec/acts_as_taggable_on/single_table_inheritance_spec.rb +1 -0
  44. data/spec/acts_as_taggable_on/tag_list_spec.rb +48 -30
  45. data/spec/acts_as_taggable_on/tag_spec.rb +86 -39
  46. data/spec/acts_as_taggable_on/taggable/dirty_spec.rb +127 -0
  47. data/spec/acts_as_taggable_on/taggable_spec.rb +103 -168
  48. data/spec/acts_as_taggable_on/tagger_spec.rb +14 -1
  49. data/spec/acts_as_taggable_on/tagging_spec.rb +91 -1
  50. data/spec/acts_as_taggable_on/tags_helper_spec.rb +1 -0
  51. data/spec/acts_as_taggable_on/utils_spec.rb +13 -11
  52. data/spec/internal/app/models/cached_model_with_array.rb +1 -1
  53. data/spec/internal/app/models/models.rb +2 -2
  54. data/spec/internal/db/schema.rb +9 -5
  55. data/spec/spec_helper.rb +4 -1
  56. data/spec/support/0-helpers.rb +32 -0
  57. data/spec/support/database.rb +1 -7
  58. data/spec/support/database_cleaner.rb +4 -0
  59. metadata +34 -71
  60. data/lib/acts_as_taggable_on/acts_as_taggable_on/compatibility.rb +0 -35
  61. data/spec/bm.rb +0 -52
  62. data/spec/schema.rb +0 -82
  63. /data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/dirty.rb +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bbd5e8b1bc5588e5fa1f7c52d650d51284426c46
4
- data.tar.gz: 8310137e6ed880ac050af6a67e0afb648720c0a8
3
+ metadata.gz: 8ab1dc9bc4d03cd7fb2396284190f76719bc4a40
4
+ data.tar.gz: 8bbb5a13b5a1cc54aea59cb1ab6e524c31ea530c
5
5
  SHA512:
6
- metadata.gz: 1ba873f7c016fac3ddbbad4f8ff7b946bb7ffca89074b4db76f63d58c241e01726d18fcd502a7e60fe31b635f6f1fae5d5c26dce911211db07a9c8506e07d13b
7
- data.tar.gz: 098fd2268afe38cd7278a8908e6c11b1aeba8370754224730510d71a336130b89831051640fac2af432171c09f51e346b18c141e2d97553a68efc680a6afa680
6
+ metadata.gz: 901d4fb2dd642138c9d8b918d49eee90a86a0ea78596c37753197583b8c4068c08068077e8917bacc0b43ff0272613002aab6670a437ef9ac98a90910f11e522
7
+ data.tar.gz: 6c0f2e8dc6157b6ea854f63456c4eaa9fc0c754d46dd419ad0a184dd76eb69c3f7486591dfe156d3a224918fcd8d81a13a90661503e216ff21730d98a5d59e52
data/.gitignore CHANGED
@@ -9,3 +9,5 @@ tmp*.sw?
9
9
  tmp
10
10
  *.gem
11
11
  *.lock
12
+
13
+ /.idea
data/.travis.yml CHANGED
@@ -1,23 +1,36 @@
1
+ language: ruby
2
+ cache: bundler
3
+
1
4
  rvm:
2
- - 1.9.3
5
+ - 2.3.1
6
+ - 2.2.5
7
+ - 2.1
3
8
  - 2.0.0
4
- - 2.1.1
5
- - rbx-2
9
+
6
10
  env:
7
11
  - DB=sqlite3
8
12
  - DB=mysql
9
13
  - DB=postgresql
14
+
10
15
  gemfile:
11
- - gemfiles/activerecord_3.2.gemfile
12
- - gemfiles/activerecord_4.0.gemfile
16
+ - gemfiles/activerecord_5.0.gemfile
17
+ - gemfiles/activerecord_4.2.gemfile
13
18
  - gemfiles/activerecord_4.1.gemfile
14
- - gemfiles/activerecord_edge.gemfile
15
- cache: bundler
19
+ - gemfiles/activerecord_4.0.gemfile
20
+
21
+ sudo: false
22
+
23
+ bundler_args: '--without local_development --jobs 3 --retry 3'
24
+
25
+ before_install:
26
+ - gem install bundler
27
+
16
28
  script: bundle exec rake
17
- before_install: gem install bundler
18
- bundler_args: '--without local_development'
29
+
19
30
  matrix:
31
+ exclude:
32
+ - rvm: 2.0.0
33
+ gemfile: gemfiles/activerecord_5.0.gemfile
34
+ - rvm: 2.1
35
+ gemfile: gemfiles/activerecord_5.0.gemfile
20
36
  fast_finish: true
21
- allow_failures:
22
- - gemfile: gemfiles/activerecord_edge.gemfile
23
- - rvm: rbx-2
data/Appraisals CHANGED
@@ -1,20 +1,17 @@
1
- appraise "activerecord-3.2" do
2
- gem "activerecord", "~> 3.2"
3
- gem "actionpack", "~> 3.2"
1
+ appraise 'activerecord-5.0' do
2
+ gem 'activerecord', "~> 5.0.0"
4
3
  end
5
4
 
6
- appraise "activerecord-4.0" do
7
- gem "activerecord", "~> 4.0"
8
- gem "actionpack", "~> 4.0"
5
+ appraise "activerecord-4.2" do
6
+ gem "activerecord", "~> 4.2.0"
9
7
  end
10
8
 
11
9
  appraise "activerecord-4.1" do
12
- gem "activerecord", "~> 4.1"
13
- gem "actionpack", "~> 4.1"
10
+ gem "activerecord", "~> 4.1.0"
11
+ gem 'mysql2', '~> 0.3.21'
14
12
  end
15
13
 
16
- appraise "activerecord-edge" do
17
- gem "activerecord", github: "rails/rails"
18
- gem "actionpack", github: "rails/rails"
19
- gem 'arel', github: 'rails/arel'
14
+ appraise "activerecord-4.0" do
15
+ gem "activerecord", "~> 4.0.0"
16
+ gem 'mysql2', '~> 0.3.21'
20
17
  end
data/CHANGELOG.md CHANGED
@@ -4,21 +4,131 @@ Each change should fall into categories that would affect whether the release is
4
4
 
5
5
  As such, a _Feature_ would map to either major or minor. A _bug fix_ to a patch. And _misc_ is either minor or patch, the difference being kind of fuzzy for the purposes of history. Adding tests would be patch level.
6
6
 
7
- ### Master [changes](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.1.0...master)
7
+ ### [3.5.0 / 2015-03-03](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.4.4...v3.5.0)
8
+
9
+ * Fixes
10
+ * [@rikettsie Fixed collation for MySql via rake rule or config parameter](https://github.com/mbleigh/acts-as-taggable-on/pull/634)
11
+ *Misc
12
+ * [@pcupueran Add rspec test for tagging_spec completeness]()
13
+
14
+ ### [3.4.4 / 2015-02-11](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.4.3...v3.4.4)
15
+
16
+ * Fixes
17
+ * [@d4rky-pl Add context constraint to find_related_* methods](https://github.com/mbleigh/acts-as-taggable-on/pull/629)
18
+
19
+
20
+ ### [3.4.3 / 2014-09-26](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.4.2...v3.4.3)
21
+
22
+ * Fixes
23
+ * [@warp clears column cache on reset_column_information resolves](https://github.com/mbleigh/acts-as-taggable-on/pull/621)
24
+
25
+ ### [3.4.2 / 2014-09-26](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.4.1...v3.4.2)
26
+
27
+ * Fixes
28
+ * [@stiff fixed tagged_with :any in postgresql](https://github.com/mbleigh/acts-as-taggable-on/pull/570)
29
+ * [@jerefrer fixed encoding in mysql](https://github.com/mbleigh/acts-as-taggable-on/pull/588)
30
+ * [@markedmondson Ensure taggings context aliases are maintained when joining multiple taggables](https://github.com/mbleigh/acts-as-taggable-on/pull/589)
31
+
32
+ ### [3.4.1 / 2014-09-01](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.4.0...v3.4.1)
33
+ * Fixes
34
+ * [@konukhov fix owned ordered taggable bug](https://github.com/mbleigh/acts-as-taggable-on/pull/585)
35
+
36
+ ### [3.4.0 / 2014-08-29](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.3.0...v3.4.0)
37
+
38
+ * Features
39
+ * [@ProGM Support for custom parsers for tags](https://github.com/mbleigh/acts-as-taggable-on/pull/579)
40
+ * [@damzcodes #577 Popular feature](https://github.com/mbleigh/acts-as-taggable-on/pull/577)
41
+ * Fixes
42
+ * [@twalpole Update for rails edge (4.2)](https://github.com/mbleigh/acts-as-taggable-on/pull/583)
43
+ * Performance
44
+ * [@dontfidget #587 Use pluck instead of select](https://github.com/mbleigh/acts-as-taggable-on/pull/587)
45
+
46
+ ### [3.3.0 / 2014-07-08](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.2.6...v3.3.0)
8
47
 
9
- * Breaking Changes
10
48
  * Features
11
- * [@chess #413 Hook to support STI subclasses of Tag in save_tags](https://github.com/mbleigh/acts-as-taggable-on/pull/413)
49
+ * [@felipeclopes #488 Support for `start_at` and `end_at` restrictions when selecting tags](https://github.com/mbleigh/acts-as-taggable-on/pull/488)
50
+
12
51
  * Fixes
13
- * [@jdelStrother #515 Rename Compatibility methods to reduce chance of conflicts ](https://github.com/mbleigh/acts-as-taggable-on/pull/515)
14
- * [@seuros #512 fix for << method](https://github.com/mbleigh/acts-as-taggable-on/pull/512)
15
- * [@sonots #510 fix IN subquery error for mysql](https://github.com/mbleigh/acts-as-taggable-on/pull/510)
16
- * [@jonseaberg #499 fix for race condition when multiple processes try to add the same tag](https://github.com/mbleigh/acts-as-taggable-on/pull/499)
17
- * [@leklund #496 Fix for distinct and postgresql json columns errors](https://github.com/mbleigh/acts-as-taggable-on/pull/496)
18
- * [@thatbettina & @plexus #394 Multiple quoted tags](https://github.com/mbleigh/acts-as-taggable-on/pull/496)
52
+ * [@tonytonyjan #560 Fix for `ActsAsTaggableOn.remove_unused_tags` doesn't work](https://github.com/mbleigh/acts-as-taggable-on/pull/560)
53
+ * [@ThearkInn #555 Fix for `tag_cloud` helper to generate correct css tags](https://github.com/mbleigh/acts-as-taggable-on/pull/555)
54
+
19
55
  * Performance
56
+ * [@pcai #556 Add back taggables index in the taggins table](https://github.com/mbleigh/acts-as-taggable-on/pull/556)
57
+
58
+
59
+ ### [3.2.6 / 2014-05-28](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.2.5...v3.2.6)
60
+
61
+ * Fixes
62
+ * [@seuros #548 Fix dirty marking when tags are not ordered](https://github.com/mbleigh/acts-as-taggable-on/issues/548)
63
+
64
+ * Misc
65
+ * [@seuros Remove actionpack dependency](https://github.com/mbleigh/acts-as-taggable-on/commit/5d20e0486c892fbe21af42fdcd79d0b6ebe87ed4)
66
+ * [@seuros #547 Add tests for update_attributes](https://github.com/mbleigh/acts-as-taggable-on/issues/547)
67
+
68
+
69
+ ### [3.2.5 / 2014-05-25](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.2.4...v3.2.5)
70
+
71
+ * Fixes
72
+ * [@seuros #546 Fix autoload bug. Now require engine file instead of autoloading it](https://github.com/mbleigh/acts-as-taggable-on/issues/546)
73
+
74
+
75
+ ### [3.2.4 / 2014-05-24](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.2.3...v3.2.4)
76
+
77
+ * Fixes
78
+ * [@seuros #544 Fix incorrect query generation related to `GROUP BY` SQL statement](https://github.com/mbleigh/acts-as-taggable-on/issues/544)
79
+
80
+ * Misc
81
+ * [@seuros #545 Remove `ammeter` development dependency](https://github.com/mbleigh/acts-as-taggable-on/pull/545)
82
+ * [@seuros #545 Deprecate `TagList.from` in favor of `TagListParser.parse`](https://github.com/mbleigh/acts-as-taggable-on/pull/545)
83
+ * [@seuros #543 Introduce lazy loading](https://github.com/mbleigh/acts-as-taggable-on/pull/543)
84
+ * [@seuros #541 Deprecate ActsAsTaggableOn::Utils](https://github.com/mbleigh/acts-as-taggable-on/pull/541)
85
+
86
+
87
+ ### [3.2.3 / 2014-05-16](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.2.2...v3.2.3)
88
+
89
+ * Fixes
90
+ * [@seuros #540 Fix for tags removal (it was affecting all records with the same tag)](https://github.com/mbleigh/acts-as-taggable-on/pull/540)
91
+ * [@akcho8 #535 Fix for `options` Hash passed to methods from being deleted by those methods](https://github.com/mbleigh/acts-as-taggable-on/pull/535)
92
+
93
+
94
+ ### [3.2.2 / 2014-05-07](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.2.1...v3.2.2)
95
+
96
+ * Breaking Changes
97
+ * [@seuros #526 Taggable models are not extended with ActsAsTaggableOn::Utils anymore](https://github.com/mbleigh/acts-as-taggable-on/pull/526)
98
+
99
+ * Fixes
100
+ * [@seuros #536 Add explicit conversion of tags to strings (when assigning tags)](https://github.com/mbleigh/acts-as-taggable-on/pull/536)
101
+
102
+ * Misc
103
+ * [@seuros #526 Delete outdated benchmark script](https://github.com/mbleigh/acts-as-taggable-on/pull/526)
104
+ * [@seuros #525 Fix tests so that they pass with MySQL](https://github.com/mbleigh/acts-as-taggable-on/pull/525)
105
+
106
+
107
+ ### [3.2.1 / 2014-05-06](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.2.0...v3.2.1)
108
+
20
109
  * Misc
21
- * [@seuros #511 Rspec 3](https://github.com/mbleigh/acts-as-taggable-on/pull/511)
110
+ * [@seuros #523 Run tests loading only ActiveRecord (without the full Rails stack)](https://github.com/mbleigh/acts-as-taggable-on/pull/523)
111
+ * [@seuros #523 Remove activesupport dependency](https://github.com/mbleigh/acts-as-taggable-on/pull/523)
112
+ * [@seuros #523 Introduce database_cleaner in specs](https://github.com/mbleigh/acts-as-taggable-on/pull/523)
113
+ * [@seuros #520 Tag_list cleanup](https://github.com/mbleigh/acts-as-taggable-on/pull/520)
114
+
115
+
116
+ ### [3.2.0 / 2014-05-01](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.1.1...v3.2.0)
117
+
118
+ * Breaking Changes
119
+ * ActsAsTaggableOn::Tag is not extend with ActsAsTaggableOn::Utils anymore
120
+ * Features
121
+ * [@chess #413 Hook to support STI subclasses of Tag in save_tags](https://github.com/mbleigh/acts-as-taggable-on/pull/413)
122
+ * Fixes
123
+ * [@jdelStrother #515 Rename Compatibility methods to reduce chance of conflicts ](https://github.com/mbleigh/acts-as-taggable-on/pull/515)
124
+ * [@seuros #512 fix for << method](https://github.com/mbleigh/acts-as-taggable-on/pull/512)
125
+ * [@sonots #510 fix IN subquery error for mysql](https://github.com/mbleigh/acts-as-taggable-on/pull/510)
126
+ * [@jonseaberg #499 fix for race condition when multiple processes try to add the same tag](https://github.com/mbleigh/acts-as-taggable-on/pull/499)
127
+ * [@leklund #496 Fix for distinct and postgresql json columns errors](https://github.com/mbleigh/acts-as-taggable-on/pull/496)
128
+ * [@thatbettina & @plexus #394 Multiple quoted tags](https://github.com/mbleigh/acts-as-taggable-on/pull/496)
129
+ * Performance
130
+ * Misc
131
+ * [@seuros #511 Rspec 3](https://github.com/mbleigh/acts-as-taggable-on/pull/511)
22
132
 
23
133
  ### [3.1.0 / 2014-03-31](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.0.1...v3.1.0)
24
134
 
data/Gemfile CHANGED
@@ -7,4 +7,5 @@ group :local_development do
7
7
  gem 'guard-rspec'
8
8
  gem 'appraisal'
9
9
  gem 'rake'
10
- end
10
+ gem 'byebug' , platforms: [:mri_21, :mri_22, :mri_23]
11
+ end
data/README.md CHANGED
@@ -1,7 +1,10 @@
1
1
  # ActsAsTaggableOn
2
+
3
+ [![Join the chat at https://gitter.im/mbleigh/acts-as-taggable-on](https://badges.gitter.im/mbleigh/acts-as-taggable-on.svg)](https://gitter.im/mbleigh/acts-as-taggable-on?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4
+ [![Gem Version](https://badge.fury.io/rb/acts-as-taggable-on.svg)](http://badge.fury.io/rb/acts-as-taggable-on)
2
5
  [![Build Status](https://secure.travis-ci.org/mbleigh/acts-as-taggable-on.png)](http://travis-ci.org/mbleigh/acts-as-taggable-on)
3
6
  [![Code Climate](https://codeclimate.com/github/mbleigh/acts-as-taggable-on.png)](https://codeclimate.com/github/mbleigh/acts-as-taggable-on)
4
- [![Inline docs](http://inch-pages.github.io/github/mbleigh/acts-as-taggable-on.png)](http://inch-pages.github.io/github/mbleigh/acts-as-taggable-on)
7
+ [![Inline docs](http://inch-ci.org/github/mbleigh/acts-as-taggable-on.png)](http://inch-ci.org/github/mbleigh/acts-as-taggable-on)
5
8
 
6
9
  This plugin was originally based on Acts as Taggable on Steroids by Jonathan Viney.
7
10
  It has evolved substantially since that point, but all credit goes to him for the
@@ -16,22 +19,14 @@ Enter Acts as Taggable On. Rather than tying functionality to a specific keyword
16
19
  tag "contexts" that can be used locally or in combination in the same way steroids
17
20
  was used.
18
21
 
19
- ## Compatibility
20
-
21
- Versions 2.x are compatible with Ruby 1.8.7+ and Rails 3.
22
22
 
23
- Versions 2.4.1 and up are compatible with Rails 4 too (thanks to arabonradar and cwoodcox).
24
-
25
- Versions >= 3.x are compatible with Ruby 1.9.3+ and Rails 3 and 4.
26
-
27
- For an up-to-date roadmap, see https://github.com/mbleigh/acts-as-taggable-on/issues/milestones
28
23
 
29
24
  ## Installation
30
25
 
31
26
  To use it, add it to your Gemfile:
32
27
 
33
28
  ```ruby
34
- gem 'acts-as-taggable-on'
29
+ gem 'acts-as-taggable-on', '~> 4.0'
35
30
  ```
36
31
 
37
32
  and bundle:
@@ -47,8 +42,6 @@ Install migrations
47
42
  ```shell
48
43
  # For the latest versions :
49
44
  rake acts_as_taggable_on_engine:install:migrations
50
- # For versions 2.4.1 and earlier :
51
- rails generate acts_as_taggable_on:migration
52
45
  ```
53
46
 
54
47
  Review the generated migrations then migrate :
@@ -56,9 +49,22 @@ Review the generated migrations then migrate :
56
49
  rake db:migrate
57
50
  ```
58
51
 
59
- #### Upgrading
52
+ #### For MySql users
53
+ You can circumvent at any time the problem of special characters [issue 623](https://github.com/mbleigh/acts-as-taggable-on/issues/623) by setting in an initializer file:
54
+
55
+ ```ruby
56
+ ActsAsTaggableOn.force_binary_collation = true
57
+ ```
58
+
59
+ Or by running this rake task:
60
+
61
+ ```shell
62
+ rake acts_as_taggable_on_engine:tag_names:collate_bin
63
+ ```
64
+
65
+ See the Configuration section for more details, and a general note valid for older
66
+ version of the gem.
60
67
 
61
- see [UPGRADING](UPGRADING.md)
62
68
 
63
69
  ## Usage
64
70
 
@@ -70,6 +76,12 @@ class User < ActiveRecord::Base
70
76
  acts_as_taggable_on :skills, :interests
71
77
  end
72
78
 
79
+ class UsersController < ApplicationController
80
+ def user_params
81
+ params.require(:user).permit(:name, :tag_list) ## Rails 4 strong params usage
82
+ end
83
+ end
84
+
73
85
  @user = User.new(:name => "Bobby")
74
86
  ```
75
87
 
@@ -135,11 +147,13 @@ these methods are added to the model: `skill_list`(and `skill_list.add`, `skill_
135
147
  # => ["joking", "clowning", "boxing", "coding"]
136
148
 
137
149
  @another_user = User.new(:name => "Alice")
138
- @another_story.skill_list.add("joking")
139
- @another_story.save
150
+ @another_user.skill_list.add("clowning")
151
+ @another_user.save
140
152
 
141
153
  User.skill_counts
142
- => [#<ActsAsTaggableOn::Tag id: 1, name: "joking", taggings_count: 2>, #<ActsAsTaggableOn::Tag id: 2, name: "clowning", taggings_count: 1>, ...]
154
+ => [#<ActsAsTaggableOn::Tag id: 1, name: "joking", taggings_count: 1>,
155
+ #<ActsAsTaggableOn::Tag id: 2, name: "clowning", taggings_count: 2>,
156
+ #<ActsAsTaggableOn::Tag id: 3, name: "boxing", taggings_count: 1>]
143
157
  ```
144
158
 
145
159
  To preserve the order in which tags are created use `acts_as_ordered_taggable`:
@@ -162,6 +176,22 @@ end
162
176
  @user.tag_list # => ["north", "east", "south", "west"]
163
177
  ```
164
178
 
179
+ ### Finding most or least used tags
180
+
181
+ You can find the most or least used tags by using:
182
+
183
+ ```ruby
184
+ ActsAsTaggableOn::Tag.most_used
185
+ ActsAsTaggableOn::Tag.least_used
186
+ ```
187
+
188
+ You can also filter the results by passing the method a limit, however the default limit is 20.
189
+
190
+ ```ruby
191
+ ActsAsTaggableOn::Tag.most_used(10)
192
+ ActsAsTaggableOn::Tag.least_used(10)
193
+ ```
194
+
165
195
  ### Finding Tagged Objects
166
196
 
167
197
  Acts As Taggable On uses scopes to create an association for tags.
@@ -176,22 +206,23 @@ end
176
206
  User.tagged_with("awesome").by_join_date
177
207
  User.tagged_with("awesome").by_join_date.paginate(:page => params[:page], :per_page => 20)
178
208
 
179
- # Find a user with matching all tags, not just one:
209
+ # Find users that matches all given tags:
180
210
  User.tagged_with(["awesome", "cool"], :match_all => true)
181
211
 
182
- # Find a user with any of the tags:
212
+ # Find users with any of the specified tags:
183
213
  User.tagged_with(["awesome", "cool"], :any => true)
184
214
 
185
- # Find a user that not tags with awesome or cool:
215
+ # Find users that has not been tagged with awesome or cool:
186
216
  User.tagged_with(["awesome", "cool"], :exclude => true)
187
217
 
188
- # Find a user with any of tags based on context:
218
+ # Find users with any of the tags based on context:
189
219
  User.tagged_with(['awesome', 'cool'], :on => :tags, :any => true).tagged_with(['smart', 'shy'], :on => :skills, :any => true)
190
220
  ```
191
221
 
192
- You can also use `:wild => true` option along with `:any` or `:exclude` option. It will looking for `%awesome%` and `%cool%` in sql.
222
+ You can also use `:wild => true` option along with `:any` or `:exclude` option. It will be looking for `%awesome%` and `%cool%` in SQL.
223
+
224
+ __Tip:__ `User.tagged_with([])` or `User.tagged_with('')` will return `[]`, an empty set of records.
193
225
 
194
- __Tip:__ `User.tagged_with([])` or `User.tagged_with('')` will return `[]`, but not all records.
195
226
 
196
227
  ### Relationships
197
228
 
@@ -229,6 +260,43 @@ to allow for dynamic tag contexts (this could be user generated tag contexts!)
229
260
  User.tagged_with("same", :on => :customs) # => [@user]
230
261
  ```
231
262
 
263
+ ### Tag Parsers
264
+
265
+ If you want to change how tags are parsed, you can define your own implementation:
266
+
267
+ ```ruby
268
+ class MyParser < ActsAsTaggableOn::GenericParser
269
+ def parse
270
+ ActsAsTaggableOn::TagList.new.tap do |tag_list|
271
+ tag_list.add @tag_list.split('|')
272
+ end
273
+ end
274
+ end
275
+ ```
276
+
277
+ Now you can use this parser, passing it as parameter:
278
+
279
+ ```ruby
280
+ @user = User.new(:name => "Bobby")
281
+ @user.tag_list = "east, south"
282
+ @user.tag_list.add("north|west", parser: MyParser)
283
+ @user.tag_list # => ["north", "east", "south", "west"]
284
+
285
+ # Or also:
286
+ @user.tag_list.parser = MyParser
287
+ @user.tag_list.add("north|west")
288
+ @user.tag_list # => ["north", "east", "south", "west"]
289
+ ```
290
+
291
+ Or change it globally:
292
+
293
+ ```ruby
294
+ ActsAsTaggableOn.default_parser = MyParser
295
+ @user = User.new(:name => "Bobby")
296
+ @user.tag_list = "east|south"
297
+ @user.tag_list # => ["east", "south"]
298
+ ```
299
+
232
300
  ### Tag Ownership
233
301
 
234
302
  Tags can have owners:
@@ -252,6 +320,42 @@ Photo.tagged_with("paris", :on => :locations, :owned_by => @some_user)
252
320
  @some_user.tag(@some_photo, :with => "paris, normandy", :on => :locations, :skip_save => true) #won't save @some_photo object
253
321
  ```
254
322
 
323
+ #### Working with Owned Tags
324
+ Note that `tag_list` only returns tags whose taggings do not have an owner. Continuing from the above example:
325
+ ```ruby
326
+ @some_photo.tag_list # => []
327
+ ```
328
+ To retrieve all tags of an object (regardless of ownership) or if only one owner can tag the object, use `all_tags_list`.
329
+
330
+ ##### Adding owned tags
331
+ Note that **owned tags** are added all at once, in the form of ***comma seperated tags*** in string.
332
+ Also, when you try to add **owned tags** again, it simply overwrites the previous set of **owned tags**.
333
+ So to append tags in previously existing **owned tags** list, go as follows:
334
+ ```ruby
335
+ def add_owned_tag
336
+ @some_item = Item.find(params[:id])
337
+ owned_tag_list = @some_item.all_tag_list - @some_item.tag_list
338
+ owned_tag_list += [(params[:tag])]
339
+ @tag_owner.tag(@some_item, :with => stringify(owned_tag_list), :on => :tags)
340
+ @some_item.save
341
+ end
342
+
343
+ def stringify(tag_list)
344
+ tag_list.inject('') { |memo, tag| memo += (tag + ',') }[0..-1]
345
+ end
346
+ ```
347
+ ##### Removing owned tags
348
+ Similarly as above, removing will be as follows:
349
+ ```ruby
350
+ def remove_owned_tag
351
+ @some_item = Item.find(params[:id])
352
+ owned_tag_list = @some_item.all_tag_list - @some_item.tag_list
353
+ owned_tag_list -= [(params[:tag])]
354
+ @tag_owner.tag(@some_item, :with => stringify(owned_tag_list), :on => :tags)
355
+ @some_item.save
356
+ end
357
+ ```
358
+
255
359
  ### Dirty objects
256
360
 
257
361
  ```ruby
@@ -273,7 +377,7 @@ Photo.tagged_with("paris", :on => :locations, :owned_by => @some_user)
273
377
  To construct tag clouds, the frequency of each tag needs to be calculated.
274
378
  Because we specified `acts_as_taggable_on` on the `User` class, we can
275
379
  get a calculation of all the tag counts by using `User.tag_counts_on(:customs)`. But what if we wanted a tag count for
276
- an single user's posts? To achieve this we call tag_counts on the association:
380
+ a single user's posts? To achieve this we call tag_counts on the association:
277
381
 
278
382
  ```ruby
279
383
  User.find(:first).posts.tag_counts_on(:tags)
@@ -344,21 +448,53 @@ If you would like tags to be case-sensitive and not use LIKE queries for creatio
344
448
  ActsAsTaggableOn.strict_case_match = true
345
449
  ```
346
450
 
451
+ If you would like to have an exact match covering special characters with MySql:
452
+
453
+ ```ruby
454
+ ActsAsTaggableOn.force_binary_collation = true
455
+ ```
456
+
347
457
  If you want to change the default delimiter (it defaults to ','). You can also pass in an array of delimiters such as ([',', '|']):
348
458
 
349
459
  ```ruby
350
460
  ActsAsTaggableOn.delimiter = ','
351
461
  ```
352
462
 
353
- *NOTE: SQLite by default can't upcase or downcase multibyte characters, resulting in unwanted behavior. Load the SQLite ICU extension for proper handle of such characters. [See docs](http://www.sqlite.org/src/artifact?ci=trunk&filename=ext/icu/README.txt)*
463
+ *NOTE 1: SQLite by default can't upcase or downcase multibyte characters, resulting in unwanted behavior. Load the SQLite ICU extension for proper handle of such characters. [See docs](http://www.sqlite.org/src/artifact?ci=trunk&filename=ext/icu/README.txt)*
464
+
465
+ *NOTE 2: the option `force_binary_collation` is strongest than `strict_case_match` and when
466
+ set to true, the `strict_case_match` is ignored.
467
+ To roughly apply the `force_binary_collation` behaviour with a version of the gem <= 3.4.4, execute the following commands in the MySql console:*
468
+
469
+ ```shell
470
+ USE my_wonderful_app_db;
471
+ ALTER TABLE tags MODIFY name VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin;
472
+ ```
473
+
474
+ #### Upgrading
475
+
476
+ see [UPGRADING](UPGRADING.md)
354
477
 
355
478
  ## Contributors
356
479
 
357
480
  We have a long list of valued contributors. [Check them all](https://github.com/mbleigh/acts-as-taggable-on/contributors)
358
481
 
359
- ## Maintainer
482
+ ## Compatibility
483
+
484
+ Versions 2.x are compatible with Ruby 1.8.7+ and Rails 3.
485
+
486
+ Versions 2.4.1 and up are compatible with Rails 4 too (thanks to arabonradar and cwoodcox).
487
+
488
+ Versions >= 3.x are compatible with Ruby 1.9.3+ and Rails 3 and 4.
489
+
490
+ Versions >= 4.x are compatible with Ruby 2.0.0+ and Rails 4 and 5.
491
+
492
+ For an up-to-date roadmap, see https://github.com/mbleigh/acts-as-taggable-on/milestones
493
+
494
+ ## TODO
360
495
 
361
- * [Joost Baaij](https://github.com/tilsammans)
496
+ - Write benchmark script
497
+ - Resolve concurrency issues
362
498
 
363
499
  ## Testing
364
500
 
data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
1
  require 'rubygems'
2
2
  require 'bundler/setup'
3
3
 
4
+ import "./lib/tasks/tags_collate_utf8.rake"
5
+
4
6
  desc 'Default: run specs'
5
7
  task default: :spec
6
8
 
data/UPGRADING.md CHANGED
@@ -4,10 +4,5 @@ Re-run the migrations generator
4
4
 
5
5
  rake acts_as_taggable_on_engine:install:migrations
6
6
 
7
- It will create any new migrations and skip existing ones
8
-
9
-
10
- ##Breaking changes:
11
-
12
- - ActsAsTaggableOn::Tag is not extend with ActsAsTaggableOn::Utils anymore.
13
- Please use ActsAsTaggableOn::Utils instead
7
+ This will create any new migrations and skip existing ones
8
+ Version 3.5.0 has a migration for mysql adapter
@@ -16,23 +16,21 @@ 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 = '>= 1.9.3'
19
+ gem.required_ruby_version = '>= 2.0.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', ['>= 3', '< 5']
26
- gem.add_runtime_dependency 'actionpack', ['>= 3', '< 5']
25
+ gem.add_runtime_dependency 'activerecord', ['>= 4.0']
27
26
 
28
27
  gem.add_development_dependency 'sqlite3'
29
- gem.add_development_dependency 'mysql2', '~> 0.3.7'
28
+ gem.add_development_dependency 'mysql2', '~> 0.3'
30
29
  gem.add_development_dependency 'pg'
31
30
 
32
- gem.add_development_dependency 'rspec-rails' , '~> 3.0.0.beta'
31
+ gem.add_development_dependency 'rspec-rails'
33
32
  gem.add_development_dependency 'rspec-its'
34
33
  gem.add_development_dependency 'rspec'
35
- gem.add_development_dependency 'ammeter'
36
34
  gem.add_development_dependency 'barrier'
37
35
  gem.add_development_dependency 'database_cleaner'
38
36
  end
@@ -2,7 +2,7 @@ class AddMissingUniqueIndices < ActiveRecord::Migration
2
2
  def self.up
3
3
  add_index :tags, :name, unique: true
4
4
 
5
- remove_index :taggings, :tag_id
5
+ remove_index :taggings, :tag_id if index_exists?(:taggings, :tag_id)
6
6
  remove_index :taggings, [:taggable_id, :taggable_type, :context]
7
7
  add_index :taggings,
8
8
  [:tag_id, :taggable_id, :taggable_type, :context, :tagger_id, :tagger_type],
@@ -13,7 +13,8 @@ class AddMissingUniqueIndices < ActiveRecord::Migration
13
13
  remove_index :tags, :name
14
14
 
15
15
  remove_index :taggings, name: 'taggings_idx'
16
- add_index :taggings, :tag_id
16
+
17
+ add_index :taggings, :tag_id unless index_exists?(:taggings, :tag_id)
17
18
  add_index :taggings, [:taggable_id, :taggable_type, :context]
18
19
  end
19
20
  end
@@ -0,0 +1,9 @@
1
+ class AddMissingTaggableIndex < ActiveRecord::Migration
2
+ def self.up
3
+ add_index :taggings, [:taggable_id, :taggable_type, :context]
4
+ end
5
+
6
+ def self.down
7
+ remove_index :taggings, [:taggable_id, :taggable_type, :context]
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # This migration is added to circumvent issue #623 and have special characters
2
+ # work properly
3
+ class ChangeCollationForTagNames < ActiveRecord::Migration
4
+ def up
5
+ if ActsAsTaggableOn::Utils.using_mysql?
6
+ execute("ALTER TABLE tags MODIFY name varchar(255) CHARACTER SET utf8 COLLATE utf8_bin;")
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ class AddMissingIndexes < ActiveRecord::Migration
2
+ def change
3
+ add_index :taggings, :tag_id
4
+ add_index :taggings, :taggable_id
5
+ add_index :taggings, :taggable_type
6
+ add_index :taggings, :tagger_id
7
+ add_index :taggings, :context
8
+
9
+ add_index :taggings, [:tagger_id, :tagger_type]
10
+ add_index :taggings, [:taggable_id, :taggable_type, :tagger_id, :context], name: 'taggings_idy'
11
+ end
12
+ end