acts-as-taggable-on 3.1.1 → 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 +4 -4
- data/.gitignore +1 -1
- data/.travis.yml +9 -7
- data/Appraisals +13 -8
- data/CHANGELOG.md +27 -7
- data/Gemfile +1 -2
- data/README.md +36 -19
- data/Rakefile +5 -17
- data/UPGRADING.md +6 -0
- data/acts-as-taggable-on.gemspec +15 -15
- data/db/migrate/1_acts_as_taggable_on_migration.rb +3 -3
- data/db/migrate/2_add_missing_unique_indices.rb +3 -5
- data/db/migrate/3_add_taggings_counter_cache_to_tags.rb +1 -1
- 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 +23 -21
- data/lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb +2 -4
- data/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb +29 -20
- data/lib/acts_as_taggable_on/acts_as_taggable_on/compatibility.rb +11 -10
- data/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb +103 -85
- data/lib/acts_as_taggable_on/acts_as_taggable_on/ownership.rb +5 -12
- data/lib/acts_as_taggable_on/acts_as_taggable_on/related.rb +11 -11
- data/lib/acts_as_taggable_on/engine.rb +0 -1
- data/lib/acts_as_taggable_on/tag.rb +24 -19
- data/lib/acts_as_taggable_on/tag_list.rb +97 -22
- data/lib/acts_as_taggable_on/taggable.rb +26 -30
- data/lib/acts_as_taggable_on/tagger.rb +30 -18
- data/lib/acts_as_taggable_on/tagging.rb +7 -8
- data/lib/acts_as_taggable_on/tags_helper.rb +1 -1
- data/lib/acts_as_taggable_on/utils.rb +57 -35
- data/lib/acts_as_taggable_on/version.rb +1 -1
- data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +133 -138
- data/spec/acts_as_taggable_on/acts_as_tagger_spec.rb +55 -58
- data/spec/acts_as_taggable_on/caching_spec.rb +34 -35
- data/spec/acts_as_taggable_on/related_spec.rb +59 -113
- data/spec/acts_as_taggable_on/single_table_inheritance_spec.rb +118 -95
- data/spec/acts_as_taggable_on/tag_list_spec.rb +89 -57
- data/spec/acts_as_taggable_on/tag_spec.rb +129 -116
- data/spec/acts_as_taggable_on/taggable_spec.rb +539 -352
- data/spec/acts_as_taggable_on/tagger_spec.rb +81 -78
- data/spec/acts_as_taggable_on/tagging_spec.rb +13 -14
- data/spec/acts_as_taggable_on/tags_helper_spec.rb +25 -25
- data/spec/acts_as_taggable_on/utils_spec.rb +7 -13
- 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/{models.rb → internal/app/models/models.rb} +34 -2
- 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/{database.yml.sample → internal/config/database.yml.sample} +2 -2
- data/spec/internal/db/schema.rb +97 -0
- data/spec/schema.rb +11 -0
- data/spec/spec_helper.rb +9 -62
- data/spec/support/array.rb +9 -0
- data/spec/support/database.rb +42 -0
- data/spec/support/database_cleaner.rb +21 -0
- metadata +105 -43
- data/gemfiles/rails_3.2.gemfile +0 -7
- data/gemfiles/rails_4.0.gemfile +0 -7
- data/gemfiles/rails_4.1.gemfile +0 -7
- data/gemfiles/rails_edge.gemfile +0 -7
- data/spec/bm.rb +0 -52
|
@@ -1,77 +1,76 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
|
-
describe
|
|
4
|
-
|
|
5
|
-
before(:each) do
|
|
6
|
-
clean_database!
|
|
7
|
-
end
|
|
3
|
+
describe 'Acts As Taggable On' do
|
|
8
4
|
|
|
9
5
|
describe 'Caching' do
|
|
10
6
|
before(:each) do
|
|
11
|
-
@taggable = CachedModel.new(:
|
|
12
|
-
@another_taggable = OtherCachedModel.new(:
|
|
7
|
+
@taggable = CachedModel.new(name: 'Bob Jones')
|
|
8
|
+
@another_taggable = OtherCachedModel.new(name: 'John Smith')
|
|
13
9
|
end
|
|
14
10
|
|
|
15
|
-
it
|
|
16
|
-
@taggable.
|
|
17
|
-
@another_taggable.
|
|
11
|
+
it 'should add saving of tag lists and cached tag lists to the instance' do
|
|
12
|
+
expect(@taggable).to respond_to(:save_cached_tag_list)
|
|
13
|
+
expect(@another_taggable).to respond_to(:save_cached_tag_list)
|
|
18
14
|
|
|
19
|
-
@taggable.
|
|
15
|
+
expect(@taggable).to respond_to(:save_tags)
|
|
20
16
|
end
|
|
21
17
|
|
|
22
|
-
it
|
|
23
|
-
TaggableModel.new(:
|
|
18
|
+
it 'should add cached tag lists to the instance if cached column is not present' do
|
|
19
|
+
expect(TaggableModel.new(name: 'Art Kram')).to_not respond_to(:save_cached_tag_list)
|
|
24
20
|
end
|
|
25
21
|
|
|
26
|
-
it
|
|
27
|
-
CachedModel.
|
|
28
|
-
OtherCachedModel.
|
|
22
|
+
it 'should generate a cached column checker for each tag type' do
|
|
23
|
+
expect(CachedModel).to respond_to(:caching_tag_list?)
|
|
24
|
+
expect(OtherCachedModel).to respond_to(:caching_language_list?)
|
|
29
25
|
end
|
|
30
26
|
|
|
31
27
|
it 'should not have cached tags' do
|
|
32
|
-
@taggable.cached_tag_list.
|
|
33
|
-
@another_taggable.cached_language_list.
|
|
28
|
+
expect(@taggable.cached_tag_list).to be_blank
|
|
29
|
+
expect(@another_taggable.cached_language_list).to be_blank
|
|
34
30
|
end
|
|
35
31
|
|
|
36
32
|
it 'should cache tags' do
|
|
37
|
-
@taggable.update_attributes(:
|
|
38
|
-
@taggable.cached_tag_list.
|
|
33
|
+
@taggable.update_attributes(tag_list: 'awesome, epic')
|
|
34
|
+
expect(@taggable.cached_tag_list).to eq('awesome, epic')
|
|
39
35
|
|
|
40
|
-
@another_taggable.update_attributes(:
|
|
41
|
-
@another_taggable.cached_language_list.
|
|
36
|
+
@another_taggable.update_attributes(language_list: 'ruby, .net')
|
|
37
|
+
expect(@another_taggable.cached_language_list).to eq('ruby, .net')
|
|
42
38
|
end
|
|
43
39
|
|
|
44
40
|
it 'should keep the cache' do
|
|
45
|
-
@taggable.update_attributes(:
|
|
46
|
-
@taggable = CachedModel.find(@taggable)
|
|
41
|
+
@taggable.update_attributes(tag_list: 'awesome, epic')
|
|
42
|
+
@taggable = CachedModel.find(@taggable.id)
|
|
47
43
|
@taggable.save!
|
|
48
|
-
@taggable.cached_tag_list.
|
|
44
|
+
expect(@taggable.cached_tag_list).to eq('awesome, epic')
|
|
49
45
|
end
|
|
50
46
|
|
|
51
47
|
it 'should update the cache' do
|
|
52
|
-
@taggable.update_attributes(:
|
|
53
|
-
@taggable.update_attributes(:
|
|
54
|
-
@taggable.cached_tag_list.
|
|
48
|
+
@taggable.update_attributes(tag_list: 'awesome, epic')
|
|
49
|
+
@taggable.update_attributes(tag_list: 'awesome')
|
|
50
|
+
expect(@taggable.cached_tag_list).to eq('awesome')
|
|
55
51
|
end
|
|
56
52
|
|
|
57
53
|
it 'should remove the cache' do
|
|
58
|
-
@taggable.update_attributes(:
|
|
59
|
-
@taggable.update_attributes(:
|
|
60
|
-
@taggable.cached_tag_list.
|
|
54
|
+
@taggable.update_attributes(tag_list: 'awesome, epic')
|
|
55
|
+
@taggable.update_attributes(tag_list: '')
|
|
56
|
+
expect(@taggable.cached_tag_list).to be_blank
|
|
61
57
|
end
|
|
62
58
|
|
|
63
59
|
it 'should have a tag list' do
|
|
64
|
-
@taggable.update_attributes(:
|
|
60
|
+
@taggable.update_attributes(tag_list: 'awesome, epic')
|
|
65
61
|
@taggable = CachedModel.find(@taggable.id)
|
|
66
|
-
@taggable.tag_list.sort.
|
|
62
|
+
expect(@taggable.tag_list.sort).to eq(%w(awesome epic).sort)
|
|
67
63
|
end
|
|
68
64
|
|
|
69
65
|
it 'should keep the tag list' do
|
|
70
|
-
@taggable.update_attributes(:
|
|
66
|
+
@taggable.update_attributes(tag_list: 'awesome, epic')
|
|
71
67
|
@taggable = CachedModel.find(@taggable.id)
|
|
72
68
|
@taggable.save!
|
|
73
|
-
@taggable.tag_list.sort.
|
|
69
|
+
expect(@taggable.tag_list.sort).to eq(%w(awesome epic).sort)
|
|
74
70
|
end
|
|
75
71
|
end
|
|
76
72
|
|
|
73
|
+
describe 'CachingWithArray' do
|
|
74
|
+
pending '#TODO'
|
|
75
|
+
end
|
|
77
76
|
end
|
|
@@ -1,143 +1,89 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
|
-
describe
|
|
4
|
-
before(:each) do
|
|
5
|
-
clean_database!
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
describe "Related Objects" do
|
|
9
|
-
it "should find related objects based on tag names on context" do
|
|
10
|
-
taggable1 = TaggableModel.create!(:name => "Taggable 1")
|
|
11
|
-
taggable2 = TaggableModel.create!(:name => "Taggable 2")
|
|
12
|
-
taggable3 = TaggableModel.create!(:name => "Taggable 3")
|
|
3
|
+
describe 'Acts As Taggable On' do
|
|
13
4
|
|
|
14
|
-
|
|
15
|
-
taggable1.save
|
|
5
|
+
describe 'Related Objects' do
|
|
16
6
|
|
|
17
|
-
|
|
18
|
-
|
|
7
|
+
#TODO, shared example
|
|
8
|
+
it 'should find related objects based on tag names on context' do
|
|
9
|
+
taggable1 = TaggableModel.create!(name: 'Taggable 1',tag_list: 'one, two')
|
|
10
|
+
taggable2 = TaggableModel.create!(name: 'Taggable 2',tag_list: 'three, four')
|
|
11
|
+
taggable3 = TaggableModel.create!(name: 'Taggable 3',tag_list: 'one, four')
|
|
19
12
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
taggable1.find_related_tags.should include(taggable3)
|
|
24
|
-
taggable1.find_related_tags.should_not include(taggable2)
|
|
13
|
+
expect(taggable1.find_related_tags).to include(taggable3)
|
|
14
|
+
expect(taggable1.find_related_tags).to_not include(taggable2)
|
|
25
15
|
end
|
|
26
16
|
|
|
27
|
-
it
|
|
28
|
-
taggable1 = OrderedTaggableModel.create!(:
|
|
29
|
-
taggable2 = OrderedTaggableModel.create!(:
|
|
30
|
-
taggable3 = OrderedTaggableModel.create!(:
|
|
31
|
-
|
|
32
|
-
taggable1.colour_list = "one, two"
|
|
33
|
-
taggable1.save
|
|
17
|
+
it 'finds related tags for ordered taggable on' do
|
|
18
|
+
taggable1 = OrderedTaggableModel.create!(name: 'Taggable 1',colour_list: 'one, two')
|
|
19
|
+
taggable2 = OrderedTaggableModel.create!(name: 'Taggable 2',colour_list: 'three, four')
|
|
20
|
+
taggable3 = OrderedTaggableModel.create!(name: 'Taggable 3',colour_list: 'one, four')
|
|
34
21
|
|
|
35
|
-
|
|
36
|
-
taggable2
|
|
37
|
-
|
|
38
|
-
taggable3.colour_list = "one, four"
|
|
39
|
-
taggable3.save
|
|
40
|
-
|
|
41
|
-
taggable1.find_related_colours.should include(taggable3)
|
|
42
|
-
taggable1.find_related_colours.should_not include(taggable2)
|
|
22
|
+
expect(taggable1.find_related_colours).to include(taggable3)
|
|
23
|
+
expect(taggable1.find_related_colours).to_not include(taggable2)
|
|
43
24
|
end
|
|
44
25
|
|
|
45
|
-
it
|
|
46
|
-
taggable1 = NonStandardIdTaggableModel.create!(:
|
|
47
|
-
taggable2 = NonStandardIdTaggableModel.create!(:
|
|
48
|
-
taggable3 = NonStandardIdTaggableModel.create!(:
|
|
49
|
-
|
|
50
|
-
taggable1.tag_list = "one, two"
|
|
51
|
-
taggable1.save
|
|
26
|
+
it 'should find related objects based on tag names on context - non standard id' do
|
|
27
|
+
taggable1 = NonStandardIdTaggableModel.create!(name: 'Taggable 1',tag_list: 'one, two')
|
|
28
|
+
taggable2 = NonStandardIdTaggableModel.create!(name: 'Taggable 2',tag_list: 'three, four')
|
|
29
|
+
taggable3 = NonStandardIdTaggableModel.create!(name: 'Taggable 3',tag_list: 'one, four')
|
|
52
30
|
|
|
53
|
-
|
|
54
|
-
taggable2
|
|
55
|
-
|
|
56
|
-
taggable3.tag_list = "one, four"
|
|
57
|
-
taggable3.save
|
|
58
|
-
|
|
59
|
-
taggable1.find_related_tags.should include(taggable3)
|
|
60
|
-
taggable1.find_related_tags.should_not include(taggable2)
|
|
31
|
+
expect(taggable1.find_related_tags).to include(taggable3)
|
|
32
|
+
expect(taggable1.find_related_tags).to_not include(taggable2)
|
|
61
33
|
end
|
|
62
34
|
|
|
63
|
-
it
|
|
64
|
-
taggable1 = TaggableModel.create!(:
|
|
65
|
-
taggable2 = OtherTaggableModel.create!(:
|
|
66
|
-
taggable3 = OtherTaggableModel.create!(:
|
|
35
|
+
it 'should find other related objects based on tag names on context' do
|
|
36
|
+
taggable1 = TaggableModel.create!(name: 'Taggable 1',tag_list: 'one, two')
|
|
37
|
+
taggable2 = OtherTaggableModel.create!(name: 'Taggable 2',tag_list: 'three, four')
|
|
38
|
+
taggable3 = OtherTaggableModel.create!(name: 'Taggable 3',tag_list: 'one, four')
|
|
67
39
|
|
|
68
|
-
taggable1.
|
|
69
|
-
taggable1.
|
|
40
|
+
expect(taggable1.find_related_tags_for(OtherTaggableModel)).to include(taggable3)
|
|
41
|
+
expect(taggable1.find_related_tags_for(OtherTaggableModel)).to_not include(taggable2)
|
|
42
|
+
end
|
|
70
43
|
|
|
71
|
-
taggable2.tag_list = "three, four"
|
|
72
|
-
taggable2.save
|
|
73
44
|
|
|
74
|
-
|
|
75
|
-
|
|
45
|
+
shared_examples "a collection" do
|
|
46
|
+
it do
|
|
47
|
+
taggable1 = described_class.create!(name: 'Taggable 1', tag_list: 'one')
|
|
48
|
+
taggable2 = described_class.create!(name: 'Taggable 2', tag_list: 'one, two')
|
|
76
49
|
|
|
77
|
-
|
|
78
|
-
|
|
50
|
+
expect(taggable1.find_related_tags).to include(taggable2)
|
|
51
|
+
expect(taggable1.find_related_tags).to_not include(taggable1)
|
|
52
|
+
end
|
|
79
53
|
end
|
|
80
54
|
|
|
81
|
-
it
|
|
82
|
-
|
|
83
|
-
|
|
55
|
+
# it 'should not include the object itself in the list of related objects' do
|
|
56
|
+
describe TaggableModel do
|
|
57
|
+
it_behaves_like "a collection"
|
|
58
|
+
end
|
|
84
59
|
|
|
85
|
-
|
|
86
|
-
|
|
60
|
+
# it 'should not include the object itself in the list of related objects - non standard id' do
|
|
61
|
+
describe NonStandardIdTaggableModel do
|
|
62
|
+
it_behaves_like "a collection"
|
|
63
|
+
end
|
|
87
64
|
|
|
88
|
-
|
|
89
|
-
|
|
65
|
+
context 'Ignored Tags' do
|
|
66
|
+
let(:taggable1) { TaggableModel.create!(name: 'Taggable 1', tag_list: 'one, two, four') }
|
|
67
|
+
let(:taggable2) { TaggableModel.create!(name: 'Taggable 2', tag_list: 'two, three') }
|
|
68
|
+
let(:taggable3) { TaggableModel.create!(name: 'Taggable 3', tag_list: 'one, three') }
|
|
90
69
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
70
|
+
it 'should not include ignored tags in related search' do
|
|
71
|
+
expect(taggable1.find_related_tags(ignore: 'two')).to_not include(taggable2)
|
|
72
|
+
expect(taggable1.find_related_tags(ignore: 'two')).to include(taggable3)
|
|
73
|
+
end
|
|
94
74
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
taggable2 = NonStandardIdTaggableModel.create!(:name => "Taggable 2")
|
|
75
|
+
it 'should accept array of ignored tags' do
|
|
76
|
+
taggable4 = TaggableModel.create!(name: 'Taggable 4', tag_list: 'four')
|
|
98
77
|
|
|
99
|
-
taggable1.tag_list = "one"
|
|
100
|
-
taggable1.save
|
|
101
78
|
|
|
102
|
-
|
|
103
|
-
|
|
79
|
+
expect(taggable1.find_related_tags(ignore: ['two', 'four'])).to_not include(taggable2)
|
|
80
|
+
expect(taggable1.find_related_tags(ignore: ['two', 'four'])).to_not include(taggable4)
|
|
81
|
+
end
|
|
104
82
|
|
|
105
|
-
|
|
106
|
-
|
|
83
|
+
it 'should accept symbols as ignored tags' do
|
|
84
|
+
expect(taggable1.find_related_tags(ignore: :two)).to_not include(taggable2)
|
|
85
|
+
end
|
|
107
86
|
end
|
|
108
87
|
|
|
109
|
-
context "Ignored Tags" do
|
|
110
|
-
let(:taggable1) { TaggableModel.create!(:name => "Taggable 1") }
|
|
111
|
-
let(:taggable2) { TaggableModel.create!(:name => "Taggable 2") }
|
|
112
|
-
let(:taggable3) { TaggableModel.create!(:name => "Taggable 3") }
|
|
113
|
-
before(:each) do
|
|
114
|
-
taggable1.tag_list = "one, two, four"
|
|
115
|
-
taggable1.save
|
|
116
|
-
|
|
117
|
-
taggable2.tag_list = "two, three"
|
|
118
|
-
taggable2.save
|
|
119
|
-
|
|
120
|
-
taggable3.tag_list = "one, three"
|
|
121
|
-
taggable3.save
|
|
122
|
-
end
|
|
123
|
-
it "should not include ignored tags in related search" do
|
|
124
|
-
taggable1.find_related_tags(:ignore => 'two').should_not include(taggable2)
|
|
125
|
-
taggable1.find_related_tags(:ignore => 'two').should include(taggable3)
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
it "should accept array of ignored tags" do
|
|
129
|
-
taggable4 = TaggableModel.create!(:name => "Taggable 4")
|
|
130
|
-
taggable4.tag_list = "four"
|
|
131
|
-
taggable4.save
|
|
132
|
-
|
|
133
|
-
taggable1.find_related_tags(:ignore => ['two', 'four']).should_not include(taggable2)
|
|
134
|
-
taggable1.find_related_tags(:ignore => ['two', 'four']).should_not include(taggable4)
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
it "should accept symbols as ignored tags" do
|
|
138
|
-
taggable1.find_related_tags(:ignore => :two).should_not include(taggable2)
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
|
|
142
88
|
end
|
|
143
89
|
end
|
|
@@ -1,149 +1,145 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
|
-
describe
|
|
3
|
+
describe 'Single Table Inheritance' do
|
|
4
|
+
let(:taggable) { TaggableModel.new(name: 'taggable model') }
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
let(:taggable) { TaggableModel.new(:name => "taggable model") }
|
|
10
|
-
|
|
11
|
-
let(:inheriting_model) { InheritingTaggableModel.new(:name => "Inheriting Taggable Model") }
|
|
12
|
-
let(:altered_inheriting) { AlteredInheritingTaggableModel.new(:name => "Altered Inheriting Model") }
|
|
6
|
+
let(:inheriting_model) { InheritingTaggableModel.new(name: 'Inheriting Taggable Model') }
|
|
7
|
+
let(:altered_inheriting) { AlteredInheritingTaggableModel.new(name: 'Altered Inheriting Model') }
|
|
13
8
|
|
|
14
9
|
1.upto(4) do |n|
|
|
15
|
-
let(:"inheriting_#{n}") { InheritingTaggableModel.new(:
|
|
10
|
+
let(:"inheriting_#{n}") { InheritingTaggableModel.new(name: "Inheriting Model #{n}") }
|
|
16
11
|
end
|
|
17
12
|
|
|
18
|
-
let(:student)
|
|
13
|
+
let(:student) { Student.create! }
|
|
19
14
|
|
|
20
|
-
describe
|
|
21
|
-
it
|
|
22
|
-
inheriting_model.
|
|
23
|
-
altered_inheriting.
|
|
15
|
+
describe 'tag contexts' do
|
|
16
|
+
it 'should pass on to STI-inherited models' do
|
|
17
|
+
expect(inheriting_model).to respond_to(:tag_list, :skill_list, :language_list)
|
|
18
|
+
expect(altered_inheriting).to respond_to(:tag_list, :skill_list, :language_list)
|
|
24
19
|
end
|
|
25
20
|
|
|
26
|
-
it
|
|
27
|
-
altered_inheriting.
|
|
21
|
+
it 'should pass on to altered STI models' do
|
|
22
|
+
expect(altered_inheriting).to respond_to(:part_list)
|
|
28
23
|
end
|
|
29
24
|
end
|
|
30
25
|
|
|
31
|
-
context
|
|
26
|
+
context 'matching contexts' do
|
|
32
27
|
|
|
33
28
|
before do
|
|
34
|
-
inheriting_1.offering_list =
|
|
35
|
-
inheriting_1.need_list =
|
|
29
|
+
inheriting_1.offering_list = 'one, two'
|
|
30
|
+
inheriting_1.need_list = 'one, two'
|
|
36
31
|
inheriting_1.save!
|
|
37
32
|
|
|
38
|
-
inheriting_2.need_list =
|
|
33
|
+
inheriting_2.need_list = 'one, two'
|
|
39
34
|
inheriting_2.save!
|
|
40
35
|
|
|
41
|
-
inheriting_3.offering_list =
|
|
36
|
+
inheriting_3.offering_list = 'one, two'
|
|
42
37
|
inheriting_3.save!
|
|
43
38
|
|
|
44
|
-
inheriting_4.tag_list =
|
|
39
|
+
inheriting_4.tag_list = 'one, two, three, four'
|
|
45
40
|
inheriting_4.save!
|
|
46
41
|
|
|
47
|
-
taggable.need_list =
|
|
42
|
+
taggable.need_list = 'one, two'
|
|
48
43
|
taggable.save!
|
|
49
44
|
end
|
|
50
45
|
|
|
51
|
-
it
|
|
52
|
-
inheriting_1.find_matching_contexts(:offerings, :needs).
|
|
53
|
-
inheriting_1.find_matching_contexts(:offerings, :needs).
|
|
54
|
-
inheriting_1.find_matching_contexts(:offerings, :needs).
|
|
55
|
-
inheriting_1.find_matching_contexts(:offerings, :needs).
|
|
46
|
+
it 'should find objects with tags of matching contexts' do
|
|
47
|
+
expect(inheriting_1.find_matching_contexts(:offerings, :needs)).to include(inheriting_2)
|
|
48
|
+
expect(inheriting_1.find_matching_contexts(:offerings, :needs)).to_not include(inheriting_3)
|
|
49
|
+
expect(inheriting_1.find_matching_contexts(:offerings, :needs)).to_not include(inheriting_4)
|
|
50
|
+
expect(inheriting_1.find_matching_contexts(:offerings, :needs)).to_not include(taggable)
|
|
56
51
|
|
|
57
|
-
inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs).
|
|
58
|
-
inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs).
|
|
59
|
-
inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs).
|
|
60
|
-
inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs).
|
|
52
|
+
expect(inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs)).to include(inheriting_2)
|
|
53
|
+
expect(inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs)).to_not include(inheriting_3)
|
|
54
|
+
expect(inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs)).to_not include(inheriting_4)
|
|
55
|
+
expect(inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs)).to include(taggable)
|
|
61
56
|
end
|
|
62
57
|
|
|
63
|
-
it
|
|
64
|
-
inheriting_1.find_matching_contexts(:offerings, :needs).
|
|
65
|
-
inheriting_1.find_matching_contexts_for(InheritingTaggableModel, :offerings, :needs).
|
|
66
|
-
inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs).
|
|
58
|
+
it 'should not include the object itself in the list of related objects with tags of matching contexts' do
|
|
59
|
+
expect(inheriting_1.find_matching_contexts(:offerings, :needs)).to_not include(inheriting_1)
|
|
60
|
+
expect(inheriting_1.find_matching_contexts_for(InheritingTaggableModel, :offerings, :needs)).to_not include(inheriting_1)
|
|
61
|
+
expect(inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs)).to_not include(inheriting_1)
|
|
67
62
|
end
|
|
68
63
|
end
|
|
69
64
|
|
|
70
|
-
context
|
|
65
|
+
context 'find related tags' do
|
|
71
66
|
before do
|
|
72
|
-
inheriting_1.tag_list =
|
|
67
|
+
inheriting_1.tag_list = 'one, two'
|
|
73
68
|
inheriting_1.save
|
|
74
69
|
|
|
75
|
-
inheriting_2.tag_list =
|
|
70
|
+
inheriting_2.tag_list = 'three, four'
|
|
76
71
|
inheriting_2.save
|
|
77
72
|
|
|
78
|
-
inheriting_3.tag_list =
|
|
73
|
+
inheriting_3.tag_list = 'one, four'
|
|
79
74
|
inheriting_3.save
|
|
80
75
|
|
|
81
|
-
taggable.tag_list =
|
|
76
|
+
taggable.tag_list = 'one, two, three, four'
|
|
82
77
|
taggable.save
|
|
83
78
|
end
|
|
84
79
|
|
|
85
|
-
it
|
|
86
|
-
inheriting_1.find_related_tags.
|
|
87
|
-
inheriting_1.find_related_tags.
|
|
88
|
-
inheriting_1.find_related_tags.
|
|
80
|
+
it 'should find related objects based on tag names on context' do
|
|
81
|
+
expect(inheriting_1.find_related_tags).to include(inheriting_3)
|
|
82
|
+
expect(inheriting_1.find_related_tags).to_not include(inheriting_2)
|
|
83
|
+
expect(inheriting_1.find_related_tags).to_not include(taggable)
|
|
89
84
|
|
|
90
|
-
inheriting_1.find_related_tags_for(TaggableModel).
|
|
91
|
-
inheriting_1.find_related_tags_for(TaggableModel).
|
|
92
|
-
inheriting_1.find_related_tags_for(TaggableModel).
|
|
85
|
+
expect(inheriting_1.find_related_tags_for(TaggableModel)).to include(inheriting_3)
|
|
86
|
+
expect(inheriting_1.find_related_tags_for(TaggableModel)).to_not include(inheriting_2)
|
|
87
|
+
expect(inheriting_1.find_related_tags_for(TaggableModel)).to include(taggable)
|
|
93
88
|
end
|
|
94
89
|
|
|
95
|
-
it
|
|
96
|
-
inheriting_1.find_related_tags.
|
|
97
|
-
inheriting_1.find_related_tags_for(InheritingTaggableModel).
|
|
98
|
-
inheriting_1.find_related_tags_for(TaggableModel).
|
|
90
|
+
it 'should not include the object itself in the list of related objects' do
|
|
91
|
+
expect(inheriting_1.find_related_tags).to_not include(inheriting_1)
|
|
92
|
+
expect(inheriting_1.find_related_tags_for(InheritingTaggableModel)).to_not include(inheriting_1)
|
|
93
|
+
expect(inheriting_1.find_related_tags_for(TaggableModel)).to_not include(inheriting_1)
|
|
99
94
|
end
|
|
100
95
|
end
|
|
101
96
|
|
|
102
|
-
describe
|
|
97
|
+
describe 'tag list' do
|
|
103
98
|
before do
|
|
104
|
-
@inherited_same = InheritingTaggableModel.new(:
|
|
105
|
-
@inherited_different = AlteredInheritingTaggableModel.new(:
|
|
99
|
+
@inherited_same = InheritingTaggableModel.new(name: 'inherited same')
|
|
100
|
+
@inherited_different = AlteredInheritingTaggableModel.new(name: 'inherited different')
|
|
106
101
|
end
|
|
107
102
|
|
|
108
|
-
|
|
109
|
-
|
|
103
|
+
#TODO, shared example
|
|
104
|
+
it 'should be able to save tags for inherited models' do
|
|
105
|
+
inheriting_model.tag_list = 'bob, kelso'
|
|
110
106
|
inheriting_model.save
|
|
111
|
-
InheritingTaggableModel.tagged_with(
|
|
107
|
+
expect(InheritingTaggableModel.tagged_with('bob').first).to eq(inheriting_model)
|
|
112
108
|
end
|
|
113
109
|
|
|
114
|
-
it
|
|
115
|
-
inheriting_model.tag_list =
|
|
110
|
+
it 'should find STI tagged models on the superclass' do
|
|
111
|
+
inheriting_model.tag_list = 'bob, kelso'
|
|
116
112
|
inheriting_model.save
|
|
117
|
-
TaggableModel.tagged_with(
|
|
113
|
+
expect(TaggableModel.tagged_with('bob').first).to eq(inheriting_model)
|
|
118
114
|
end
|
|
119
115
|
|
|
120
|
-
it
|
|
121
|
-
altered_inheriting.part_list =
|
|
116
|
+
it 'should be able to add on contexts only to some subclasses' do
|
|
117
|
+
altered_inheriting.part_list = 'fork, spoon'
|
|
122
118
|
altered_inheriting.save
|
|
123
|
-
InheritingTaggableModel.tagged_with(
|
|
124
|
-
AlteredInheritingTaggableModel.tagged_with(
|
|
119
|
+
expect(InheritingTaggableModel.tagged_with('fork', on: :parts)).to be_empty
|
|
120
|
+
expect(AlteredInheritingTaggableModel.tagged_with('fork', on: :parts).first).to eq(altered_inheriting)
|
|
125
121
|
end
|
|
126
122
|
|
|
127
|
-
it
|
|
128
|
-
inheriting_model.tag_list =
|
|
123
|
+
it 'should have different tag_counts_on for inherited models' do
|
|
124
|
+
inheriting_model.tag_list = 'bob, kelso'
|
|
129
125
|
inheriting_model.save!
|
|
130
|
-
altered_inheriting.tag_list =
|
|
126
|
+
altered_inheriting.tag_list = 'fork, spoon'
|
|
131
127
|
altered_inheriting.save!
|
|
132
128
|
|
|
133
|
-
InheritingTaggableModel.tag_counts_on(:tags, :
|
|
134
|
-
AlteredInheritingTaggableModel.tag_counts_on(:tags, :
|
|
135
|
-
TaggableModel.tag_counts_on(:tags, :
|
|
129
|
+
expect(InheritingTaggableModel.tag_counts_on(:tags, order: 'tags.id').map(&:name)).to eq(%w(bob kelso))
|
|
130
|
+
expect(AlteredInheritingTaggableModel.tag_counts_on(:tags, order: 'tags.id').map(&:name)).to eq(%w(fork spoon))
|
|
131
|
+
expect(TaggableModel.tag_counts_on(:tags, order: 'tags.id').map(&:name)).to eq(%w(bob kelso fork spoon))
|
|
136
132
|
end
|
|
137
133
|
|
|
138
|
-
it
|
|
139
|
-
inheriting_model.tag_list =
|
|
134
|
+
it 'should have different tags_on for inherited models' do
|
|
135
|
+
inheriting_model.tag_list = 'bob, kelso'
|
|
140
136
|
inheriting_model.save!
|
|
141
|
-
altered_inheriting.tag_list =
|
|
137
|
+
altered_inheriting.tag_list = 'fork, spoon'
|
|
142
138
|
altered_inheriting.save!
|
|
143
139
|
|
|
144
|
-
InheritingTaggableModel.tags_on(:tags, :
|
|
145
|
-
AlteredInheritingTaggableModel.tags_on(:tags, :
|
|
146
|
-
TaggableModel.tags_on(:tags, :
|
|
140
|
+
expect(InheritingTaggableModel.tags_on(:tags, order: 'tags.id').map(&:name)).to eq(%w(bob kelso))
|
|
141
|
+
expect(AlteredInheritingTaggableModel.tags_on(:tags, order: 'tags.id').map(&:name)).to eq(%w(fork spoon))
|
|
142
|
+
expect(TaggableModel.tags_on(:tags, order: 'tags.id').map(&:name)).to eq(%w(bob kelso fork spoon))
|
|
147
143
|
end
|
|
148
144
|
|
|
149
145
|
it 'should store same tag without validation conflict' do
|
|
@@ -153,35 +149,62 @@ describe "Single Table Inheritance" do
|
|
|
153
149
|
inheriting_model.tag_list = 'one'
|
|
154
150
|
inheriting_model.save!
|
|
155
151
|
|
|
156
|
-
inheriting_model.update_attributes! :
|
|
152
|
+
inheriting_model.update_attributes! name: 'foo'
|
|
157
153
|
end
|
|
158
154
|
end
|
|
159
155
|
|
|
160
|
-
describe
|
|
161
|
-
it
|
|
162
|
-
student.tag(taggable, :
|
|
163
|
-
student.owned_taggings.
|
|
156
|
+
describe 'ownership' do
|
|
157
|
+
it 'should have taggings' do
|
|
158
|
+
student.tag(taggable, with: 'ruby,scheme', on: :tags)
|
|
159
|
+
expect(student.owned_taggings.count).to eq(2)
|
|
164
160
|
end
|
|
165
161
|
|
|
166
|
-
it
|
|
167
|
-
student.tag(taggable, :
|
|
168
|
-
student.owned_tags.
|
|
162
|
+
it 'should have tags' do
|
|
163
|
+
student.tag(taggable, with: 'ruby,scheme', on: :tags)
|
|
164
|
+
expect(student.owned_tags.count).to eq(2)
|
|
169
165
|
end
|
|
170
166
|
|
|
171
|
-
it
|
|
172
|
-
student.tag(taggable, :
|
|
173
|
-
taggable.tags_from(student).
|
|
167
|
+
it 'should return tags for the inheriting tagger' do
|
|
168
|
+
student.tag(taggable, with: 'ruby, scheme', on: :tags)
|
|
169
|
+
expect(taggable.tags_from(student)).to eq(%w(ruby scheme))
|
|
174
170
|
end
|
|
175
171
|
|
|
176
|
-
it
|
|
177
|
-
student.tag(taggable, :
|
|
178
|
-
taggable.owner_tags_on(student, :tags).
|
|
172
|
+
it 'returns owner tags on the tagger' do
|
|
173
|
+
student.tag(taggable, with: 'ruby, scheme', on: :tags)
|
|
174
|
+
expect(taggable.owner_tags_on(student, :tags).count).to eq(2)
|
|
179
175
|
end
|
|
180
176
|
|
|
181
|
-
it
|
|
182
|
-
student.tag(taggable, :
|
|
183
|
-
TaggableModel.tagged_with(%w(ruby scheme), :
|
|
177
|
+
it 'should scope objects returned by tagged_with by owners' do
|
|
178
|
+
student.tag(taggable, with: 'ruby, scheme', on: :tags)
|
|
179
|
+
expect(TaggableModel.tagged_with(%w(ruby scheme), owned_by: student).count).to eq(1)
|
|
184
180
|
end
|
|
185
181
|
end
|
|
186
182
|
|
|
183
|
+
describe 'a subclass of Tag' do
|
|
184
|
+
let(:company) { Company.new(:name => 'Dewey, Cheatham & Howe') }
|
|
185
|
+
let(:user) { User.create! }
|
|
186
|
+
|
|
187
|
+
subject { Market.create! :name => 'finance' }
|
|
188
|
+
|
|
189
|
+
its(:type) { should eql 'Market' }
|
|
190
|
+
|
|
191
|
+
it 'sets STI type through string list' do
|
|
192
|
+
company.market_list = 'law, accounting'
|
|
193
|
+
company.save!
|
|
194
|
+
expect(Market.count).to eq(2)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
it 'does not interfere with a normal Tag context on the same model' do
|
|
198
|
+
company.location_list = 'cambridge'
|
|
199
|
+
company.save!
|
|
200
|
+
expect(ActsAsTaggableOn::Tag.where(name: 'cambridge', type: nil)).to_not be_empty
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
it 'is returned with proper type through ownership' do
|
|
204
|
+
user.tag(company, :with => 'ripoffs, rackets', :on => :markets)
|
|
205
|
+
tags = company.owner_tags_on(user, :markets)
|
|
206
|
+
expect(tags.all? { |tag| tag.is_a? Market }).to be_truthy
|
|
207
|
+
end
|
|
208
|
+
end
|
|
187
209
|
end
|
|
210
|
+
|