acts-as-taggable-on 2.0.0 → 3.2.2
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 +7 -0
- data/.gitignore +11 -0
- data/.travis.yml +23 -0
- data/Appraisals +20 -0
- data/CHANGELOG.md +112 -0
- data/CONTRIBUTING.md +44 -0
- data/Gemfile +9 -5
- data/Guardfile +5 -0
- data/{MIT-LICENSE → LICENSE.md} +1 -1
- data/README.md +385 -0
- data/Rakefile +13 -53
- data/UPGRADING.md +13 -0
- data/acts-as-taggable-on.gemspec +38 -0
- data/{lib/generators/acts_as_taggable_on/migration/templates/active_record/migration.rb → db/migrate/1_acts_as_taggable_on_migration.rb} +5 -3
- data/db/migrate/2_add_missing_unique_indices.rb +19 -0
- data/db/migrate/3_add_taggings_counter_cache_to_tags.rb +14 -0
- data/gemfiles/activerecord_3.2.gemfile +15 -0
- data/gemfiles/activerecord_4.0.gemfile +15 -0
- data/gemfiles/activerecord_4.1.gemfile +15 -0
- data/gemfiles/activerecord_edge.gemfile +16 -0
- data/lib/acts-as-taggable-on.rb +65 -22
- data/lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb +53 -24
- data/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb +120 -42
- data/lib/acts_as_taggable_on/acts_as_taggable_on/compatibility.rb +35 -0
- data/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb +309 -124
- data/lib/acts_as_taggable_on/acts_as_taggable_on/dirty.rb +36 -0
- data/lib/acts_as_taggable_on/acts_as_taggable_on/ownership.rb +96 -72
- data/lib/acts_as_taggable_on/acts_as_taggable_on/related.rb +43 -36
- data/lib/acts_as_taggable_on/engine.rb +5 -0
- data/lib/acts_as_taggable_on/tag.rb +133 -63
- data/lib/acts_as_taggable_on/tag_list.rb +162 -81
- data/lib/acts_as_taggable_on/taggable.rb +101 -0
- data/lib/acts_as_taggable_on/{acts_as_tagger.rb → tagger.rb} +34 -13
- data/lib/acts_as_taggable_on/tagging.rb +28 -18
- data/lib/acts_as_taggable_on/tags_helper.rb +12 -14
- data/lib/acts_as_taggable_on/utils.rb +62 -0
- data/lib/acts_as_taggable_on/version.rb +4 -0
- data/lib/acts_as_taggable_on.rb +6 -0
- data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +189 -195
- data/spec/acts_as_taggable_on/acts_as_tagger_spec.rb +78 -81
- data/spec/acts_as_taggable_on/caching_spec.rb +76 -0
- data/spec/acts_as_taggable_on/related_spec.rb +89 -0
- data/spec/acts_as_taggable_on/single_table_inheritance_spec.rb +210 -0
- data/spec/acts_as_taggable_on/tag_list_spec.rb +149 -61
- data/spec/acts_as_taggable_on/tag_spec.rb +245 -65
- data/spec/acts_as_taggable_on/taggable_spec.rb +776 -187
- data/spec/acts_as_taggable_on/tagger_spec.rb +119 -70
- data/spec/acts_as_taggable_on/tagging_spec.rb +17 -21
- data/spec/acts_as_taggable_on/tags_helper_spec.rb +38 -22
- data/spec/acts_as_taggable_on/utils_spec.rb +15 -0
- data/spec/internal/app/models/altered_inheriting_taggable_model.rb +3 -0
- data/spec/internal/app/models/cached_model.rb +3 -0
- data/spec/internal/app/models/cached_model_with_array.rb +5 -0
- data/spec/internal/app/models/company.rb +15 -0
- data/spec/internal/app/models/inheriting_taggable_model.rb +2 -0
- data/spec/internal/app/models/market.rb +2 -0
- data/spec/internal/app/models/models.rb +90 -0
- data/spec/internal/app/models/non_standard_id_taggable_model.rb +8 -0
- data/spec/internal/app/models/ordered_taggable_model.rb +4 -0
- data/spec/internal/app/models/other_cached_model.rb +3 -0
- data/spec/internal/app/models/other_taggable_model.rb +4 -0
- data/spec/internal/app/models/student.rb +2 -0
- data/spec/internal/app/models/taggable_model.rb +13 -0
- data/spec/internal/app/models/untaggable_model.rb +3 -0
- data/spec/internal/app/models/user.rb +3 -0
- data/spec/internal/config/database.yml.sample +19 -0
- data/spec/internal/db/schema.rb +97 -0
- data/spec/schema.rb +57 -18
- data/spec/spec_helper.rb +12 -47
- data/spec/support/array.rb +9 -0
- data/spec/support/database.rb +42 -0
- data/spec/support/database_cleaner.rb +21 -0
- metadata +286 -63
- data/CHANGELOG +0 -25
- data/README.rdoc +0 -221
- data/VERSION +0 -1
- data/generators/acts_as_taggable_on_migration/acts_as_taggable_on_migration_generator.rb +0 -7
- data/generators/acts_as_taggable_on_migration/templates/migration.rb +0 -29
- data/lib/acts_as_taggable_on/acts_as_taggable_on.rb +0 -53
- data/lib/acts_as_taggable_on/compatibility/Gemfile +0 -6
- data/lib/acts_as_taggable_on/compatibility/active_record_backports.rb +0 -17
- data/lib/generators/acts_as_taggable_on/migration/migration_generator.rb +0 -31
- data/rails/init.rb +0 -1
- data/spec/bm.rb +0 -52
- data/spec/models.rb +0 -30
- /data/{spec/spec.opts → .rspec} +0 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: bc40e6d7c5c8b741bfc71aee7ae2406c6f824108
|
|
4
|
+
data.tar.gz: 3c89e20ed3b39ef33d52724d4bb8b9aa3e5738f9
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: e4142af492646d113a10fa0ae4815d91a281f2a55d60fb70b653a96d4ac58e24c56e1e10bcbf9907bbcc06cee2b476b6ec4a568cc25e5247578a140cbf388d85
|
|
7
|
+
data.tar.gz: eceb8e025f83cdbc9e237405eac982aa3b7c7ef0f54d803fcd80d1ed837b833d4f07fe549f0eb0eaa443edb5cdc84bcad79555a67a886e7fc706b46aa5d37b35
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
rvm:
|
|
2
|
+
- 1.9.3
|
|
3
|
+
- 2.0.0
|
|
4
|
+
- 2.1.1
|
|
5
|
+
- rbx-2
|
|
6
|
+
env:
|
|
7
|
+
- DB=sqlite3
|
|
8
|
+
- DB=mysql
|
|
9
|
+
- DB=postgresql
|
|
10
|
+
gemfile:
|
|
11
|
+
- gemfiles/activerecord_3.2.gemfile
|
|
12
|
+
- gemfiles/activerecord_4.0.gemfile
|
|
13
|
+
- gemfiles/activerecord_4.1.gemfile
|
|
14
|
+
- gemfiles/activerecord_edge.gemfile
|
|
15
|
+
cache: bundler
|
|
16
|
+
script: bundle exec rake
|
|
17
|
+
before_install: gem install bundler
|
|
18
|
+
bundler_args: '--without local_development'
|
|
19
|
+
matrix:
|
|
20
|
+
fast_finish: true
|
|
21
|
+
allow_failures:
|
|
22
|
+
- gemfile: gemfiles/activerecord_edge.gemfile
|
|
23
|
+
- rvm: rbx-2
|
data/Appraisals
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
appraise "activerecord-3.2" do
|
|
2
|
+
gem "activerecord", "~> 3.2"
|
|
3
|
+
gem "actionpack", "~> 3.2"
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
appraise "activerecord-4.0" do
|
|
7
|
+
gem "activerecord", "~> 4.0"
|
|
8
|
+
gem "actionpack", "~> 4.0"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
appraise "activerecord-4.1" do
|
|
12
|
+
gem "activerecord", "~> 4.1"
|
|
13
|
+
gem "actionpack", "~> 4.1"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
appraise "activerecord-edge" do
|
|
17
|
+
gem "activerecord", github: "rails/rails"
|
|
18
|
+
gem "actionpack", github: "rails/rails"
|
|
19
|
+
gem 'arel', github: 'rails/arel'
|
|
20
|
+
end
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
Changes are below categorized as `Features, Fixes, or Misc`.
|
|
2
|
+
|
|
3
|
+
Each change should fall into categories that would affect whether the release is major (breaking changes), minor (new behavior), or patch (bug fix). See [semver](http://semver.org/) and [pessimistic versioning](http://guides.rubygems.org/patterns/#pessimistic_version_constraint)
|
|
4
|
+
|
|
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
|
+
|
|
7
|
+
### Master [changes](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.2.0...master)
|
|
8
|
+
|
|
9
|
+
* Breaking Changes
|
|
10
|
+
* Taggable models are not extend with ActsAsTaggableOn::Utils anymore
|
|
11
|
+
* Features
|
|
12
|
+
* Fixes
|
|
13
|
+
* Performance
|
|
14
|
+
* Misc
|
|
15
|
+
* Deleted outdated benchmark script
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### [3.2.0 / 2014-05-1](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.1.1...v3.2.0)
|
|
19
|
+
|
|
20
|
+
* Breaking Changes
|
|
21
|
+
* ActsAsTaggableOn::Tag is not extend with ActsAsTaggableOn::Utils anymore
|
|
22
|
+
* Features
|
|
23
|
+
* [@chess #413 Hook to support STI subclasses of Tag in save_tags](https://github.com/mbleigh/acts-as-taggable-on/pull/413)
|
|
24
|
+
* Fixes
|
|
25
|
+
* [@jdelStrother #515 Rename Compatibility methods to reduce chance of conflicts ](https://github.com/mbleigh/acts-as-taggable-on/pull/515)
|
|
26
|
+
* [@seuros #512 fix for << method](https://github.com/mbleigh/acts-as-taggable-on/pull/512)
|
|
27
|
+
* [@sonots #510 fix IN subquery error for mysql](https://github.com/mbleigh/acts-as-taggable-on/pull/510)
|
|
28
|
+
* [@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)
|
|
29
|
+
* [@leklund #496 Fix for distinct and postgresql json columns errors](https://github.com/mbleigh/acts-as-taggable-on/pull/496)
|
|
30
|
+
* [@thatbettina & @plexus #394 Multiple quoted tags](https://github.com/mbleigh/acts-as-taggable-on/pull/496)
|
|
31
|
+
* Performance
|
|
32
|
+
* Misc
|
|
33
|
+
* [@seuros #511 Rspec 3](https://github.com/mbleigh/acts-as-taggable-on/pull/511)
|
|
34
|
+
|
|
35
|
+
### [3.1.0 / 2014-03-31](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.0.1...v3.1.0)
|
|
36
|
+
|
|
37
|
+
* Fixes
|
|
38
|
+
* [@mikehale #487 Match_all respects context](https://github.com/mbleigh/acts-as-taggable-on/pull/487)
|
|
39
|
+
* Performance
|
|
40
|
+
* [@dgilperez #390 Add taggings counter cache](https://github.com/mbleigh/acts-as-taggable-on/pull/390)
|
|
41
|
+
* Misc
|
|
42
|
+
* [@jonseaberg Add missing indexes to schema used in specs #474](https://github.com/mbleigh/acts-as-taggable-on/pull/474)
|
|
43
|
+
* [@seuros Specify Ruby >= 1.9.3 required in gemspec](https://github.com/mbleigh/acts-as-taggable-on/pull/502)
|
|
44
|
+
* [@kiasaki Add missing quotes to code example](https://github.com/mbleigh/acts-as-taggable-on/pull/501)
|
|
45
|
+
|
|
46
|
+
### [3.1.0.rc1 / 2014-02-26](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.0.1...v3.1.0.rc1)
|
|
47
|
+
|
|
48
|
+
* Features
|
|
49
|
+
* [@jamesburke-examtime #467 Add :order_by_matching_tag_count option](https://github.com/mbleigh/acts-as-taggable-on/pull/469)
|
|
50
|
+
* Fixes
|
|
51
|
+
* [@rafael #406 Dirty attributes not correctly derived](https://github.com/mbleigh/acts-as-taggable-on/pull/406)
|
|
52
|
+
* [@bzbnhang #440 Did not respect strict_case_match](https://github.com/mbleigh/acts-as-taggable-on/pull/440)
|
|
53
|
+
* [@znz #456 Fix breaking encoding of tag](https://github.com/mbleigh/acts-as-taggable-on/pull/456)
|
|
54
|
+
* [@rgould #417 Let '.count' work when tagged_with is accompanied by a group clause](https://github.com/mbleigh/acts-as-taggable-on/pull/417)
|
|
55
|
+
* [@developer88 #461 Move 'Distinct' out of select string and use .uniq instead](https://github.com/mbleigh/acts-as-taggable-on/pull/461)
|
|
56
|
+
* [@gerard-leijdekkers #473 Fixed down migration index name](https://github.com/mbleigh/acts-as-taggable-on/pull/473)
|
|
57
|
+
* [@leo-souza #498 Use database's lower function for case-insensitive match](https://github.com/mbleigh/acts-as-taggable-on/pull/498)
|
|
58
|
+
* Misc
|
|
59
|
+
* [@billychan #463 Thread safe support](https://github.com/mbleigh/acts-as-taggable-on/pull/463)
|
|
60
|
+
* [@billychan #386 Add parse:true instructions to README](https://github.com/mbleigh/acts-as-taggable-on/pull/386)
|
|
61
|
+
* [@seuros #449 Improve README/UPGRADING/post install docs](https://github.com/mbleigh/acts-as-taggable-on/pull/449)
|
|
62
|
+
* [@seuros #452 Remove I18n deprecation warning in specs](https://github.com/mbleigh/acts-as-taggable-on/pull/452)
|
|
63
|
+
* [@seuros #453 Test against Ruby 2.1 on Travis CI](https://github.com/mbleigh/acts-as-taggable-on/pull/453)
|
|
64
|
+
* [@takashi #454 Clarify example in docs](https://github.com/mbleigh/acts-as-taggable-on/pull/454)
|
|
65
|
+
|
|
66
|
+
### [3.0.1 / 2014-01-08](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.0.0...v3.0.1)
|
|
67
|
+
|
|
68
|
+
* Fixes
|
|
69
|
+
* [@rafael #406 Dirty attributes not correctly derived](https://github.com/mbleigh/acts-as-taggable-on/pull/406)
|
|
70
|
+
* [@bzbnhang #440 Did not respect strict_case_match](https://github.com/mbleigh/acts-as-taggable-on/pull/440)
|
|
71
|
+
* [@znz #456 Fix breaking encoding of tag](https://github.com/mbleigh/acts-as-taggable-on/pull/456)
|
|
72
|
+
* Misc
|
|
73
|
+
* [@billychan #386 Add parse:true instructions to README](https://github.com/mbleigh/acts-as-taggable-on/pull/386)
|
|
74
|
+
* [@seuros #449 Improve README/UPGRADING/post install docs](https://github.com/mbleigh/acts-as-taggable-on/pull/449)
|
|
75
|
+
* [@seuros #452 Remove I18n deprecation warning in specs](https://github.com/mbleigh/acts-as-taggable-on/pull/452)
|
|
76
|
+
* [@seuros #453 Test against Ruby 2.1 on Travis CI](https://github.com/mbleigh/acts-as-taggable-on/pull/453)
|
|
77
|
+
* [@takashi #454 Clarify example in docs](https://github.com/mbleigh/acts-as-taggable-on/pull/454)
|
|
78
|
+
|
|
79
|
+
### [3.0.0 / 2014-01-01](https://github.com/mbleigh/acts-as-taggable-on/compare/v2.4.1...v3.0.0)
|
|
80
|
+
|
|
81
|
+
* Breaking Changes
|
|
82
|
+
* No longer supports Ruby 1.8.
|
|
83
|
+
* Features
|
|
84
|
+
* Supports Rails 4.1.
|
|
85
|
+
* Misc (TODO: expand)
|
|
86
|
+
* [zquest #359](https://github.com/mbleigh/acts-as-taggable-on/pull/359)
|
|
87
|
+
* [rsl #367](https://github.com/mbleigh/acts-as-taggable-on/pull/367)
|
|
88
|
+
* [ktdreyer #383](https://github.com/mbleigh/acts-as-taggable-on/pull/383)
|
|
89
|
+
* [cwoodcox #346](https://github.com/mbleigh/acts-as-taggable-on/pull/346)
|
|
90
|
+
* [mrb #421](https://github.com/mbleigh/acts-as-taggable-on/pull/421)
|
|
91
|
+
* [bf4 #430](https://github.com/mbleigh/acts-as-taggable-on/pull/430)
|
|
92
|
+
* [sanemat #368](https://github.com/mbleigh/acts-as-taggable-on/pull/368)
|
|
93
|
+
* [bf4 #343](https://github.com/mbleigh/acts-as-taggable-on/pull/343)
|
|
94
|
+
* [marclennox #429](https://github.com/mbleigh/acts-as-taggable-on/pull/429)
|
|
95
|
+
* [shekibobo #403](https://github.com/mbleigh/acts-as-taggable-on/pull/403)
|
|
96
|
+
* [ches ktdreyer #410](https://github.com/mbleigh/acts-as-taggable-on/pull/410)
|
|
97
|
+
* [makaroni4 #371](https://github.com/mbleigh/acts-as-taggable-on/pull/371)
|
|
98
|
+
* [kenzai dstosik awt #431](https://github.com/mbleigh/acts-as-taggable-on/pull/431)
|
|
99
|
+
* [bf4 joelcogen shekibobo aaronchi #438](https://github.com/mbleigh/acts-as-taggable-on/pull/438)
|
|
100
|
+
* [seuros #442](https://github.com/mbleigh/acts-as-taggable-on/pull/442)
|
|
101
|
+
* [bf4 #445](https://github.com/mbleigh/acts-as-taggable-on/pull/445)
|
|
102
|
+
* [eaglemt #446](https://github.com/mbleigh/acts-as-taggable-on/pull/446)
|
|
103
|
+
|
|
104
|
+
### 3.0.0.rc2 [changes](https://github.com/mbleigh/acts-as-taggable-on/compare/fork-v3.0.0.rc1...fork-v3.0.0.rc2)
|
|
105
|
+
|
|
106
|
+
### 3.0.0.rc1 [changes](https://github.com/mbleigh/acts-as-taggable-on/compare/v2.4.1...fork-v3.0.0.rc1)
|
|
107
|
+
|
|
108
|
+
### [2.4.1 / 2013-05-07](https://github.com/mbleigh/acts-as-taggable-on/compare/v2.4.0...v2.4.1)
|
|
109
|
+
|
|
110
|
+
* Features
|
|
111
|
+
* Fixes
|
|
112
|
+
* Misc
|
data/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# How to contribute:
|
|
2
|
+
|
|
3
|
+
## Bug reports / Issues
|
|
4
|
+
|
|
5
|
+
* Is something broken or not working as expected? Check for an existing issue or [create a new one](https://github.com/mbleigh/acts-as-taggable-on/issues/new)
|
|
6
|
+
* IMPORTANT: Include the version of the gem, if you've install from git, what Ruby and Rails you are running, etc.
|
|
7
|
+
|
|
8
|
+
## Code
|
|
9
|
+
|
|
10
|
+
1. [Fork and clone the repo](https://help.github.com/articles/fork-a-repo)
|
|
11
|
+
2. Install the gem dependencies: `bundle install`
|
|
12
|
+
3. Make the changes you want and back them up with tests.
|
|
13
|
+
* [Run the tests](https://github.com/mbleigh/acts-as-taggable-on#testing) (`bundle exec rake spec`)
|
|
14
|
+
4. Update the CHANGELOG.md file with your changes and give yourself credit
|
|
15
|
+
5. Commit and create a pull request with details as to what has been changed and why
|
|
16
|
+
* Use well-described, small (atomic) commits.
|
|
17
|
+
* Include links to any relevant github issues.
|
|
18
|
+
* *Don't* change the VERSION file.
|
|
19
|
+
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.
|
|
20
|
+
|
|
21
|
+
How I handle pull requests:
|
|
22
|
+
|
|
23
|
+
* If the tests pass and the pull request looks good, I will merge it.
|
|
24
|
+
* If the pull request needs to be changed,
|
|
25
|
+
* you can change it by updating the branch you generated the pull request from
|
|
26
|
+
* either by adding more commits, or
|
|
27
|
+
* by force pushing to it
|
|
28
|
+
* I can make any changes myself and manually merge the code in.
|
|
29
|
+
|
|
30
|
+
### Commit Messages
|
|
31
|
+
|
|
32
|
+
* [A Note About Git Commit Messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
|
|
33
|
+
* [http://stopwritingramblingcommitmessages.com/](http://stopwritingramblingcommitmessages.com/)
|
|
34
|
+
* [ThoughtBot style guide](https://github.com/thoughtbot/guides/tree/master/style#git)
|
|
35
|
+
|
|
36
|
+
### About Pull Requests (PR's)
|
|
37
|
+
|
|
38
|
+
* [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/)
|
|
39
|
+
* [Using Pull Requests](https://help.github.com/articles/using-pull-requests)
|
|
40
|
+
* [Github pull requests made easy](http://www.element84.com/github-pull-requests-made-easy.html)
|
|
41
|
+
|
|
42
|
+
## Documentation
|
|
43
|
+
|
|
44
|
+
* Update the wiki
|
data/Gemfile
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
source
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
gem '
|
|
3
|
+
gemspec
|
|
4
|
+
|
|
5
|
+
group :local_development do
|
|
6
|
+
gem 'guard'
|
|
7
|
+
gem 'guard-rspec'
|
|
8
|
+
gem 'appraisal'
|
|
9
|
+
gem 'rake'
|
|
10
|
+
end
|
data/Guardfile
ADDED
data/{MIT-LICENSE → LICENSE.md}
RENAMED
data/README.md
ADDED
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
# ActsAsTaggableOn
|
|
2
|
+
[](http://travis-ci.org/mbleigh/acts-as-taggable-on)
|
|
3
|
+
[](https://codeclimate.com/github/mbleigh/acts-as-taggable-on)
|
|
4
|
+
[](http://inch-pages.github.io/github/mbleigh/acts-as-taggable-on)
|
|
5
|
+
|
|
6
|
+
This plugin was originally based on Acts as Taggable on Steroids by Jonathan Viney.
|
|
7
|
+
It has evolved substantially since that point, but all credit goes to him for the
|
|
8
|
+
initial tagging functionality that so many people have used.
|
|
9
|
+
|
|
10
|
+
For instance, in a social network, a user might have tags that are called skills,
|
|
11
|
+
interests, sports, and more. There is no real way to differentiate between tags and
|
|
12
|
+
so an implementation of this type is not possible with acts as taggable on steroids.
|
|
13
|
+
|
|
14
|
+
Enter Acts as Taggable On. Rather than tying functionality to a specific keyword
|
|
15
|
+
(namely `tags`), acts as taggable on allows you to specify an arbitrary number of
|
|
16
|
+
tag "contexts" that can be used locally or in combination in the same way steroids
|
|
17
|
+
was used.
|
|
18
|
+
|
|
19
|
+
## Compatibility
|
|
20
|
+
|
|
21
|
+
Versions 2.x are compatible with Ruby 1.8.7+ and Rails 3.
|
|
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
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
To use it, add it to your Gemfile:
|
|
32
|
+
|
|
33
|
+
```ruby
|
|
34
|
+
gem 'acts-as-taggable-on'
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
and bundle:
|
|
38
|
+
|
|
39
|
+
```shell
|
|
40
|
+
bundle
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
#### Post Installation
|
|
44
|
+
|
|
45
|
+
Install migrations
|
|
46
|
+
|
|
47
|
+
```shell
|
|
48
|
+
# For the latest versions :
|
|
49
|
+
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
|
+
```
|
|
53
|
+
|
|
54
|
+
Review the generated migrations then migrate :
|
|
55
|
+
```shell
|
|
56
|
+
rake db:migrate
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
#### Upgrading
|
|
60
|
+
|
|
61
|
+
see [UPGRADING](UPGRADING.md)
|
|
62
|
+
|
|
63
|
+
## Usage
|
|
64
|
+
|
|
65
|
+
Setup
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
class User < ActiveRecord::Base
|
|
69
|
+
acts_as_taggable # Alias for acts_as_taggable_on :tags
|
|
70
|
+
acts_as_taggable_on :skills, :interests
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
@user = User.new(:name => "Bobby")
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Add and remove a single tag
|
|
77
|
+
|
|
78
|
+
```ruby
|
|
79
|
+
@user.tag_list.add("awesome") # add a single tag. alias for <<
|
|
80
|
+
@user.tag_list.remove("awesome") # remove a single tag
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Add and remove multiple tags in an array
|
|
84
|
+
|
|
85
|
+
```ruby
|
|
86
|
+
@user.tag_list.add("awesome", "slick")
|
|
87
|
+
@user.tag_list.remove("awesome", "slick")
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
You can also add and remove tags in format of String. This would
|
|
91
|
+
be convenient in some cases such as handling tag input param in a String.
|
|
92
|
+
|
|
93
|
+
Pay attention you need to add `parse: true` as option in this case.
|
|
94
|
+
|
|
95
|
+
You may also want to take a look at delimiter in the string. The default
|
|
96
|
+
is comma `,` so you don't need to do anything here. However, if you made
|
|
97
|
+
a change on delimiter setting, make sure the string will match. See
|
|
98
|
+
[configuration](#configuration) for more about delimiter.
|
|
99
|
+
|
|
100
|
+
```ruby
|
|
101
|
+
@user.tag_list.add("awesome, slick", parse: true)
|
|
102
|
+
@user.tag_list.remove("awesome, slick", parse: true)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
You can also add and remove tags by direct assignment. Note this will
|
|
106
|
+
remove existing tags so use it with attention.
|
|
107
|
+
|
|
108
|
+
```ruby
|
|
109
|
+
@user.tag_list = "awesome, slick, hefty"
|
|
110
|
+
@user.save
|
|
111
|
+
@user.reload
|
|
112
|
+
@user.tags
|
|
113
|
+
=> [#<ActsAsTaggableOn::Tag id: 1, name: "awesome", taggings_count: 1>,
|
|
114
|
+
#<ActsAsTaggableOn::Tag id: 2, name: "slick", taggings_count: 1>,
|
|
115
|
+
#<ActsAsTaggableOn::Tag id: 3, name: "hefty", taggings_count: 1>]
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
With the defined context in model, you have multiple new methods at disposal
|
|
119
|
+
to manage and view the tags in the context. For example, with `:skill` context
|
|
120
|
+
these methods are added to the model: `skill_list`(and `skill_list.add`, `skill_list.remove`
|
|
121
|
+
`skill_list=`), `skills`(plural), `skill_counts`.
|
|
122
|
+
|
|
123
|
+
```ruby
|
|
124
|
+
@user.skill_list = "joking, clowning, boxing"
|
|
125
|
+
@user.save
|
|
126
|
+
@user.reload
|
|
127
|
+
@user.skills
|
|
128
|
+
=> [#<ActsAsTaggableOn::Tag id: 1, name: "joking", taggings_count: 1>,
|
|
129
|
+
#<ActsAsTaggableOn::Tag id: 2, name: "clowning", taggings_count: 1>,
|
|
130
|
+
#<ActsAsTaggableOn::Tag id: 3, name: "boxing", taggings_count: 1>]
|
|
131
|
+
|
|
132
|
+
@user.skill_list.add("coding")
|
|
133
|
+
|
|
134
|
+
@user.skill_list
|
|
135
|
+
# => ["joking", "clowning", "boxing", "coding"]
|
|
136
|
+
|
|
137
|
+
@another_user = User.new(:name => "Alice")
|
|
138
|
+
@another_user.skill_list.add("clowning")
|
|
139
|
+
@another_user.save
|
|
140
|
+
|
|
141
|
+
User.skill_counts
|
|
142
|
+
=> [#<ActsAsTaggableOn::Tag id: 1, name: "joking", taggings_count: 1>,
|
|
143
|
+
#<ActsAsTaggableOn::Tag id: 2, name: "clowning", taggings_count: 2>,
|
|
144
|
+
#<ActsAsTaggableOn::Tag id: 3, name: "boxing", taggings_count: 1>]
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
To preserve the order in which tags are created use `acts_as_ordered_taggable`:
|
|
148
|
+
|
|
149
|
+
```ruby
|
|
150
|
+
class User < ActiveRecord::Base
|
|
151
|
+
# Alias for acts_as_ordered_taggable_on :tags
|
|
152
|
+
acts_as_ordered_taggable
|
|
153
|
+
acts_as_ordered_taggable_on :skills, :interests
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
@user = User.new(:name => "Bobby")
|
|
157
|
+
@user.tag_list = "east, south"
|
|
158
|
+
@user.save
|
|
159
|
+
|
|
160
|
+
@user.tag_list = "north, east, south, west"
|
|
161
|
+
@user.save
|
|
162
|
+
|
|
163
|
+
@user.reload
|
|
164
|
+
@user.tag_list # => ["north", "east", "south", "west"]
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Finding Tagged Objects
|
|
168
|
+
|
|
169
|
+
Acts As Taggable On uses scopes to create an association for tags.
|
|
170
|
+
This way you can mix and match to filter down your results.
|
|
171
|
+
|
|
172
|
+
```ruby
|
|
173
|
+
class User < ActiveRecord::Base
|
|
174
|
+
acts_as_taggable_on :tags, :skills
|
|
175
|
+
scope :by_join_date, order("created_at DESC")
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
User.tagged_with("awesome").by_join_date
|
|
179
|
+
User.tagged_with("awesome").by_join_date.paginate(:page => params[:page], :per_page => 20)
|
|
180
|
+
|
|
181
|
+
# Find users that matches all given tags:
|
|
182
|
+
User.tagged_with(["awesome", "cool"], :match_all => true)
|
|
183
|
+
|
|
184
|
+
# Find users with any of the specified tags:
|
|
185
|
+
User.tagged_with(["awesome", "cool"], :any => true)
|
|
186
|
+
|
|
187
|
+
# Find users that has not been tagged with awesome or cool:
|
|
188
|
+
User.tagged_with(["awesome", "cool"], :exclude => true)
|
|
189
|
+
|
|
190
|
+
# Find users with any of the tags based on context:
|
|
191
|
+
User.tagged_with(['awesome', 'cool'], :on => :tags, :any => true).tagged_with(['smart', 'shy'], :on => :skills, :any => true)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
You can also use `:wild => true` option along with `:any` or `:exclude` option. It will be looking for `%awesome%` and `%cool%` in SQL.
|
|
195
|
+
|
|
196
|
+
__Tip:__ `User.tagged_with([])` or `User.tagged_with('')` will return `[]`, an empty set of records.
|
|
197
|
+
|
|
198
|
+
### Relationships
|
|
199
|
+
|
|
200
|
+
You can find objects of the same type based on similar tags on certain contexts.
|
|
201
|
+
Also, objects will be returned in descending order based on the total number of
|
|
202
|
+
matched tags.
|
|
203
|
+
|
|
204
|
+
```ruby
|
|
205
|
+
@bobby = User.find_by_name("Bobby")
|
|
206
|
+
@bobby.skill_list # => ["jogging", "diving"]
|
|
207
|
+
|
|
208
|
+
@frankie = User.find_by_name("Frankie")
|
|
209
|
+
@frankie.skill_list # => ["hacking"]
|
|
210
|
+
|
|
211
|
+
@tom = User.find_by_name("Tom")
|
|
212
|
+
@tom.skill_list # => ["hacking", "jogging", "diving"]
|
|
213
|
+
|
|
214
|
+
@tom.find_related_skills # => [<User name="Bobby">, <User name="Frankie">]
|
|
215
|
+
@bobby.find_related_skills # => [<User name="Tom">]
|
|
216
|
+
@frankie.find_related_skills # => [<User name="Tom">]
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Dynamic Tag Contexts
|
|
220
|
+
|
|
221
|
+
In addition to the generated tag contexts in the definition, it is also possible
|
|
222
|
+
to allow for dynamic tag contexts (this could be user generated tag contexts!)
|
|
223
|
+
|
|
224
|
+
```ruby
|
|
225
|
+
@user = User.new(:name => "Bobby")
|
|
226
|
+
@user.set_tag_list_on(:customs, "same, as, tag, list")
|
|
227
|
+
@user.tag_list_on(:customs) # => ["same", "as", "tag", "list"]
|
|
228
|
+
@user.save
|
|
229
|
+
@user.tags_on(:customs) # => [<Tag name='same'>,...]
|
|
230
|
+
@user.tag_counts_on(:customs)
|
|
231
|
+
User.tagged_with("same", :on => :customs) # => [@user]
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Tag Ownership
|
|
235
|
+
|
|
236
|
+
Tags can have owners:
|
|
237
|
+
|
|
238
|
+
```ruby
|
|
239
|
+
class User < ActiveRecord::Base
|
|
240
|
+
acts_as_tagger
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
class Photo < ActiveRecord::Base
|
|
244
|
+
acts_as_taggable_on :locations
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
@some_user.tag(@some_photo, :with => "paris, normandy", :on => :locations)
|
|
248
|
+
@some_user.owned_taggings
|
|
249
|
+
@some_user.owned_tags
|
|
250
|
+
Photo.tagged_with("paris", :on => :locations, :owned_by => @some_user)
|
|
251
|
+
@some_photo.locations_from(@some_user) # => ["paris", "normandy"]
|
|
252
|
+
@some_photo.owner_tags_on(@some_user, :locations) # => [#<ActsAsTaggableOn::Tag id: 1, name: "paris">...]
|
|
253
|
+
@some_photo.owner_tags_on(nil, :locations) # => Ownerships equivalent to saying @some_photo.locations
|
|
254
|
+
@some_user.tag(@some_photo, :with => "paris, normandy", :on => :locations, :skip_save => true) #won't save @some_photo object
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Dirty objects
|
|
258
|
+
|
|
259
|
+
```ruby
|
|
260
|
+
@bobby = User.find_by_name("Bobby")
|
|
261
|
+
@bobby.skill_list # => ["jogging", "diving"]
|
|
262
|
+
|
|
263
|
+
@bobby.skill_list_changed? #=> false
|
|
264
|
+
@bobby.changes #=> {}
|
|
265
|
+
|
|
266
|
+
@bobby.skill_list = "swimming"
|
|
267
|
+
@bobby.changes.should == {"skill_list"=>["jogging, diving", ["swimming"]]}
|
|
268
|
+
@bobby.skill_list_changed? #=> true
|
|
269
|
+
|
|
270
|
+
@bobby.skill_list_change.should == ["jogging, diving", ["swimming"]]
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Tag cloud calculations
|
|
274
|
+
|
|
275
|
+
To construct tag clouds, the frequency of each tag needs to be calculated.
|
|
276
|
+
Because we specified `acts_as_taggable_on` on the `User` class, we can
|
|
277
|
+
get a calculation of all the tag counts by using `User.tag_counts_on(:customs)`. But what if we wanted a tag count for
|
|
278
|
+
a single user's posts? To achieve this we call tag_counts on the association:
|
|
279
|
+
|
|
280
|
+
```ruby
|
|
281
|
+
User.find(:first).posts.tag_counts_on(:tags)
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
A helper is included to assist with generating tag clouds.
|
|
285
|
+
|
|
286
|
+
Here is an example that generates a tag cloud.
|
|
287
|
+
|
|
288
|
+
Helper:
|
|
289
|
+
|
|
290
|
+
```ruby
|
|
291
|
+
module PostsHelper
|
|
292
|
+
include ActsAsTaggableOn::TagsHelper
|
|
293
|
+
end
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Controller:
|
|
297
|
+
|
|
298
|
+
```ruby
|
|
299
|
+
class PostController < ApplicationController
|
|
300
|
+
def tag_cloud
|
|
301
|
+
@tags = Post.tag_counts_on(:tags)
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
View:
|
|
307
|
+
|
|
308
|
+
```erb
|
|
309
|
+
<% tag_cloud(@tags, %w(css1 css2 css3 css4)) do |tag, css_class| %>
|
|
310
|
+
<%= link_to tag.name, { :action => :tag, :id => tag.name }, :class => css_class %>
|
|
311
|
+
<% end %>
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
CSS:
|
|
315
|
+
|
|
316
|
+
```css
|
|
317
|
+
.css1 { font-size: 1.0em; }
|
|
318
|
+
.css2 { font-size: 1.2em; }
|
|
319
|
+
.css3 { font-size: 1.4em; }
|
|
320
|
+
.css4 { font-size: 1.6em; }
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
## Configuration
|
|
324
|
+
|
|
325
|
+
If you would like to remove unused tag objects after removing taggings, add:
|
|
326
|
+
|
|
327
|
+
```ruby
|
|
328
|
+
ActsAsTaggableOn.remove_unused_tags = true
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
If you want force tags to be saved downcased:
|
|
332
|
+
|
|
333
|
+
```ruby
|
|
334
|
+
ActsAsTaggableOn.force_lowercase = true
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
If you want tags to be saved parametrized (you can redefine to_param as well):
|
|
338
|
+
|
|
339
|
+
```ruby
|
|
340
|
+
ActsAsTaggableOn.force_parameterize = true
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
If you would like tags to be case-sensitive and not use LIKE queries for creation:
|
|
344
|
+
|
|
345
|
+
```ruby
|
|
346
|
+
ActsAsTaggableOn.strict_case_match = true
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
If you want to change the default delimiter (it defaults to ','). You can also pass in an array of delimiters such as ([',', '|']):
|
|
350
|
+
|
|
351
|
+
```ruby
|
|
352
|
+
ActsAsTaggableOn.delimiter = ','
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
*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)*
|
|
356
|
+
|
|
357
|
+
## Contributors
|
|
358
|
+
|
|
359
|
+
We have a long list of valued contributors. [Check them all](https://github.com/mbleigh/acts-as-taggable-on/contributors)
|
|
360
|
+
|
|
361
|
+
## Maintainer
|
|
362
|
+
|
|
363
|
+
* [Joost Baaij](https://github.com/tilsammans)
|
|
364
|
+
|
|
365
|
+
## TODO
|
|
366
|
+
|
|
367
|
+
- Write benchmark script
|
|
368
|
+
- Resolve concurrency issues
|
|
369
|
+
|
|
370
|
+
## Testing
|
|
371
|
+
|
|
372
|
+
Acts As Taggable On uses RSpec for its test coverage. Inside the gem
|
|
373
|
+
directory, you can run the specs with:
|
|
374
|
+
|
|
375
|
+
```shell
|
|
376
|
+
bundle
|
|
377
|
+
rake spec
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
You can run all the tests across all the Rails versions by running `rake appraise`. If you'd also like to [run the tests across all rubies and databases as configured for Travis CI, install and run `wwtd`](https://github.com/grosser/wwtd).
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
## License
|
|
384
|
+
|
|
385
|
+
See [LICENSE](https://github.com/mbleigh/acts-as-taggable-on/blob/master/LICENSE.md)
|