acts-as-taggable-on 4.0.0 → 8.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.
- checksums.yaml +5 -5
- data/.github/workflows/spec.yml +95 -0
- data/.gitignore +1 -1
- data/Appraisals +12 -10
- data/CHANGELOG.md +206 -71
- data/CONTRIBUTING.md +13 -0
- data/Gemfile +1 -1
- data/README.md +79 -13
- data/acts-as-taggable-on.gemspec +2 -6
- data/db/migrate/1_acts_as_taggable_on_migration.rb +14 -8
- data/db/migrate/2_add_missing_unique_indices.rb +14 -9
- data/db/migrate/3_add_taggings_counter_cache_to_tags.rb +9 -4
- data/db/migrate/4_add_missing_taggable_index.rb +8 -3
- data/db/migrate/5_change_collation_for_tag_names.rb +7 -2
- data/db/migrate/6_add_missing_indexes_on_taggings.rb +22 -0
- data/db/migrate/7_add_tenant_to_taggings.rb +16 -0
- data/gemfiles/activerecord_5.0.gemfile +11 -5
- data/gemfiles/activerecord_5.1.gemfile +21 -0
- data/gemfiles/activerecord_5.2.gemfile +21 -0
- data/gemfiles/activerecord_6.0.gemfile +21 -0
- data/gemfiles/activerecord_6.1.gemfile +23 -0
- data/lib/acts-as-taggable-on.rb +6 -2
- data/lib/acts_as_taggable_on/tag.rb +23 -23
- data/lib/acts_as_taggable_on/tag_list.rb +1 -0
- data/lib/acts_as_taggable_on/taggable.rb +18 -1
- data/lib/acts_as_taggable_on/taggable/cache.rb +38 -34
- data/lib/acts_as_taggable_on/taggable/collection.rb +9 -7
- data/lib/acts_as_taggable_on/taggable/core.rb +49 -179
- data/lib/acts_as_taggable_on/taggable/ownership.rb +16 -5
- data/lib/acts_as_taggable_on/taggable/related.rb +1 -1
- data/lib/acts_as_taggable_on/taggable/tag_list_type.rb +4 -0
- data/lib/acts_as_taggable_on/taggable/tagged_with_query.rb +16 -0
- data/lib/acts_as_taggable_on/taggable/tagged_with_query/all_tags_query.rb +111 -0
- data/lib/acts_as_taggable_on/taggable/tagged_with_query/any_tags_query.rb +70 -0
- data/lib/acts_as_taggable_on/taggable/tagged_with_query/exclude_tags_query.rb +82 -0
- data/lib/acts_as_taggable_on/taggable/tagged_with_query/query_base.rb +61 -0
- data/lib/acts_as_taggable_on/tagger.rb +3 -3
- data/lib/acts_as_taggable_on/tagging.rb +9 -4
- data/lib/acts_as_taggable_on/utils.rb +4 -4
- data/lib/acts_as_taggable_on/version.rb +1 -2
- data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +4 -12
- data/spec/acts_as_taggable_on/caching_spec.rb +34 -10
- data/spec/acts_as_taggable_on/{taggable/dirty_spec.rb → dirty_spec.rb} +28 -13
- data/spec/acts_as_taggable_on/single_table_inheritance_spec.rb +28 -8
- data/spec/acts_as_taggable_on/tag_spec.rb +16 -1
- data/spec/acts_as_taggable_on/taggable_spec.rb +22 -15
- data/spec/acts_as_taggable_on/tagger_spec.rb +2 -2
- data/spec/acts_as_taggable_on/tagging_spec.rb +26 -0
- data/spec/internal/app/models/altered_inheriting_taggable_model.rb +2 -0
- data/spec/internal/app/models/cached_model_with_array.rb +6 -0
- data/spec/internal/app/models/columns_override_model.rb +5 -0
- data/spec/internal/app/models/company.rb +1 -1
- data/spec/internal/app/models/inheriting_taggable_model.rb +2 -0
- data/spec/internal/app/models/market.rb +1 -1
- data/spec/internal/app/models/non_standard_id_taggable_model.rb +1 -1
- data/spec/internal/app/models/student.rb +2 -0
- data/spec/internal/app/models/taggable_model.rb +3 -0
- data/spec/internal/app/models/user.rb +1 -1
- data/spec/internal/config/database.yml.sample +4 -8
- data/spec/internal/db/schema.rb +17 -5
- data/spec/spec_helper.rb +0 -1
- data/spec/support/database.rb +4 -4
- metadata +29 -68
- data/.travis.yml +0 -36
- data/UPGRADING.md +0 -8
- data/db/migrate/6_add_missing_indexes.rb +0 -12
- data/gemfiles/activerecord_4.0.gemfile +0 -16
- data/gemfiles/activerecord_4.1.gemfile +0 -16
- data/gemfiles/activerecord_4.2.gemfile +0 -15
- data/lib/acts_as_taggable_on/taggable/dirty.rb +0 -36
- data/spec/internal/app/models/models.rb +0 -90
@@ -20,14 +20,14 @@ module ActsAsTaggableOn
|
|
20
20
|
Digest::SHA1.hexdigest(string)[0..6]
|
21
21
|
end
|
22
22
|
|
23
|
-
def active_record5?
|
24
|
-
::ActiveRecord::VERSION::MAJOR == 5
|
25
|
-
end
|
26
|
-
|
27
23
|
def like_operator
|
28
24
|
using_postgresql? ? 'ILIKE' : 'LIKE'
|
29
25
|
end
|
30
26
|
|
27
|
+
def legacy_activerecord?
|
28
|
+
ActiveRecord.version <= Gem::Version.new('5.3.0')
|
29
|
+
end
|
30
|
+
|
31
31
|
# escape _ and % characters in strings, since these are wildcards in SQL.
|
32
32
|
def escape_like(str)
|
33
33
|
str.gsub(/[!%_]/) { |x| '!' + x }
|
@@ -73,14 +73,6 @@ describe 'Acts As Taggable On' do
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
-
describe 'Reloading' do
|
77
|
-
it 'should save a model instantiated by Model.find' do
|
78
|
-
taggable = TaggableModel.create!(name: 'Taggable')
|
79
|
-
found_taggable = TaggableModel.find(taggable.id)
|
80
|
-
found_taggable.save
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
76
|
describe 'Matching Contexts' do
|
85
77
|
it 'should find objects with tags of matching contexts' do
|
86
78
|
taggable1 = TaggableModel.create!(name: 'Taggable 1')
|
@@ -142,7 +134,7 @@ describe 'Acts As Taggable On' do
|
|
142
134
|
taggable1.save
|
143
135
|
|
144
136
|
column = TaggableModel.connection.quote_column_name("context")
|
145
|
-
offer_alias = TaggableModel.connection.quote_table_name(
|
137
|
+
offer_alias = TaggableModel.connection.quote_table_name(ActsAsTaggableOn.taggings_table)
|
146
138
|
need_alias = TaggableModel.connection.quote_table_name("need_taggings_taggable_models_join")
|
147
139
|
|
148
140
|
expect(TaggableModel.joins(:offerings, :needs).to_sql).to include "#{offer_alias}.#{column}"
|
@@ -200,7 +192,7 @@ describe 'Acts As Taggable On' do
|
|
200
192
|
its(:cached_glass_list) { should be_blank }
|
201
193
|
|
202
194
|
context 'language taggings cache after update' do
|
203
|
-
before { @taggable.
|
195
|
+
before { @taggable.update(language_list: 'ruby, .net') }
|
204
196
|
subject { @taggable }
|
205
197
|
|
206
198
|
its(:language_list) { should == ['ruby', '.net']}
|
@@ -209,7 +201,7 @@ describe 'Acts As Taggable On' do
|
|
209
201
|
end
|
210
202
|
|
211
203
|
context 'status taggings cache after update' do
|
212
|
-
before { @taggable.
|
204
|
+
before { @taggable.update(status_list: 'happy, married') }
|
213
205
|
subject { @taggable }
|
214
206
|
|
215
207
|
its(:status_list) { should == ['happy', 'married'] }
|
@@ -222,7 +214,7 @@ describe 'Acts As Taggable On' do
|
|
222
214
|
|
223
215
|
context 'glass taggings cache after update' do
|
224
216
|
before do
|
225
|
-
@taggable.
|
217
|
+
@taggable.update(glass_list: 'rectangle, aviator')
|
226
218
|
end
|
227
219
|
|
228
220
|
subject { @taggable }
|
@@ -31,40 +31,40 @@ describe 'Acts As Taggable On' do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'should cache tags' do
|
34
|
-
@taggable.
|
34
|
+
@taggable.update(tag_list: 'awesome, epic')
|
35
35
|
expect(@taggable.cached_tag_list).to eq('awesome, epic')
|
36
36
|
|
37
|
-
@another_taggable.
|
37
|
+
@another_taggable.update(language_list: 'ruby, .net')
|
38
38
|
expect(@another_taggable.cached_language_list).to eq('ruby, .net')
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'should keep the cache' do
|
42
|
-
@taggable.
|
42
|
+
@taggable.update(tag_list: 'awesome, epic')
|
43
43
|
@taggable = CachedModel.find(@taggable.id)
|
44
44
|
@taggable.save!
|
45
45
|
expect(@taggable.cached_tag_list).to eq('awesome, epic')
|
46
46
|
end
|
47
47
|
|
48
48
|
it 'should update the cache' do
|
49
|
-
@taggable.
|
50
|
-
@taggable.
|
49
|
+
@taggable.update(tag_list: 'awesome, epic')
|
50
|
+
@taggable.update(tag_list: 'awesome')
|
51
51
|
expect(@taggable.cached_tag_list).to eq('awesome')
|
52
52
|
end
|
53
53
|
|
54
54
|
it 'should remove the cache' do
|
55
|
-
@taggable.
|
56
|
-
@taggable.
|
55
|
+
@taggable.update(tag_list: 'awesome, epic')
|
56
|
+
@taggable.update(tag_list: '')
|
57
57
|
expect(@taggable.cached_tag_list).to be_blank
|
58
58
|
end
|
59
59
|
|
60
60
|
it 'should have a tag list' do
|
61
|
-
@taggable.
|
61
|
+
@taggable.update(tag_list: 'awesome, epic')
|
62
62
|
@taggable = CachedModel.find(@taggable.id)
|
63
63
|
expect(@taggable.tag_list.sort).to eq(%w(awesome epic).sort)
|
64
64
|
end
|
65
65
|
|
66
66
|
it 'should keep the tag list' do
|
67
|
-
@taggable.
|
67
|
+
@taggable.update(tag_list: 'awesome, epic')
|
68
68
|
@taggable = CachedModel.find(@taggable.id)
|
69
69
|
@taggable.save!
|
70
70
|
expect(@taggable.tag_list.sort).to eq(%w(awesome epic).sort)
|
@@ -75,6 +75,12 @@ describe 'Acts As Taggable On' do
|
|
75
75
|
CachedModel.reset_column_information
|
76
76
|
expect(CachedModel.instance_variable_get(:@acts_as_taggable_on_cache_columns)).to eql(nil)
|
77
77
|
end
|
78
|
+
|
79
|
+
it 'should not override a user-defined columns method' do
|
80
|
+
expect(ColumnsOverrideModel.columns.map(&:name)).not_to include('ignored_column')
|
81
|
+
ColumnsOverrideModel.acts_as_taggable
|
82
|
+
expect(ColumnsOverrideModel.columns.map(&:name)).not_to include('ignored_column')
|
83
|
+
end
|
78
84
|
end
|
79
85
|
|
80
86
|
describe 'with a custom delimiter' do
|
@@ -89,7 +95,7 @@ describe 'Acts As Taggable On' do
|
|
89
95
|
end
|
90
96
|
|
91
97
|
it 'should cache tags with custom delimiter' do
|
92
|
-
@taggable.
|
98
|
+
@taggable.update(tag_list: 'awesome; epic')
|
93
99
|
expect(@taggable.tag_list).to eq(['awesome', 'epic'])
|
94
100
|
expect(@taggable.cached_tag_list).to eq('awesome; epic')
|
95
101
|
|
@@ -99,6 +105,24 @@ describe 'Acts As Taggable On' do
|
|
99
105
|
end
|
100
106
|
end
|
101
107
|
|
108
|
+
describe 'Cache methods initialization on new models' do
|
109
|
+
before(:all) do
|
110
|
+
ActiveRecord::Base.connection.execute(
|
111
|
+
'INSERT INTO cache_methods_injected_models (cached_tag_list) VALUES (\'ciao\')'
|
112
|
+
)
|
113
|
+
class CacheMethodsInjectedModel < ActiveRecord::Base
|
114
|
+
acts_as_taggable
|
115
|
+
end
|
116
|
+
end
|
117
|
+
after(:all) { Object.send(:remove_const, :CacheMethodsInjectedModel) }
|
118
|
+
|
119
|
+
it 'cached_tag_list_on? get injected correctly' do
|
120
|
+
expect do
|
121
|
+
CacheMethodsInjectedModel.first.tag_list
|
122
|
+
end.not_to raise_error
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
102
126
|
describe 'CachingWithArray' do
|
103
127
|
pending '#TODO'
|
104
128
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
|
-
describe
|
4
|
+
describe 'Dirty behavior of taggable objects' do
|
5
5
|
context 'with un-contexted tags' do
|
6
6
|
before(:each) do
|
7
7
|
@taggable = TaggableModel.create(tag_list: 'awesome, epic')
|
@@ -14,19 +14,27 @@ describe ActsAsTaggableOn::Taggable::Dirty do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'should show changes of dirty object' do
|
17
|
-
expect(@taggable.changes).to eq({'tag_list' => ['awesome, epic', ['one']]})
|
17
|
+
expect(@taggable.changes).to eq({'tag_list' => [['awesome', 'epic'], ['one']]})
|
18
18
|
end
|
19
19
|
|
20
|
-
it '
|
21
|
-
|
20
|
+
it 'should show changes of freshly initialized dirty object' do
|
21
|
+
taggable = TaggableModel.find(@taggable.id)
|
22
|
+
taggable.tag_list = 'one'
|
23
|
+
expect(taggable.changes).to eq({'tag_list' => [['awesome', 'epic'], ['one']]})
|
24
|
+
end
|
25
|
+
|
26
|
+
if Rails.version >= "5.1"
|
27
|
+
it 'flags tag_list as changed' do
|
28
|
+
expect(@taggable.will_save_change_to_tag_list?).to be_truthy
|
29
|
+
end
|
22
30
|
end
|
23
31
|
|
24
32
|
it 'preserves original value' do
|
25
|
-
expect(@taggable.tag_list_was).to eq('awesome, epic')
|
33
|
+
expect(@taggable.tag_list_was).to eq(['awesome', 'epic'])
|
26
34
|
end
|
27
35
|
|
28
36
|
it 'shows what the change was' do
|
29
|
-
expect(@taggable.tag_list_change).to eq(['awesome, epic', ['one']])
|
37
|
+
expect(@taggable.tag_list_change).to eq([['awesome', 'epic'], ['one']])
|
30
38
|
end
|
31
39
|
|
32
40
|
context 'without order' do
|
@@ -90,7 +98,7 @@ describe ActsAsTaggableOn::Taggable::Dirty do
|
|
90
98
|
end
|
91
99
|
|
92
100
|
it 'should show changes of dirty object' do
|
93
|
-
expect(@taggable.changes).to eq({'language_list' => ['awesome, epic', ['one']]})
|
101
|
+
expect(@taggable.changes).to eq({'language_list' => [['awesome', 'epic'], ['one']]})
|
94
102
|
end
|
95
103
|
|
96
104
|
it 'flags language_list as changed' do
|
@@ -98,15 +106,11 @@ describe ActsAsTaggableOn::Taggable::Dirty do
|
|
98
106
|
end
|
99
107
|
|
100
108
|
it 'preserves original value' do
|
101
|
-
expect(@taggable.language_list_was).to eq('awesome, epic')
|
109
|
+
expect(@taggable.language_list_was).to eq(['awesome', 'epic'])
|
102
110
|
end
|
103
111
|
|
104
112
|
it 'shows what the change was' do
|
105
|
-
expect(@taggable.language_list_change).to eq(['awesome, epic', ['one']])
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'shows what the changes were' do
|
109
|
-
expect(@taggable.language_list_changes).to eq(['awesome, epic', ['one']])
|
113
|
+
expect(@taggable.language_list_change).to eq([['awesome', 'epic'], ['one']])
|
110
114
|
end
|
111
115
|
end
|
112
116
|
|
@@ -123,5 +127,16 @@ describe ActsAsTaggableOn::Taggable::Dirty do
|
|
123
127
|
expect(@taggable.changes).to be_empty
|
124
128
|
end
|
125
129
|
end
|
130
|
+
|
131
|
+
context 'when language_list changed by association' do
|
132
|
+
let(:tag) { ActsAsTaggableOn::Tag.new(name: 'one') }
|
133
|
+
|
134
|
+
it 'flags language_list as changed' do
|
135
|
+
expect(@taggable.changes).to be_empty
|
136
|
+
@taggable.languages << tag
|
137
|
+
expect(@taggable.language_list_changed?).to be_truthy
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
126
141
|
end
|
127
142
|
end
|
@@ -127,9 +127,9 @@ describe 'Single Table Inheritance' do
|
|
127
127
|
altered_inheriting.tag_list = 'fork, spoon'
|
128
128
|
altered_inheriting.save!
|
129
129
|
|
130
|
-
expect(InheritingTaggableModel.tag_counts_on(:tags, order:
|
131
|
-
expect(AlteredInheritingTaggableModel.tag_counts_on(:tags, order:
|
132
|
-
expect(TaggableModel.tag_counts_on(:tags, order:
|
130
|
+
expect(InheritingTaggableModel.tag_counts_on(:tags, order: "#{ActsAsTaggableOn.tags_table}.id").map(&:name)).to eq(%w(bob kelso))
|
131
|
+
expect(AlteredInheritingTaggableModel.tag_counts_on(:tags, order: "#{ActsAsTaggableOn.tags_table}.id").map(&:name)).to eq(%w(fork spoon))
|
132
|
+
expect(TaggableModel.tag_counts_on(:tags, order: "#{ActsAsTaggableOn.tags_table}.id").map(&:name)).to eq(%w(bob kelso fork spoon))
|
133
133
|
end
|
134
134
|
|
135
135
|
it 'should have different tags_on for inherited models' do
|
@@ -138,9 +138,9 @@ describe 'Single Table Inheritance' do
|
|
138
138
|
altered_inheriting.tag_list = 'fork, spoon'
|
139
139
|
altered_inheriting.save!
|
140
140
|
|
141
|
-
expect(InheritingTaggableModel.tags_on(:tags, order:
|
142
|
-
expect(AlteredInheritingTaggableModel.tags_on(:tags, order:
|
143
|
-
expect(TaggableModel.tags_on(:tags, order:
|
141
|
+
expect(InheritingTaggableModel.tags_on(:tags, order: "#{ActsAsTaggableOn.tags_table}.id").map(&:name)).to eq(%w(bob kelso))
|
142
|
+
expect(AlteredInheritingTaggableModel.tags_on(:tags, order: "#{ActsAsTaggableOn.tags_table}.id").map(&:name)).to eq(%w(fork spoon))
|
143
|
+
expect(TaggableModel.tags_on(:tags, order: "#{ActsAsTaggableOn.tags_table}.id").map(&:name)).to eq(%w(bob kelso fork spoon))
|
144
144
|
end
|
145
145
|
|
146
146
|
it 'should store same tag without validation conflict' do
|
@@ -150,7 +150,12 @@ describe 'Single Table Inheritance' do
|
|
150
150
|
inheriting_model.tag_list = 'one'
|
151
151
|
inheriting_model.save!
|
152
152
|
|
153
|
-
inheriting_model.
|
153
|
+
inheriting_model.update! name: 'foo'
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should only join with taggable's table to check type for inherited models" do
|
157
|
+
expect(TaggableModel.tag_counts_on(:tags).to_sql).to_not match /INNER JOIN taggable_models ON/
|
158
|
+
expect(InheritingTaggableModel.tag_counts_on(:tags).to_sql).to match /INNER JOIN taggable_models ON/
|
154
159
|
end
|
155
160
|
end
|
156
161
|
|
@@ -170,11 +175,27 @@ describe 'Single Table Inheritance' do
|
|
170
175
|
expect(taggable.tags_from(student)).to eq(%w(ruby scheme))
|
171
176
|
end
|
172
177
|
|
178
|
+
it 'returns all owner tags on the taggable' do
|
179
|
+
student.tag(taggable, with: 'ruby, scheme', on: :tags)
|
180
|
+
student.tag(taggable, with: 'skill_one', on: :skills)
|
181
|
+
student.tag(taggable, with: 'english, spanish', on: :language)
|
182
|
+
expect(taggable.owner_tags(student).count).to eq(5)
|
183
|
+
expect(taggable.owner_tags(student).sort == %w(english ruby scheme skill_one spanish))
|
184
|
+
end
|
185
|
+
|
186
|
+
|
173
187
|
it 'returns owner tags on the tagger' do
|
174
188
|
student.tag(taggable, with: 'ruby, scheme', on: :tags)
|
175
189
|
expect(taggable.owner_tags_on(student, :tags).count).to eq(2)
|
176
190
|
end
|
177
191
|
|
192
|
+
it 'returns owner tags on the taggable for an array of contexts' do
|
193
|
+
student.tag(taggable, with: 'ruby, scheme', on: :tags)
|
194
|
+
student.tag(taggable, with: 'skill_one, skill_two', on: :skills)
|
195
|
+
expect(taggable.owner_tags_on(student, [:tags, :skills]).count).to eq(4)
|
196
|
+
expect(taggable.owner_tags_on(student, [:tags, :skills]).sort == %w(ruby scheme skill_one skill_two))
|
197
|
+
end
|
198
|
+
|
178
199
|
it 'should scope objects returned by tagged_with by owners' do
|
179
200
|
student.tag(taggable, with: 'ruby, scheme', on: :tags)
|
180
201
|
expect(TaggableModel.tagged_with(%w(ruby scheme), owned_by: student).count).to eq(1)
|
@@ -208,4 +229,3 @@ describe 'Single Table Inheritance' do
|
|
208
229
|
end
|
209
230
|
end
|
210
231
|
end
|
211
|
-
|
@@ -14,7 +14,7 @@ end
|
|
14
14
|
describe ActsAsTaggableOn::Tag do
|
15
15
|
before(:each) do
|
16
16
|
@tag = ActsAsTaggableOn::Tag.new
|
17
|
-
@user = TaggableModel.create(name: 'Pablo')
|
17
|
+
@user = TaggableModel.create(name: 'Pablo', tenant_id: 100)
|
18
18
|
end
|
19
19
|
|
20
20
|
|
@@ -70,6 +70,21 @@ describe ActsAsTaggableOn::Tag do
|
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
+
describe 'for tenant' do
|
74
|
+
before(:each) do
|
75
|
+
@user.skill_list.add('ruby')
|
76
|
+
@user.save
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should return tags for the tenant' do
|
80
|
+
expect(ActsAsTaggableOn::Tag.for_tenant('100').pluck(:name)).to include('ruby')
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should not return tags for other tenants' do
|
84
|
+
expect(ActsAsTaggableOn::Tag.for_tenant('200').pluck(:name)).to_not include('ruby')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
73
88
|
describe 'find or create by name' do
|
74
89
|
before(:each) do
|
75
90
|
@tag.name = 'awesome'
|
@@ -109,6 +109,10 @@ describe 'Taggable' do
|
|
109
109
|
expect(@taggable.tag_types).to eq(TaggableModel.tag_types)
|
110
110
|
end
|
111
111
|
|
112
|
+
it 'should have tenant column' do
|
113
|
+
expect(TaggableModel.tenant_column).to eq(:tenant_id)
|
114
|
+
end
|
115
|
+
|
112
116
|
it 'should have tag_counts_on' do
|
113
117
|
expect(TaggableModel.tag_counts_on(:tags)).to be_empty
|
114
118
|
|
@@ -200,8 +204,8 @@ describe 'Taggable' do
|
|
200
204
|
@taggables[1].skill_list = 'css'
|
201
205
|
@taggables.each { |taggable| taggable.save }
|
202
206
|
|
203
|
-
@found_taggables_by_tag = TaggableModel.joins(:tags).where(
|
204
|
-
@found_taggables_by_skill = TaggableModel.joins(:skills).where(
|
207
|
+
@found_taggables_by_tag = TaggableModel.joins(:tags).where(ActsAsTaggableOn.tags_table => {name: ['bob']})
|
208
|
+
@found_taggables_by_skill = TaggableModel.joins(:skills).where(ActsAsTaggableOn.tags_table => {name: ['ruby']})
|
205
209
|
|
206
210
|
expect(@found_taggables_by_tag).to include @taggables[0]
|
207
211
|
expect(@found_taggables_by_tag).to_not include @taggables[1]
|
@@ -247,7 +251,7 @@ describe 'Taggable' do
|
|
247
251
|
expect(TaggableModel.tagged_with("ruby", :start_at => today, :end_at => tomorrow).count).to eq(1)
|
248
252
|
end
|
249
253
|
|
250
|
-
|
254
|
+
it "shouldn't be able to find a tag outside date range" do
|
251
255
|
@taggable.skill_list = "ruby"
|
252
256
|
@taggable.save
|
253
257
|
|
@@ -255,14 +259,17 @@ describe 'Taggable' do
|
|
255
259
|
end
|
256
260
|
|
257
261
|
it 'should be able to find by tag with context' do
|
258
|
-
@taggable.skill_list = 'ruby, rails, css'
|
259
|
-
@taggable.tag_list = 'bob, charlie'
|
262
|
+
@taggable.skill_list = 'ruby, rails, css, julia'
|
263
|
+
@taggable.tag_list = 'bob, charlie, julia'
|
260
264
|
@taggable.save
|
261
265
|
|
262
266
|
expect(TaggableModel.tagged_with('ruby').first).to eq(@taggable)
|
263
267
|
expect(TaggableModel.tagged_with('ruby, css').first).to eq(@taggable)
|
264
268
|
expect(TaggableModel.tagged_with('bob', on: :skills).first).to_not eq(@taggable)
|
265
269
|
expect(TaggableModel.tagged_with('bob', on: :tags).first).to eq(@taggable)
|
270
|
+
expect(TaggableModel.tagged_with('julia', on: :skills).size).to eq(1)
|
271
|
+
expect(TaggableModel.tagged_with('julia', on: :tags).size).to eq(1)
|
272
|
+
expect(TaggableModel.tagged_with('julia', on: nil).size).to eq(2)
|
266
273
|
end
|
267
274
|
|
268
275
|
it 'should not care about case' do
|
@@ -335,7 +342,7 @@ describe 'Taggable' do
|
|
335
342
|
TaggableModel.create(name: 'Charlie', skill_list: 'ruby')
|
336
343
|
|
337
344
|
expect(TaggableModel.all_tag_counts).to_not be_empty
|
338
|
-
expect(TaggableModel.all_tag_counts(order:
|
345
|
+
expect(TaggableModel.all_tag_counts(order: "#{ActsAsTaggableOn.tags_table}.id").first.count).to eq(3) # ruby
|
339
346
|
end
|
340
347
|
|
341
348
|
it 'should be able to get all tags on model as whole' do
|
@@ -344,7 +351,7 @@ describe 'Taggable' do
|
|
344
351
|
TaggableModel.create(name: 'Charlie', skill_list: 'ruby')
|
345
352
|
|
346
353
|
expect(TaggableModel.all_tags).to_not be_empty
|
347
|
-
expect(TaggableModel.all_tags(order:
|
354
|
+
expect(TaggableModel.all_tags(order: "#{ActsAsTaggableOn.tags_table}.id").first.name).to eq('ruby')
|
348
355
|
end
|
349
356
|
|
350
357
|
it 'should be able to use named scopes to chain tag finds by any tags by context' do
|
@@ -366,7 +373,7 @@ describe 'Taggable' do
|
|
366
373
|
TaggableModel.create(name: 'Frank', tag_list: 'ruby, rails')
|
367
374
|
TaggableModel.create(name: 'Charlie', skill_list: 'ruby')
|
368
375
|
|
369
|
-
expect(TaggableModel.tagged_with('ruby').tag_counts(order:
|
376
|
+
expect(TaggableModel.tagged_with('ruby').tag_counts(order: "#{ActsAsTaggableOn.tags_table}.id").first.count).to eq(2) # ruby
|
370
377
|
expect(TaggableModel.tagged_with('ruby').skill_counts.first.count).to eq(1) # ruby
|
371
378
|
end
|
372
379
|
|
@@ -375,7 +382,7 @@ describe 'Taggable' do
|
|
375
382
|
TaggableModel.create(name: 'Frank', tag_list: 'ruby, rails')
|
376
383
|
TaggableModel.create(name: 'Charlie', skill_list: 'ruby')
|
377
384
|
|
378
|
-
expect(TaggableModel.tagged_with('ruby').all_tag_counts(order:
|
385
|
+
expect(TaggableModel.tagged_with('ruby').all_tag_counts(order: "#{ActsAsTaggableOn.tags_table}.id").first.count).to eq(3) # ruby
|
379
386
|
end
|
380
387
|
|
381
388
|
it 'should be able to get all scoped tags' do
|
@@ -383,7 +390,7 @@ describe 'Taggable' do
|
|
383
390
|
TaggableModel.create(name: 'Frank', tag_list: 'ruby, rails')
|
384
391
|
TaggableModel.create(name: 'Charlie', skill_list: 'ruby')
|
385
392
|
|
386
|
-
expect(TaggableModel.tagged_with('ruby').all_tags(order:
|
393
|
+
expect(TaggableModel.tagged_with('ruby').all_tags(order: "#{ActsAsTaggableOn.tags_table}.id").first.name).to eq('ruby')
|
387
394
|
end
|
388
395
|
|
389
396
|
it 'should only return tag counts for the available scope' do
|
@@ -474,7 +481,7 @@ describe 'Taggable' do
|
|
474
481
|
|
475
482
|
expect(TaggableModel.tagged_with(%w(bob tricia), wild: true, any: true).to_a.sort_by { |o| o.id }).to eq([bob, frank, steve])
|
476
483
|
expect(TaggableModel.tagged_with(%w(bob tricia), wild: true, exclude: true).to_a).to eq([jim])
|
477
|
-
expect(TaggableModel.tagged_with('ji', wild: true, any: true).to_a
|
484
|
+
expect(TaggableModel.tagged_with('ji', wild: true, any: true).to_a).to match_array([frank, jim])
|
478
485
|
end
|
479
486
|
end
|
480
487
|
|
@@ -538,7 +545,7 @@ describe 'Taggable' do
|
|
538
545
|
|
539
546
|
it 'should not delete tags if not updated' do
|
540
547
|
model = TaggableModel.create(name: 'foo', tag_list: 'ruby, rails, programming')
|
541
|
-
model.
|
548
|
+
model.update(name: 'bar')
|
542
549
|
model.reload
|
543
550
|
expect(model.tag_list.sort).to eq(%w(ruby rails programming).sort)
|
544
551
|
end
|
@@ -669,15 +676,15 @@ describe 'Taggable' do
|
|
669
676
|
# NOTE: type column supports an STI Tag subclass in the test suite, though
|
670
677
|
# isn't included by default in the migration generator
|
671
678
|
expect(@taggable.grouped_column_names_for(ActsAsTaggableOn::Tag))
|
672
|
-
.to eq(
|
679
|
+
.to eq("#{ActsAsTaggableOn.tags_table}.id, #{ActsAsTaggableOn.tags_table}.name, #{ActsAsTaggableOn.tags_table}.taggings_count, #{ActsAsTaggableOn.tags_table}.type")
|
673
680
|
end
|
674
681
|
|
675
682
|
it 'should return all column names joined for TaggableModel GROUP clause' do
|
676
|
-
expect(@taggable.grouped_column_names_for(TaggableModel)).to eq('taggable_models.id, taggable_models.name, taggable_models.type')
|
683
|
+
expect(@taggable.grouped_column_names_for(TaggableModel)).to eq('taggable_models.id, taggable_models.name, taggable_models.type, taggable_models.tenant_id')
|
677
684
|
end
|
678
685
|
|
679
686
|
it 'should return all column names joined for NonStandardIdTaggableModel GROUP clause' do
|
680
|
-
expect(@taggable.grouped_column_names_for(TaggableModel)).to eq("taggable_models.#{TaggableModel.primary_key}, taggable_models.name, taggable_models.type")
|
687
|
+
expect(@taggable.grouped_column_names_for(TaggableModel)).to eq("taggable_models.#{TaggableModel.primary_key}, taggable_models.name, taggable_models.type, taggable_models.tenant_id")
|
681
688
|
end
|
682
689
|
end
|
683
690
|
|