sb-acts-as-taggable-on 6.5.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 (87) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +39 -0
  5. data/Appraisals +15 -0
  6. data/CHANGELOG.md +330 -0
  7. data/CONTRIBUTING.md +57 -0
  8. data/Gemfile +11 -0
  9. data/Guardfile +5 -0
  10. data/LICENSE.md +20 -0
  11. data/README.md +555 -0
  12. data/Rakefile +21 -0
  13. data/UPGRADING.md +8 -0
  14. data/acts-as-taggable-on.gemspec +32 -0
  15. data/db/migrate/1_acts_as_taggable_on_migration.rb +36 -0
  16. data/db/migrate/2_add_missing_unique_indices.rb +25 -0
  17. data/db/migrate/3_add_taggings_counter_cache_to_tags.rb +19 -0
  18. data/db/migrate/4_add_missing_taggable_index.rb +14 -0
  19. data/db/migrate/5_change_collation_for_tag_names.rb +14 -0
  20. data/db/migrate/6_add_missing_indexes_on_taggings.rb +22 -0
  21. data/gemfiles/activerecord_5.0.gemfile +21 -0
  22. data/gemfiles/activerecord_5.1.gemfile +21 -0
  23. data/gemfiles/activerecord_5.2.gemfile +21 -0
  24. data/gemfiles/activerecord_6.0.gemfile +21 -0
  25. data/lib/acts-as-taggable-on.rb +133 -0
  26. data/lib/acts_as_taggable_on.rb +6 -0
  27. data/lib/acts_as_taggable_on/default_parser.rb +79 -0
  28. data/lib/acts_as_taggable_on/engine.rb +4 -0
  29. data/lib/acts_as_taggable_on/generic_parser.rb +19 -0
  30. data/lib/acts_as_taggable_on/tag.rb +139 -0
  31. data/lib/acts_as_taggable_on/tag_list.rb +106 -0
  32. data/lib/acts_as_taggable_on/taggable.rb +101 -0
  33. data/lib/acts_as_taggable_on/taggable/cache.rb +90 -0
  34. data/lib/acts_as_taggable_on/taggable/collection.rb +183 -0
  35. data/lib/acts_as_taggable_on/taggable/core.rb +322 -0
  36. data/lib/acts_as_taggable_on/taggable/ownership.rb +136 -0
  37. data/lib/acts_as_taggable_on/taggable/related.rb +71 -0
  38. data/lib/acts_as_taggable_on/taggable/tag_list_type.rb +4 -0
  39. data/lib/acts_as_taggable_on/taggable/tagged_with_query.rb +16 -0
  40. data/lib/acts_as_taggable_on/taggable/tagged_with_query/all_tags_query.rb +111 -0
  41. data/lib/acts_as_taggable_on/taggable/tagged_with_query/any_tags_query.rb +70 -0
  42. data/lib/acts_as_taggable_on/taggable/tagged_with_query/exclude_tags_query.rb +82 -0
  43. data/lib/acts_as_taggable_on/taggable/tagged_with_query/query_base.rb +61 -0
  44. data/lib/acts_as_taggable_on/tagger.rb +89 -0
  45. data/lib/acts_as_taggable_on/tagging.rb +36 -0
  46. data/lib/acts_as_taggable_on/tags_helper.rb +15 -0
  47. data/lib/acts_as_taggable_on/utils.rb +37 -0
  48. data/lib/acts_as_taggable_on/version.rb +3 -0
  49. data/lib/tasks/tags_collate_utf8.rake +21 -0
  50. data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +285 -0
  51. data/spec/acts_as_taggable_on/acts_as_tagger_spec.rb +112 -0
  52. data/spec/acts_as_taggable_on/caching_spec.rb +129 -0
  53. data/spec/acts_as_taggable_on/default_parser_spec.rb +47 -0
  54. data/spec/acts_as_taggable_on/dirty_spec.rb +142 -0
  55. data/spec/acts_as_taggable_on/generic_parser_spec.rb +14 -0
  56. data/spec/acts_as_taggable_on/related_spec.rb +99 -0
  57. data/spec/acts_as_taggable_on/single_table_inheritance_spec.rb +231 -0
  58. data/spec/acts_as_taggable_on/tag_list_spec.rb +176 -0
  59. data/spec/acts_as_taggable_on/tag_spec.rb +340 -0
  60. data/spec/acts_as_taggable_on/taggable_spec.rb +817 -0
  61. data/spec/acts_as_taggable_on/tagger_spec.rb +153 -0
  62. data/spec/acts_as_taggable_on/tagging_spec.rb +117 -0
  63. data/spec/acts_as_taggable_on/tags_helper_spec.rb +45 -0
  64. data/spec/acts_as_taggable_on/utils_spec.rb +23 -0
  65. data/spec/internal/app/models/altered_inheriting_taggable_model.rb +5 -0
  66. data/spec/internal/app/models/cached_model.rb +3 -0
  67. data/spec/internal/app/models/cached_model_with_array.rb +11 -0
  68. data/spec/internal/app/models/columns_override_model.rb +5 -0
  69. data/spec/internal/app/models/company.rb +15 -0
  70. data/spec/internal/app/models/inheriting_taggable_model.rb +4 -0
  71. data/spec/internal/app/models/market.rb +2 -0
  72. data/spec/internal/app/models/non_standard_id_taggable_model.rb +8 -0
  73. data/spec/internal/app/models/ordered_taggable_model.rb +4 -0
  74. data/spec/internal/app/models/other_cached_model.rb +3 -0
  75. data/spec/internal/app/models/other_taggable_model.rb +4 -0
  76. data/spec/internal/app/models/student.rb +4 -0
  77. data/spec/internal/app/models/taggable_model.rb +14 -0
  78. data/spec/internal/app/models/untaggable_model.rb +3 -0
  79. data/spec/internal/app/models/user.rb +3 -0
  80. data/spec/internal/config/database.yml.sample +19 -0
  81. data/spec/internal/db/schema.rb +110 -0
  82. data/spec/spec_helper.rb +20 -0
  83. data/spec/support/0-helpers.rb +32 -0
  84. data/spec/support/array.rb +9 -0
  85. data/spec/support/database.rb +36 -0
  86. data/spec/support/database_cleaner.rb +21 -0
  87. metadata +269 -0
@@ -0,0 +1,153 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe 'Tagger' do
5
+ before(:each) do
6
+ @user = User.create
7
+ @taggable = TaggableModel.create(name: 'Bob Jones')
8
+ end
9
+
10
+
11
+
12
+ it 'should have taggings' do
13
+ @user.tag(@taggable, with: 'ruby,scheme', on: :tags)
14
+ expect(@user.owned_taggings.size).to eq(2)
15
+ end
16
+
17
+ it 'should have tags' do
18
+ @user.tag(@taggable, with: 'ruby,scheme', on: :tags)
19
+ expect(@user.owned_tags.size).to eq(2)
20
+ end
21
+
22
+ it 'should scope objects returned by tagged_with by owners' do
23
+ @taggable2 = TaggableModel.create(name: 'Jim Jones')
24
+ @taggable3 = TaggableModel.create(name: 'Jane Doe')
25
+
26
+ @user2 = User.new
27
+ @user.tag(@taggable, with: 'ruby, scheme', on: :tags)
28
+ @user2.tag(@taggable2, with: 'ruby, scheme', on: :tags)
29
+ @user2.tag(@taggable3, with: 'ruby, scheme', on: :tags)
30
+
31
+ expect(TaggableModel.tagged_with(%w(ruby scheme), owned_by: @user).count).to eq(1)
32
+ expect(TaggableModel.tagged_with(%w(ruby scheme), owned_by: @user2).count).to eq(2)
33
+ end
34
+
35
+ it 'only returns objects tagged by owned_by when any is true' do
36
+ @user2 = User.new
37
+ @taggable2 = TaggableModel.create(name: 'Jim Jones')
38
+ @taggable3 = TaggableModel.create(name: 'Jane Doe')
39
+
40
+ @user.tag(@taggable, with: 'ruby', on: :tags)
41
+ @user.tag(@taggable2, with: 'java', on: :tags)
42
+ @user2.tag(@taggable3, with: 'ruby', on: :tags)
43
+
44
+ tags = TaggableModel.tagged_with(%w(ruby java), owned_by: @user, any: true)
45
+ expect(tags).to include(@taggable, @taggable2)
46
+ expect(tags.size).to eq(2)
47
+ end
48
+
49
+ it 'only returns objects tagged by owned_by when exclude is true' do
50
+ @user2 = User.new
51
+ @taggable2 = TaggableModel.create(name: 'Jim Jones')
52
+ @taggable3 = TaggableModel.create(name: 'Jane Doe')
53
+
54
+ @user.tag(@taggable, with: 'ruby', on: :tags)
55
+ @user.tag(@taggable2, with: 'java', on: :tags)
56
+ @user2.tag(@taggable3, with: 'java', on: :tags)
57
+
58
+ tags = TaggableModel.tagged_with(%w(ruby), owned_by: @user, exclude: true)
59
+ expect(tags).to eq([@taggable2])
60
+ end
61
+
62
+ it 'should not overlap tags from different taggers' do
63
+ @user2 = User.new
64
+ expect(-> {
65
+ @user.tag(@taggable, with: 'ruby, scheme', on: :tags)
66
+ @user2.tag(@taggable, with: 'java, python, lisp, ruby', on: :tags)
67
+ }).to change(ActsAsTaggableOn::Tagging, :count).by(6)
68
+
69
+ [@user, @user2, @taggable].each(&:reload)
70
+
71
+ expect(@user.owned_tags.map(&:name).sort).to eq(%w(ruby scheme).sort)
72
+ expect(@user2.owned_tags.map(&:name).sort).to eq(%w(java python lisp ruby).sort)
73
+
74
+ expect(@taggable.tags_from(@user).sort).to eq(%w(ruby scheme).sort)
75
+ expect(@taggable.tags_from(@user2).sort).to eq(%w(java lisp python ruby).sort)
76
+
77
+ expect(@taggable.all_tags_list.sort).to eq(%w(ruby scheme java python lisp).sort)
78
+ expect(@taggable.all_tags_on(:tags).size).to eq(5)
79
+ end
80
+
81
+ it 'should not lose tags from different taggers' do
82
+ @user2 = User.create
83
+ @user2.tag(@taggable, with: 'java, python, lisp, ruby', on: :tags)
84
+ @user.tag(@taggable, with: 'ruby, scheme', on: :tags)
85
+
86
+ expect(-> {
87
+ @user2.tag(@taggable, with: 'java, python, lisp', on: :tags)
88
+ }).to change(ActsAsTaggableOn::Tagging, :count).by(-1)
89
+
90
+ [@user, @user2, @taggable].each(&:reload)
91
+
92
+ expect(@taggable.tags_from(@user).sort).to eq(%w(ruby scheme).sort)
93
+ expect(@taggable.tags_from(@user2).sort).to eq(%w(java python lisp).sort)
94
+
95
+ expect(@taggable.all_tags_list.sort).to eq(%w(ruby scheme java python lisp).sort)
96
+ expect(@taggable.all_tags_on(:tags).length).to eq(5)
97
+ end
98
+
99
+ it 'should not lose tags' do
100
+ @user2 = User.create
101
+
102
+ @user.tag(@taggable, with: 'awesome', on: :tags)
103
+ @user2.tag(@taggable, with: 'awesome, epic', on: :tags)
104
+
105
+ expect(-> {
106
+ @user2.tag(@taggable, with: 'epic', on: :tags)
107
+ }).to change(ActsAsTaggableOn::Tagging, :count).by(-1)
108
+
109
+ @taggable.reload
110
+ expect(@taggable.all_tags_list).to include('awesome')
111
+ expect(@taggable.all_tags_list).to include('epic')
112
+ end
113
+
114
+ it 'should not lose tags' do
115
+ @taggable.update(tag_list: 'ruby')
116
+ @user.tag(@taggable, with: 'ruby, scheme', on: :tags)
117
+
118
+ [@taggable, @user].each(&:reload)
119
+ expect(@taggable.tag_list).to eq(%w(ruby))
120
+ expect(@taggable.all_tags_list.sort).to eq(%w(ruby scheme).sort)
121
+
122
+ expect(-> {
123
+ @taggable.update(tag_list: '')
124
+ }).to change(ActsAsTaggableOn::Tagging, :count).by(-1)
125
+
126
+ expect(@taggable.tag_list).to be_empty
127
+ expect(@taggable.all_tags_list.sort).to eq(%w(ruby scheme).sort)
128
+ end
129
+
130
+ it 'is tagger' do
131
+ expect(@user.is_tagger?).to be_truthy
132
+ end
133
+
134
+ it 'should skip save if skip_save is passed as option' do
135
+ expect(-> {
136
+ @user.tag(@taggable, with: 'epic', on: :tags, skip_save: true)
137
+ }).to_not change(ActsAsTaggableOn::Tagging, :count)
138
+ end
139
+
140
+ it 'should change tags order in ordered taggable' do
141
+ @ordered_taggable = OrderedTaggableModel.create name: 'hey!'
142
+
143
+ @user.tag @ordered_taggable, with: 'tag, tag1', on: :tags
144
+ expect(@ordered_taggable.reload.tags_from(@user)).to eq(['tag', 'tag1'])
145
+
146
+ @user.tag @ordered_taggable, with: 'tag2, tag1', on: :tags
147
+ expect(@ordered_taggable.reload.tags_from(@user)).to eq(['tag2', 'tag1'])
148
+
149
+ @user.tag @ordered_taggable, with: 'tag1, tag2', on: :tags
150
+ expect(@ordered_taggable.reload.tags_from(@user)).to eq(['tag1', 'tag2'])
151
+ end
152
+
153
+ end
@@ -0,0 +1,117 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe ActsAsTaggableOn::Tagging do
5
+ before(:each) do
6
+ @tagging = ActsAsTaggableOn::Tagging.new
7
+ end
8
+
9
+ it 'should not be valid with a invalid tag' do
10
+ @tagging.taggable = TaggableModel.create(name: 'Bob Jones')
11
+ @tagging.tag = ActsAsTaggableOn::Tag.new(name: '')
12
+ @tagging.context = 'tags'
13
+
14
+ expect(@tagging).to_not be_valid
15
+
16
+ expect(@tagging.errors[:tag_id]).to eq(['can\'t be blank'])
17
+ end
18
+
19
+ it 'should not create duplicate taggings' do
20
+ @taggable = TaggableModel.create(name: 'Bob Jones')
21
+ @tag = ActsAsTaggableOn::Tag.create(name: 'awesome')
22
+
23
+ expect(-> {
24
+ 2.times { ActsAsTaggableOn::Tagging.create(taggable: @taggable, tag: @tag, context: 'tags') }
25
+ }).to change(ActsAsTaggableOn::Tagging, :count).by(1)
26
+ end
27
+
28
+ it 'should not delete tags of other records' do
29
+ 6.times { TaggableModel.create(name: 'Bob Jones', tag_list: 'very, serious, bug') }
30
+ expect(ActsAsTaggableOn::Tag.count).to eq(3)
31
+ taggable = TaggableModel.first
32
+ taggable.tag_list = 'bug'
33
+ taggable.save
34
+
35
+ expect(taggable.tag_list).to eq(['bug'])
36
+
37
+ another_taggable = TaggableModel.where('id != ?', taggable.id).sample
38
+ expect(another_taggable.tag_list.sort).to eq(%w(very serious bug).sort)
39
+ end
40
+
41
+ it 'should destroy unused tags after tagging destroyed' do
42
+ previous_setting = ActsAsTaggableOn.remove_unused_tags
43
+ ActsAsTaggableOn.remove_unused_tags = true
44
+ ActsAsTaggableOn::Tag.destroy_all
45
+ @taggable = TaggableModel.create(name: 'Bob Jones')
46
+ @taggable.update_attribute :tag_list, 'aaa,bbb,ccc'
47
+ @taggable.update_attribute :tag_list, ''
48
+ expect(ActsAsTaggableOn::Tag.count).to eql(0)
49
+ ActsAsTaggableOn.remove_unused_tags = previous_setting
50
+ end
51
+
52
+ describe 'context scopes' do
53
+ before do
54
+ @tagging_2 = ActsAsTaggableOn::Tagging.new
55
+ @tagging_3 = ActsAsTaggableOn::Tagging.new
56
+
57
+ @tagger = User.new
58
+ @tagger_2 = User.new
59
+
60
+ @tagging.taggable = TaggableModel.create(name: "Black holes")
61
+ @tagging.tag = ActsAsTaggableOn::Tag.create(name: "Physics")
62
+ @tagging.tagger = @tagger
63
+ @tagging.context = 'Science'
64
+ @tagging.save
65
+
66
+ @tagging_2.taggable = TaggableModel.create(name: "Satellites")
67
+ @tagging_2.tag = ActsAsTaggableOn::Tag.create(name: "Technology")
68
+ @tagging_2.tagger = @tagger_2
69
+ @tagging_2.context = 'Science'
70
+ @tagging_2.save
71
+
72
+ @tagging_3.taggable = TaggableModel.create(name: "Satellites")
73
+ @tagging_3.tag = ActsAsTaggableOn::Tag.create(name: "Engineering")
74
+ @tagging_3.tagger = @tagger_2
75
+ @tagging_3.context = 'Astronomy'
76
+ @tagging_3.save
77
+
78
+ end
79
+
80
+ describe '.owned_by' do
81
+ it "should belong to a specific user" do
82
+ expect(ActsAsTaggableOn::Tagging.owned_by(@tagger).first).to eq(@tagging)
83
+ end
84
+ end
85
+
86
+ describe '.by_context' do
87
+ it "should be found by context" do
88
+ expect(ActsAsTaggableOn::Tagging.by_context('Science').length).to eq(2);
89
+ end
90
+ end
91
+
92
+ describe '.by_contexts' do
93
+ it "should find taggings by contexts" do
94
+ expect(ActsAsTaggableOn::Tagging.by_contexts(['Science', 'Astronomy']).first).to eq(@tagging);
95
+ expect(ActsAsTaggableOn::Tagging.by_contexts(['Science', 'Astronomy']).second).to eq(@tagging_2);
96
+ expect(ActsAsTaggableOn::Tagging.by_contexts(['Science', 'Astronomy']).third).to eq(@tagging_3);
97
+ expect(ActsAsTaggableOn::Tagging.by_contexts(['Science', 'Astronomy']).length).to eq(3);
98
+ end
99
+ end
100
+
101
+ describe '.not_owned' do
102
+ before do
103
+ @tagging_4 = ActsAsTaggableOn::Tagging.new
104
+ @tagging_4.taggable = TaggableModel.create(name: "Gravity")
105
+ @tagging_4.tag = ActsAsTaggableOn::Tag.create(name: "Space")
106
+ @tagging_4.context = "Science"
107
+ @tagging_4.save
108
+ end
109
+
110
+ it "should found the taggings that do not have owner" do
111
+ expect(ActsAsTaggableOn::Tagging.all.length).to eq(4)
112
+ expect(ActsAsTaggableOn::Tagging.not_owned.length).to eq(1)
113
+ expect(ActsAsTaggableOn::Tagging.not_owned.first).to eq(@tagging_4)
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,45 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe ActsAsTaggableOn::TagsHelper do
5
+ before(:each) do
6
+ @bob = TaggableModel.create(name: 'Bob Jones', language_list: 'ruby, php')
7
+ @tom = TaggableModel.create(name: 'Tom Marley', language_list: 'ruby, java')
8
+ @eve = TaggableModel.create(name: 'Eve Nodd', language_list: 'ruby, c++')
9
+
10
+ @helper =
11
+ class Helper
12
+ include ActsAsTaggableOn::TagsHelper
13
+ end.new
14
+ end
15
+
16
+
17
+ it 'should yield the proper css classes' do
18
+ tags = {}
19
+
20
+ @helper.tag_cloud(TaggableModel.tag_counts_on(:languages), %w(sucky awesome)) do |tag, css_class|
21
+ tags[tag.name] = css_class
22
+ end
23
+
24
+ expect(tags['ruby']).to eq('awesome')
25
+ expect(tags['java']).to eq('sucky')
26
+ expect(tags['c++']).to eq('sucky')
27
+ expect(tags['php']).to eq('sucky')
28
+ end
29
+
30
+ it 'should handle tags with zero counts (build for empty)' do
31
+ ActsAsTaggableOn::Tag.create(name: 'php')
32
+ ActsAsTaggableOn::Tag.create(name: 'java')
33
+ ActsAsTaggableOn::Tag.create(name: 'c++')
34
+
35
+ tags = {}
36
+
37
+ @helper.tag_cloud(ActsAsTaggableOn::Tag.all, %w(sucky awesome)) do |tag, css_class|
38
+ tags[tag.name] = css_class
39
+ end
40
+
41
+ expect(tags['java']).to eq('sucky')
42
+ expect(tags['c++']).to eq('sucky')
43
+ expect(tags['php']).to eq('sucky')
44
+ end
45
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe ActsAsTaggableOn::Utils do
5
+ describe '#like_operator' do
6
+ it 'should return \'ILIKE\' when the adapter is PostgreSQL' do
7
+ allow(ActsAsTaggableOn::Utils.connection).to receive(:adapter_name) { 'PostgreSQL' }
8
+ expect(ActsAsTaggableOn::Utils.like_operator).to eq('ILIKE')
9
+ end
10
+
11
+ it 'should return \'LIKE\' when the adapter is not PostgreSQL' do
12
+ allow(ActsAsTaggableOn::Utils.connection).to receive(:adapter_name) { 'MySQL' }
13
+ expect(ActsAsTaggableOn::Utils.like_operator).to eq('LIKE')
14
+ end
15
+ end
16
+
17
+ describe '#sha_prefix' do
18
+ it 'should return a consistent prefix for a given word' do
19
+ expect(ActsAsTaggableOn::Utils.sha_prefix('kittens')).to eq(ActsAsTaggableOn::Utils.sha_prefix('kittens'))
20
+ expect(ActsAsTaggableOn::Utils.sha_prefix('puppies')).not_to eq(ActsAsTaggableOn::Utils.sha_prefix('kittens'))
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,5 @@
1
+ require_relative 'taggable_model'
2
+
3
+ class AlteredInheritingTaggableModel < TaggableModel
4
+ acts_as_taggable_on :parts
5
+ end
@@ -0,0 +1,3 @@
1
+ class CachedModel < ActiveRecord::Base
2
+ acts_as_taggable
3
+ end
@@ -0,0 +1,11 @@
1
+ if using_postgresql?
2
+ class CachedModelWithArray < ActiveRecord::Base
3
+ acts_as_taggable
4
+ end
5
+ if postgresql_support_json?
6
+ class TaggableModelWithJson < ActiveRecord::Base
7
+ acts_as_taggable
8
+ acts_as_taggable_on :skills
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ class ColumnsOverrideModel < ActiveRecord::Base
2
+ def self.columns
3
+ super.reject { |c| c.name == 'ignored_column' }
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ class Company < ActiveRecord::Base
2
+ acts_as_taggable_on :locations, :markets
3
+
4
+ has_many :markets, :through => :market_taggings, :source => :tag
5
+
6
+ private
7
+
8
+ def find_or_create_tags_from_list_with_context(tag_list, context)
9
+ if context.to_sym == :markets
10
+ Market.find_or_create_all_with_like_by_name(tag_list)
11
+ else
12
+ super
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ require_relative 'taggable_model'
2
+
3
+ class InheritingTaggableModel < TaggableModel
4
+ end
@@ -0,0 +1,2 @@
1
+ class Market < ActsAsTaggableOn::Tag
2
+ end
@@ -0,0 +1,8 @@
1
+ class NonStandardIdTaggableModel < ActiveRecord::Base
2
+ self.primary_key = :an_id
3
+ acts_as_taggable
4
+ acts_as_taggable_on :languages
5
+ acts_as_taggable_on :skills
6
+ acts_as_taggable_on :needs, :offerings
7
+ has_many :untaggable_models
8
+ end
@@ -0,0 +1,4 @@
1
+ class OrderedTaggableModel < ActiveRecord::Base
2
+ acts_as_ordered_taggable
3
+ acts_as_ordered_taggable_on :colours
4
+ end
@@ -0,0 +1,3 @@
1
+ class OtherCachedModel < ActiveRecord::Base
2
+ acts_as_taggable_on :languages, :statuses, :glasses
3
+ end
@@ -0,0 +1,4 @@
1
+ class OtherTaggableModel < ActiveRecord::Base
2
+ acts_as_taggable_on :tags, :languages
3
+ acts_as_taggable_on :needs, :offerings
4
+ end
@@ -0,0 +1,4 @@
1
+ require_relative 'user'
2
+
3
+ class Student < User
4
+ end
@@ -0,0 +1,14 @@
1
+ class TaggableModel < ActiveRecord::Base
2
+ acts_as_taggable
3
+ acts_as_taggable_on :languages
4
+ acts_as_taggable_on :skills
5
+ acts_as_taggable_on :needs, :offerings
6
+ has_many :untaggable_models
7
+
8
+ attr_reader :tag_list_submethod_called
9
+
10
+ def tag_list=(v)
11
+ @tag_list_submethod_called = true
12
+ super
13
+ end
14
+ end