acts-as-taggable-on 3.2.1 → 3.4.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 +4 -4
- data/.travis.yml +21 -1
- data/Appraisals +8 -6
- data/CHANGELOG.md +99 -10
- data/README.md +78 -11
- data/acts-as-taggable-on.gemspec +2 -4
- data/db/migrate/4_add_missing_taggable_index.rb +9 -0
- data/gemfiles/activerecord_3.2.gemfile +0 -1
- data/gemfiles/activerecord_4.0.gemfile +1 -2
- data/gemfiles/activerecord_4.1.gemfile +1 -2
- data/gemfiles/activerecord_4.2.gemfile +16 -0
- data/gemfiles/activerecord_edge.gemfile +0 -1
- data/lib/acts-as-taggable-on.rb +40 -21
- data/lib/acts_as_taggable_on/default_parser.rb +79 -0
- data/lib/acts_as_taggable_on/generic_parser.rb +19 -0
- data/lib/acts_as_taggable_on/tag.rb +6 -1
- data/lib/acts_as_taggable_on/tag_list.rb +20 -79
- data/lib/acts_as_taggable_on/tag_list_parser.rb +21 -0
- data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/cache.rb +1 -0
- data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/collection.rb +3 -1
- data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/core.rb +87 -51
- data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/ownership.rb +1 -1
- data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/related.rb +6 -6
- data/lib/acts_as_taggable_on/taggable.rb +7 -8
- data/lib/acts_as_taggable_on/tagging.rb +7 -1
- data/lib/acts_as_taggable_on/tags_helper.rb +2 -2
- data/lib/acts_as_taggable_on/utils.rb +26 -50
- data/lib/acts_as_taggable_on/version.rb +1 -1
- data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +1 -1
- data/spec/acts_as_taggable_on/acts_as_tagger_spec.rb +1 -0
- data/spec/acts_as_taggable_on/caching_spec.rb +1 -0
- data/spec/acts_as_taggable_on/default_parser_spec.rb +47 -0
- data/spec/acts_as_taggable_on/generic_parser_spec.rb +14 -0
- data/spec/acts_as_taggable_on/related_spec.rb +1 -0
- data/spec/acts_as_taggable_on/single_table_inheritance_spec.rb +1 -0
- data/spec/acts_as_taggable_on/tag_list_parser_spec.rb +46 -0
- data/spec/acts_as_taggable_on/tag_list_spec.rb +23 -31
- data/spec/acts_as_taggable_on/tag_spec.rb +54 -38
- data/spec/acts_as_taggable_on/taggable/dirty_spec.rb +127 -0
- data/spec/acts_as_taggable_on/taggable_spec.rb +84 -164
- data/spec/acts_as_taggable_on/tagger_spec.rb +1 -1
- data/spec/acts_as_taggable_on/tagging_spec.rb +37 -1
- data/spec/acts_as_taggable_on/tags_helper_spec.rb +1 -0
- data/spec/acts_as_taggable_on/utils_spec.rb +6 -11
- data/spec/internal/app/models/cached_model_with_array.rb +1 -1
- data/spec/internal/app/models/models.rb +2 -2
- data/spec/internal/db/schema.rb +2 -2
- data/spec/spec_helper.rb +0 -1
- data/spec/support/0-helpers.rb +32 -0
- data/spec/support/database_cleaner.rb +4 -0
- metadata +29 -52
- data/spec/bm.rb +0 -52
- data/spec/schema.rb +0 -82
- /data/lib/acts_as_taggable_on/{acts_as_taggable_on/compatibility.rb → compatibility.rb} +0 -0
- /data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/dirty.rb +0 -0
|
@@ -208,6 +208,14 @@ describe 'Taggable' do
|
|
|
208
208
|
expect(TaggableModel.tagged_with('ruby').group(:created_at).count.count).to eq(1)
|
|
209
209
|
end
|
|
210
210
|
|
|
211
|
+
it 'can be used as scope' do
|
|
212
|
+
@taggable.skill_list = 'ruby'
|
|
213
|
+
@taggable.save
|
|
214
|
+
untaggable_model = @taggable.untaggable_models.create!(name:'foobar')
|
|
215
|
+
scope_tag = TaggableModel.tagged_with('ruby', any: 'distinct', order: 'taggable_models.name asc')
|
|
216
|
+
expect(UntaggableModel.joins(:taggable_model).merge(scope_tag).except(:select)).to eq([untaggable_model])
|
|
217
|
+
end
|
|
218
|
+
|
|
211
219
|
it "shouldn't generate a query with DISTINCT by default" do
|
|
212
220
|
@taggable.skill_list = 'ruby, rails, css'
|
|
213
221
|
@taggable.save
|
|
@@ -215,6 +223,20 @@ describe 'Taggable' do
|
|
|
215
223
|
expect(TaggableModel.tagged_with('ruby').to_sql).to_not match /DISTINCT/
|
|
216
224
|
end
|
|
217
225
|
|
|
226
|
+
it "should be able to find a tag using dates" do
|
|
227
|
+
@taggable.skill_list = "ruby"
|
|
228
|
+
@taggable.save
|
|
229
|
+
|
|
230
|
+
expect(TaggableModel.tagged_with("ruby", :start_at => Date.today, :end_at => Date.tomorrow).count).to eq(1)
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
it "shouldn't be able to find a tag outside date range" do
|
|
234
|
+
@taggable.skill_list = "ruby"
|
|
235
|
+
@taggable.save
|
|
236
|
+
|
|
237
|
+
expect(TaggableModel.tagged_with("ruby", :start_at => Date.today - 2.days, :end_at => Date.today - 1.day).count).to eq(0)
|
|
238
|
+
end
|
|
239
|
+
|
|
218
240
|
it 'should be able to find by tag with context' do
|
|
219
241
|
@taggable.skill_list = 'ruby, rails, css'
|
|
220
242
|
@taggable.tag_list = 'bob, charlie'
|
|
@@ -255,16 +277,14 @@ describe 'Taggable' do
|
|
|
255
277
|
expect(TaggableModel.select('distinct(taggable_models.id), taggable_models.*').joins(:untaggable_models).tagged_with(['rails', 'ruby'], :any => false).to_a.sort).to eq([bob, frank].sort)
|
|
256
278
|
end
|
|
257
279
|
|
|
258
|
-
unless
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
TaggableModel.create(name: 'Katia', tag_list: 'ПРИВЕТ')
|
|
280
|
+
it 'should not care about case for unicode names', unless: using_sqlite? do
|
|
281
|
+
ActsAsTaggableOn.strict_case_match = false
|
|
282
|
+
TaggableModel.create(name: 'Anya', tag_list: 'ПРИВЕТ')
|
|
283
|
+
TaggableModel.create(name: 'Igor', tag_list: 'привет')
|
|
284
|
+
TaggableModel.create(name: 'Katia', tag_list: 'ПРИВЕТ')
|
|
264
285
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
end
|
|
286
|
+
expect(ActsAsTaggableOn::Tag.all.size).to eq(1)
|
|
287
|
+
expect(TaggableModel.tagged_with('привет').to_a).to eq(TaggableModel.tagged_with('ПРИВЕТ').to_a)
|
|
268
288
|
end
|
|
269
289
|
|
|
270
290
|
context 'should be able to create and find tags in languages without capitalization :' do
|
|
@@ -494,6 +514,19 @@ describe 'Taggable' do
|
|
|
494
514
|
end
|
|
495
515
|
end
|
|
496
516
|
|
|
517
|
+
it 'should options key not be deleted' do
|
|
518
|
+
options = {:exclude => true}
|
|
519
|
+
TaggableModel.tagged_with("foo", options)
|
|
520
|
+
expect(options).to eq({:exclude => true})
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
it 'should not delete tags if not updated' do
|
|
524
|
+
model = TaggableModel.create(name: 'foo', tag_list: 'ruby, rails, programming')
|
|
525
|
+
model.update_attributes(name: 'bar')
|
|
526
|
+
model.reload
|
|
527
|
+
expect(model.tag_list.sort).to eq(%w(ruby rails programming).sort)
|
|
528
|
+
end
|
|
529
|
+
|
|
497
530
|
context 'Duplicates' do
|
|
498
531
|
context 'should not create duplicate taggings' do
|
|
499
532
|
let(:bob) { TaggableModel.create(name: 'Bob') }
|
|
@@ -580,28 +613,26 @@ describe 'Taggable' do
|
|
|
580
613
|
|
|
581
614
|
end
|
|
582
615
|
|
|
583
|
-
if
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
connor.save
|
|
600
|
-
end
|
|
616
|
+
xit 'should not duplicate tags added on different threads', if: supports_concurrency?, skip: 'FIXME, Deadlocks in travis' do
|
|
617
|
+
#TODO, try with more threads and fix deadlock
|
|
618
|
+
thread_count = 4
|
|
619
|
+
barrier = Barrier.new thread_count
|
|
620
|
+
|
|
621
|
+
expect {
|
|
622
|
+
thread_count.times.map do |idx|
|
|
623
|
+
Thread.start do
|
|
624
|
+
connor = TaggableModel.first_or_create(name: 'Connor')
|
|
625
|
+
connor.tag_list = 'There, can, be, only, one'
|
|
626
|
+
barrier.wait
|
|
627
|
+
begin
|
|
628
|
+
connor.save
|
|
629
|
+
rescue ActsAsTaggableOn::DuplicateTagError
|
|
630
|
+
# second save should succeed
|
|
631
|
+
connor.save
|
|
601
632
|
end
|
|
602
|
-
end
|
|
603
|
-
|
|
604
|
-
|
|
633
|
+
end
|
|
634
|
+
end.map(&:join)
|
|
635
|
+
}.to change(ActsAsTaggableOn::Tag, :count).by(5)
|
|
605
636
|
end
|
|
606
637
|
end
|
|
607
638
|
|
|
@@ -621,8 +652,8 @@ describe 'Taggable' do
|
|
|
621
652
|
it 'should return all column names joined for Tag GROUP clause' do
|
|
622
653
|
# NOTE: type column supports an STI Tag subclass in the test suite, though
|
|
623
654
|
# isn't included by default in the migration generator
|
|
624
|
-
expect(@taggable.grouped_column_names_for(ActsAsTaggableOn::Tag))
|
|
625
|
-
|
|
655
|
+
expect(@taggable.grouped_column_names_for(ActsAsTaggableOn::Tag))
|
|
656
|
+
.to eq('tags.id, tags.name, tags.taggings_count, tags.type')
|
|
626
657
|
end
|
|
627
658
|
|
|
628
659
|
it 'should return all column names joined for TaggableModel GROUP clause' do
|
|
@@ -693,114 +724,6 @@ describe 'Taggable' do
|
|
|
693
724
|
end
|
|
694
725
|
end
|
|
695
726
|
|
|
696
|
-
describe 'Dirty Objects' do
|
|
697
|
-
context 'with un-contexted tags' do
|
|
698
|
-
before(:each) do
|
|
699
|
-
@taggable = TaggableModel.create(tag_list: 'awesome, epic')
|
|
700
|
-
end
|
|
701
|
-
|
|
702
|
-
context 'when tag_list changed' do
|
|
703
|
-
before(:each) do
|
|
704
|
-
expect(@taggable.changes).to be_empty
|
|
705
|
-
@taggable.tag_list = 'one'
|
|
706
|
-
end
|
|
707
|
-
|
|
708
|
-
it 'should show changes of dirty object' do
|
|
709
|
-
expect(@taggable.changes).to eq({'tag_list' => ['awesome, epic', ['one']]})
|
|
710
|
-
end
|
|
711
|
-
|
|
712
|
-
it 'flags tag_list as changed' do
|
|
713
|
-
expect(@taggable.tag_list_changed?).to be_truthy
|
|
714
|
-
end
|
|
715
|
-
|
|
716
|
-
it 'preserves original value' do
|
|
717
|
-
expect(@taggable.tag_list_was).to eq('awesome, epic')
|
|
718
|
-
end
|
|
719
|
-
|
|
720
|
-
it 'shows what the change was' do
|
|
721
|
-
expect(@taggable.tag_list_change).to eq(['awesome, epic', ['one']])
|
|
722
|
-
end
|
|
723
|
-
end
|
|
724
|
-
|
|
725
|
-
context 'when tag_list is the same' do
|
|
726
|
-
before(:each) do
|
|
727
|
-
@taggable.tag_list = 'awesome, epic'
|
|
728
|
-
end
|
|
729
|
-
|
|
730
|
-
it 'is not flagged as changed' do
|
|
731
|
-
expect(@taggable.tag_list_changed?).to be_falsy
|
|
732
|
-
end
|
|
733
|
-
|
|
734
|
-
it 'does not show any changes to the taggable item' do
|
|
735
|
-
expect(@taggable.changes).to be_empty
|
|
736
|
-
end
|
|
737
|
-
|
|
738
|
-
context "and using a delimiter different from a ','" do
|
|
739
|
-
before do
|
|
740
|
-
@old_delimiter = ActsAsTaggableOn.delimiter
|
|
741
|
-
ActsAsTaggableOn.delimiter = ';'
|
|
742
|
-
end
|
|
743
|
-
|
|
744
|
-
after do
|
|
745
|
-
ActsAsTaggableOn.delimiter = @old_delimiter
|
|
746
|
-
end
|
|
747
|
-
|
|
748
|
-
it 'does not show any changes to the taggable item when using array assignments' do
|
|
749
|
-
@taggable.tag_list = %w(awesome epic)
|
|
750
|
-
expect(@taggable.changes).to be_empty
|
|
751
|
-
end
|
|
752
|
-
end
|
|
753
|
-
end
|
|
754
|
-
end
|
|
755
|
-
|
|
756
|
-
context 'with context tags' do
|
|
757
|
-
before(:each) do
|
|
758
|
-
@taggable = TaggableModel.create('language_list' => 'awesome, epic')
|
|
759
|
-
end
|
|
760
|
-
|
|
761
|
-
context 'when language_list changed' do
|
|
762
|
-
before(:each) do
|
|
763
|
-
expect(@taggable.changes).to be_empty
|
|
764
|
-
@taggable.language_list = 'one'
|
|
765
|
-
end
|
|
766
|
-
|
|
767
|
-
it 'should show changes of dirty object' do
|
|
768
|
-
expect(@taggable.changes).to eq({'language_list' => ['awesome, epic', ['one']]})
|
|
769
|
-
end
|
|
770
|
-
|
|
771
|
-
it 'flags language_list as changed' do
|
|
772
|
-
expect(@taggable.language_list_changed?).to be_truthy
|
|
773
|
-
end
|
|
774
|
-
|
|
775
|
-
it 'preserves original value' do
|
|
776
|
-
expect(@taggable.language_list_was).to eq('awesome, epic')
|
|
777
|
-
end
|
|
778
|
-
|
|
779
|
-
it 'shows what the change was' do
|
|
780
|
-
expect(@taggable.language_list_change).to eq(['awesome, epic', ['one']])
|
|
781
|
-
end
|
|
782
|
-
|
|
783
|
-
it 'shows what the changes were' do
|
|
784
|
-
expect(@taggable.language_list_changes).to eq(['awesome, epic', ['one']])
|
|
785
|
-
end
|
|
786
|
-
end
|
|
787
|
-
|
|
788
|
-
context 'when language_list is the same' do
|
|
789
|
-
before(:each) do
|
|
790
|
-
@taggable.language_list = 'awesome, epic'
|
|
791
|
-
end
|
|
792
|
-
|
|
793
|
-
it 'is not flagged as changed' do
|
|
794
|
-
expect(@taggable.language_list_changed?).to be_falsy
|
|
795
|
-
end
|
|
796
|
-
|
|
797
|
-
it 'does not show any changes to the taggable item' do
|
|
798
|
-
expect(@taggable.changes).to be_empty
|
|
799
|
-
end
|
|
800
|
-
end
|
|
801
|
-
end
|
|
802
|
-
end
|
|
803
|
-
|
|
804
727
|
describe 'Autogenerated methods' do
|
|
805
728
|
it 'should be overridable' do
|
|
806
729
|
expect(TaggableModel.create(tag_list: 'woo').tag_list_submethod_called).to be_truthy
|
|
@@ -847,33 +770,30 @@ describe 'Taggable' do
|
|
|
847
770
|
end
|
|
848
771
|
end
|
|
849
772
|
|
|
773
|
+
describe 'Taggable model with json columns', if: postgresql_support_json? do
|
|
774
|
+
before(:each) do
|
|
775
|
+
@taggable = TaggableModelWithJson.new(:name => 'Bob Jones')
|
|
776
|
+
@taggables = [@taggable, TaggableModelWithJson.new(:name => 'John Doe')]
|
|
777
|
+
end
|
|
850
778
|
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
@taggables = [@taggable, TaggableModelWithJson.new(:name => 'John Doe')]
|
|
856
|
-
end
|
|
857
|
-
|
|
858
|
-
it 'should be able to find by tag with context' do
|
|
859
|
-
@taggable.skill_list = 'ruby, rails, css'
|
|
860
|
-
@taggable.tag_list = 'bob, charlie'
|
|
861
|
-
@taggable.save
|
|
779
|
+
it 'should be able to find by tag with context' do
|
|
780
|
+
@taggable.skill_list = 'ruby, rails, css'
|
|
781
|
+
@taggable.tag_list = 'bob, charlie'
|
|
782
|
+
@taggable.save
|
|
862
783
|
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
784
|
+
expect(TaggableModelWithJson.tagged_with('ruby').first).to eq(@taggable)
|
|
785
|
+
expect(TaggableModelWithJson.tagged_with('ruby, css').first).to eq(@taggable)
|
|
786
|
+
expect(TaggableModelWithJson.tagged_with('bob', :on => :skills).first).to_not eq(@taggable)
|
|
787
|
+
expect(TaggableModelWithJson.tagged_with('bob', :on => :tags).first).to eq(@taggable)
|
|
788
|
+
end
|
|
868
789
|
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
790
|
+
it 'should be able to find tagged with any tag' do
|
|
791
|
+
bob = TaggableModelWithJson.create(:name => 'Bob', :tag_list => 'fitter, happier, more productive', :skill_list => 'ruby, rails, css')
|
|
792
|
+
frank = TaggableModelWithJson.create(:name => 'Frank', :tag_list => 'weaker, depressed, inefficient', :skill_list => 'ruby, rails, css')
|
|
793
|
+
steve = TaggableModelWithJson.create(:name => 'Steve', :tag_list => 'fitter, happier, more productive', :skill_list => 'c++, java, ruby')
|
|
873
794
|
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
end
|
|
795
|
+
expect(TaggableModelWithJson.tagged_with(%w(ruby java), :order => 'taggable_model_with_jsons.name', :any => true).to_a).to eq([bob, frank, steve])
|
|
796
|
+
expect(TaggableModelWithJson.tagged_with(%w(c++ fitter), :order => 'taggable_model_with_jsons.name', :any => true).to_a).to eq([bob, steve])
|
|
797
|
+
expect(TaggableModelWithJson.tagged_with(%w(depressed css), :order => 'taggable_model_with_jsons.name', :any => true).to_a).to eq([bob, frank])
|
|
878
798
|
end
|
|
879
799
|
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
|
1
2
|
require 'spec_helper'
|
|
2
3
|
|
|
3
4
|
describe 'Tagger' do
|
|
@@ -43,7 +44,6 @@ describe 'Tagger' do
|
|
|
43
44
|
tags = TaggableModel.tagged_with(%w(ruby java), owned_by: @user, any: true)
|
|
44
45
|
expect(tags).to include(@taggable, @taggable2)
|
|
45
46
|
expect(tags.size).to eq(2)
|
|
46
|
-
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
it 'only returns objects tagged by owned_by when exclude is true' do
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
|
1
2
|
require 'spec_helper'
|
|
2
3
|
|
|
3
4
|
describe ActsAsTaggableOn::Tagging do
|
|
@@ -23,5 +24,40 @@ describe ActsAsTaggableOn::Tagging do
|
|
|
23
24
|
2.times { ActsAsTaggableOn::Tagging.create(taggable: @taggable, tag: @tag, context: 'tags') }
|
|
24
25
|
}).to change(ActsAsTaggableOn::Tagging, :count).by(1)
|
|
25
26
|
end
|
|
26
|
-
|
|
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
|
+
pending 'context scopes' do
|
|
53
|
+
describe '.by_context'
|
|
54
|
+
|
|
55
|
+
describe '.by_contexts'
|
|
56
|
+
|
|
57
|
+
describe '.owned_by'
|
|
58
|
+
|
|
59
|
+
describe '.not_owned'
|
|
60
|
+
|
|
61
|
+
end
|
|
62
|
+
|
|
27
63
|
end
|
|
@@ -1,21 +1,16 @@
|
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
|
1
2
|
require 'spec_helper'
|
|
2
3
|
|
|
3
4
|
describe ActsAsTaggableOn::Utils do
|
|
4
|
-
describe 'like_operator' do
|
|
5
|
-
before(:each) do
|
|
6
|
-
TaggableModel.acts_as_taggable_on(:tags, :languages, :skills, :needs, :offerings)
|
|
7
|
-
@taggable = TaggableModel.new(name: 'Bob Jones')
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
describe '#like_operator' do
|
|
11
6
|
it 'should return \'ILIKE\' when the adapter is PostgreSQL' do
|
|
12
|
-
allow(
|
|
13
|
-
expect(
|
|
7
|
+
allow(ActsAsTaggableOn::Utils.connection).to receive(:adapter_name) { 'PostgreSQL' }
|
|
8
|
+
expect(ActsAsTaggableOn::Utils.like_operator).to eq('ILIKE')
|
|
14
9
|
end
|
|
15
10
|
|
|
16
11
|
it 'should return \'LIKE\' when the adapter is not PostgreSQL' do
|
|
17
|
-
allow(
|
|
18
|
-
expect(
|
|
12
|
+
allow(ActsAsTaggableOn::Utils.connection).to receive(:adapter_name) { 'MySQL' }
|
|
13
|
+
expect(ActsAsTaggableOn::Utils.like_operator).to eq('LIKE')
|
|
19
14
|
end
|
|
20
15
|
end
|
|
21
16
|
end
|
|
@@ -77,11 +77,11 @@ class OrderedTaggableModel < ActiveRecord::Base
|
|
|
77
77
|
acts_as_ordered_taggable_on :colours
|
|
78
78
|
end
|
|
79
79
|
|
|
80
|
-
if
|
|
80
|
+
if using_postgresql?
|
|
81
81
|
class CachedModelWithArray < ActiveRecord::Base
|
|
82
82
|
acts_as_taggable
|
|
83
83
|
end
|
|
84
|
-
if
|
|
84
|
+
if postgresql_support_json?
|
|
85
85
|
class TaggableModelWithJson < ActiveRecord::Base
|
|
86
86
|
acts_as_taggable
|
|
87
87
|
acts_as_taggable_on :skills
|
data/spec/internal/db/schema.rb
CHANGED
|
@@ -76,7 +76,7 @@ ActiveRecord::Schema.define version: 0 do
|
|
|
76
76
|
|
|
77
77
|
|
|
78
78
|
# Special cases for postgresql
|
|
79
|
-
if
|
|
79
|
+
if using_postgresql?
|
|
80
80
|
|
|
81
81
|
create_table :other_cached_with_array_models, force: true do |t|
|
|
82
82
|
t.column :name, :string
|
|
@@ -86,7 +86,7 @@ ActiveRecord::Schema.define version: 0 do
|
|
|
86
86
|
t.column :cached_glass_list, :string, array: true
|
|
87
87
|
end
|
|
88
88
|
|
|
89
|
-
if
|
|
89
|
+
if postgresql_support_json?
|
|
90
90
|
create_table :taggable_model_with_jsons, :force => true do |t|
|
|
91
91
|
t.column :name, :string
|
|
92
92
|
t.column :type, :string
|
data/spec/spec_helper.rb
CHANGED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
def using_sqlite?
|
|
2
|
+
ActsAsTaggableOn::Utils.connection && ActsAsTaggableOn::Utils.connection.adapter_name == 'SQLite'
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
def supports_concurrency?
|
|
6
|
+
!using_sqlite?
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def using_postgresql?
|
|
10
|
+
ActsAsTaggableOn::Utils.using_postgresql?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def postgresql_version
|
|
14
|
+
if using_postgresql?
|
|
15
|
+
ActsAsTaggableOn::Utils.connection.execute('SHOW SERVER_VERSION').first['server_version'].to_f
|
|
16
|
+
else
|
|
17
|
+
0.0
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def postgresql_support_json?
|
|
22
|
+
postgresql_version >= 9.2
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def using_mysql?
|
|
27
|
+
ActsAsTaggableOn::Utils.using_mysql?
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def using_case_insensitive_collation?
|
|
31
|
+
using_mysql? && ActsAsTaggableOn::Utils.connection.collation =~ /_ci\Z/
|
|
32
|
+
end
|