acts-as-taggable-on 3.5.0 → 4.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +14 -18
  4. data/Appraisals +9 -8
  5. data/CHANGELOG.md +3 -1
  6. data/Gemfile +1 -1
  7. data/README.md +41 -3
  8. data/acts-as-taggable-on.gemspec +3 -3
  9. data/db/migrate/2_add_missing_unique_indices.rb +3 -2
  10. data/db/migrate/6_add_missing_indexes.rb +12 -0
  11. data/gemfiles/activerecord_4.0.gemfile +3 -2
  12. data/gemfiles/activerecord_4.1.gemfile +3 -2
  13. data/gemfiles/activerecord_4.2.gemfile +2 -3
  14. data/gemfiles/{activerecord_3.2.gemfile → activerecord_5.0.gemfile} +2 -2
  15. data/lib/acts-as-taggable-on.rb +16 -12
  16. data/lib/acts_as_taggable_on/engine.rb +0 -1
  17. data/lib/acts_as_taggable_on/tag.rb +6 -2
  18. data/lib/acts_as_taggable_on/tag_list.rb +2 -13
  19. data/lib/acts_as_taggable_on/taggable/cache.rb +1 -1
  20. data/lib/acts_as_taggable_on/taggable/collection.rb +6 -3
  21. data/lib/acts_as_taggable_on/taggable/core.rb +21 -16
  22. data/lib/acts_as_taggable_on/taggable/ownership.rb +3 -3
  23. data/lib/acts_as_taggable_on/tagger.rb +12 -11
  24. data/lib/acts_as_taggable_on/tagging.rb +4 -14
  25. data/lib/acts_as_taggable_on/utils.rb +2 -3
  26. data/lib/acts_as_taggable_on/version.rb +1 -1
  27. data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +10 -1
  28. data/spec/acts_as_taggable_on/acts_as_tagger_spec.rb +1 -1
  29. data/spec/acts_as_taggable_on/caching_spec.rb +22 -0
  30. data/spec/acts_as_taggable_on/tag_list_spec.rb +27 -1
  31. data/spec/acts_as_taggable_on/tag_spec.rb +15 -0
  32. data/spec/acts_as_taggable_on/taggable_spec.rb +19 -5
  33. data/spec/acts_as_taggable_on/tagging_spec.rb +64 -10
  34. data/spec/internal/db/schema.rb +7 -3
  35. data/spec/support/database.rb +1 -7
  36. metadata +12 -21
  37. data/lib/acts_as_taggable_on/compatibility.rb +0 -35
  38. data/lib/acts_as_taggable_on/tag_list_parser.rb +0 -21
  39. data/spec/acts_as_taggable_on/tag_list_parser_spec.rb +0 -46
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 92222646174fc38e87d9972cea2022c78e9ba337
4
- data.tar.gz: 62d819d54ea8d538ce67d1f30c4c640e63333328
3
+ metadata.gz: 8c10b1bdc1cfdce1f5faa7db0cb813257657bcda
4
+ data.tar.gz: fdc07fbeaf0a0fe45e1410b2f6a52078a168ff8d
5
5
  SHA512:
6
- metadata.gz: 6a17ce74f9d91e98037faa3348449813632f2f1ba2a4ca92a297beaafa8e544b650c2e12586c03a9aab8c2c6b0b5c1c1de21571d860be49aed971b0d20b8338e
7
- data.tar.gz: d50ea8e8200c3eaef6f1d80b53412637604e74de62dd3a2e6385e22d1fbf579bbb372f2bbd9b6c026f3f062e4959a288a5a890360d5f98cde6df222ebc72947f
6
+ metadata.gz: 1542dd8c7ebafeed4794f6f734da1e98f9641d7ddda18fa93c7e49ec4d5b14867353e065a6f3598050d0606f3e2809c5034a07c9f91385f22c90159dad202c50
7
+ data.tar.gz: aba26b02cbc655676003bfb6d73092ab49dae44013985a6838b187b3f4920507e684e73fab8a53c7d8b11e036cbc58a608943e3116ebee4ff10bf7df8fea6e80
data/.gitignore CHANGED
@@ -9,3 +9,5 @@ tmp*.sw?
9
9
  tmp
10
10
  *.gem
11
11
  *.lock
12
+
13
+ /.idea
@@ -1,11 +1,11 @@
1
1
  language: ruby
2
+ cache: bundler
2
3
 
3
4
  rvm:
5
+ - 2.3.1
6
+ - 2.2.5
4
7
  - 2.1
5
- - 2.2
6
8
  - 2.0.0
7
- - 1.9.3
8
- - rbx-2
9
9
 
10
10
  env:
11
11
  - DB=sqlite3
@@ -13,28 +13,24 @@ env:
13
13
  - DB=postgresql
14
14
 
15
15
  gemfile:
16
- - gemfiles/activerecord_3.2.gemfile
17
- - gemfiles/activerecord_4.0.gemfile
16
+ - gemfiles/activerecord_5.0.gemfile
17
+ - gemfiles/activerecord_4.2.gemfile
18
18
  - gemfiles/activerecord_4.1.gemfile
19
+ - gemfiles/activerecord_4.0.gemfile
19
20
 
20
21
  sudo: false
21
22
 
22
23
  bundler_args: '--without local_development --jobs 3 --retry 3'
23
24
 
25
+ before_install:
26
+ - gem install bundler
27
+
24
28
  script: bundle exec rake
25
29
 
26
30
  matrix:
27
- fast_finish: true
28
- allow_failures:
29
- - gemfile: gemfiles/activerecord_edge.gemfile
30
- - rvm: rbx-2
31
31
  exclude:
32
- - rvm: 2.2
33
- gemfile: gemfiles/activerecord_3.2.gemfile
34
- - rvm: 1.9.3
35
- gemfile: gemfiles/activerecord_4.0.gemfile
36
- - rvm: 1.9.3
37
- gemfile: gemfiles/activerecord_4.1.gemfile
38
- - rvm: rbx-2
39
- gemfile: gemfiles/activerecord_3.2.gemfile
40
-
32
+ - rvm: 2.0.0
33
+ gemfile: gemfiles/activerecord_5.0.gemfile
34
+ - rvm: 2.1
35
+ gemfile: gemfiles/activerecord_5.0.gemfile
36
+ fast_finish: true
data/Appraisals CHANGED
@@ -1,16 +1,17 @@
1
- appraise "activerecord-3.2" do
2
- gem "activerecord", github: "rails/rails" , branch: '3-2-stable'
1
+ appraise 'activerecord-5.0' do
2
+ gem 'activerecord', "~> 5.0.0"
3
3
  end
4
4
 
5
- appraise "activerecord-4.0" do
6
- gem "activerecord", github: "rails/rails" , branch: '4-0-stable'
5
+ appraise "activerecord-4.2" do
6
+ gem "activerecord", "~> 4.2.0"
7
7
  end
8
8
 
9
9
  appraise "activerecord-4.1" do
10
- gem "activerecord", github: "rails/rails" , branch: '4-1-stable'
10
+ gem "activerecord", "~> 4.1.0"
11
+ gem 'mysql2', '~> 0.3.21'
11
12
  end
12
13
 
13
- appraise "activerecord-4.2" do
14
- gem "railties", github: "rails/rails" , branch: '4-2-stable'
15
- gem "activerecord", github: "rails/rails" , branch: '4-2-stable'
14
+ appraise "activerecord-4.0" do
15
+ gem "activerecord", "~> 4.0.0"
16
+ gem 'mysql2', '~> 0.3.21'
16
17
  end
@@ -4,10 +4,12 @@ Each change should fall into categories that would affect whether the release is
4
4
 
5
5
  As such, a _Feature_ would map to either major or minor. A _bug fix_ to a patch. And _misc_ is either minor or patch, the difference being kind of fuzzy for the purposes of history. Adding tests would be patch level.
6
6
 
7
- ### [3.5.0 / 2015-02-11](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.4.4...v3.5.0)
7
+ ### [3.5.0 / 2015-03-03](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.4.4...v3.5.0)
8
8
 
9
9
  * Fixes
10
10
  * [@rikettsie Fixed collation for MySql via rake rule or config parameter](https://github.com/mbleigh/acts-as-taggable-on/pull/634)
11
+ *Misc
12
+ * [@pcupueran Add rspec test for tagging_spec completeness]()
11
13
 
12
14
  ### [3.4.4 / 2015-02-11](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.4.3...v3.4.4)
13
15
 
data/Gemfile CHANGED
@@ -7,5 +7,5 @@ group :local_development do
7
7
  gem 'guard-rspec'
8
8
  gem 'appraisal'
9
9
  gem 'rake'
10
- gem 'byebug' , platform: :mri_21
10
+ gem 'byebug' , platforms: [:mri_21, :mri_22, :mri_23]
11
11
  end
data/README.md CHANGED
@@ -1,4 +1,6 @@
1
1
  # ActsAsTaggableOn
2
+
3
+ [![Join the chat at https://gitter.im/mbleigh/acts-as-taggable-on](https://badges.gitter.im/mbleigh/acts-as-taggable-on.svg)](https://gitter.im/mbleigh/acts-as-taggable-on?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
2
4
  [![Gem Version](https://badge.fury.io/rb/acts-as-taggable-on.svg)](http://badge.fury.io/rb/acts-as-taggable-on)
3
5
  [![Build Status](https://secure.travis-ci.org/mbleigh/acts-as-taggable-on.png)](http://travis-ci.org/mbleigh/acts-as-taggable-on)
4
6
  [![Code Climate](https://codeclimate.com/github/mbleigh/acts-as-taggable-on.png)](https://codeclimate.com/github/mbleigh/acts-as-taggable-on)
@@ -89,7 +91,7 @@ end
89
91
 
90
92
  class UsersController < ApplicationController
91
93
  def user_params
92
- params.require(:user).permit(:name, :tag_list => []) ## Rails 4 strong params usage
94
+ params.require(:user).permit(:name, :tag_list) ## Rails 4 strong params usage
93
95
  end
94
96
  end
95
97
 
@@ -273,7 +275,7 @@ User.tagged_with("same", :on => :customs) # => [@user]
273
275
 
274
276
  ### Tag Parsers
275
277
 
276
- If you want to change how tags are parsed, you can define a your own implementation:
278
+ If you want to change how tags are parsed, you can define your own implementation:
277
279
 
278
280
  ```ruby
279
281
  class MyParser < ActsAsTaggableOn::GenericParser
@@ -302,7 +304,7 @@ Now you can use this parser, passing it as parameter:
302
304
  Or change it globally:
303
305
 
304
306
  ```ruby
305
- ActsAsTaggable.default_parser = MyParser
307
+ ActsAsTaggableOn.default_parser = MyParser
306
308
  @user = User.new(:name => "Bobby")
307
309
  @user.tag_list = "east|south"
308
310
  @user.tag_list # => ["east", "south"]
@@ -331,6 +333,42 @@ Photo.tagged_with("paris", :on => :locations, :owned_by => @some_user)
331
333
  @some_user.tag(@some_photo, :with => "paris, normandy", :on => :locations, :skip_save => true) #won't save @some_photo object
332
334
  ```
333
335
 
336
+ #### Working with Owned Tags
337
+ Note that `tag_list` only returns tags whose taggings do not have an owner. Continuing from the above example:
338
+ ```ruby
339
+ @some_photo.tag_list # => []
340
+ ```
341
+ To retrieve all tags of an object (regardless of ownership) or if only one owner can tag the object, use `all_tags_list`.
342
+
343
+ ##### Adding owned tags
344
+ Note that **owned tags** are added all at once, in the form of ***comma seperated tags*** in string.
345
+ Also, when you try to add **owned tags** again, it simply overwrites the previous set of **owned tags**.
346
+ So to append tags in previously existing **owned tags** list, go as follows:
347
+ ```ruby
348
+ def add_owned_tag
349
+ @some_item = Item.find(params[:id])
350
+ owned_tag_list = @some_item.all_tag_list - @some_item.tag_list
351
+ owned_tag_list += [(params[:tag])]
352
+ @tag_owner.tag(@some_item, :with => stringify(owned_tag_list), :on => :tags)
353
+ @some_item.save
354
+ end
355
+
356
+ def stringify(tag_list)
357
+ tag_list.inject('') { |memo, tag| memo += (tag + ',') }[0..-1]
358
+ end
359
+ ```
360
+ ##### Removing owned tags
361
+ Similarly as above, removing will be as follows:
362
+ ```ruby
363
+ def remove_owned_tag
364
+ @some_item = Item.find(params[:id])
365
+ owned_tag_list = @some_item.all_tag_list - @some_item.tag_list
366
+ owned_tag_list -= [(params[:tag])]
367
+ @tag_owner.tag(@some_item, :with => stringify(owned_tag_list), :on => :tags)
368
+ @some_item.save
369
+ end
370
+ ```
371
+
334
372
  ### Dirty objects
335
373
 
336
374
  ```ruby
@@ -16,16 +16,16 @@ Gem::Specification.new do |gem|
16
16
  gem.files = `git ls-files`.split($/)
17
17
  gem.test_files = gem.files.grep(%r{^spec/})
18
18
  gem.require_paths = ['lib']
19
- gem.required_ruby_version = '>= 1.9.3'
19
+ gem.required_ruby_version = '>= 2.0.0'
20
20
 
21
21
  if File.exist?('UPGRADING.md')
22
22
  gem.post_install_message = File.read('UPGRADING.md')
23
23
  end
24
24
 
25
- gem.add_runtime_dependency 'activerecord', ['>= 3.2', '< 5']
25
+ gem.add_runtime_dependency 'activerecord', ['>= 4.0']
26
26
 
27
27
  gem.add_development_dependency 'sqlite3'
28
- gem.add_development_dependency 'mysql2', '~> 0.3.7'
28
+ gem.add_development_dependency 'mysql2', '~> 0.3'
29
29
  gem.add_development_dependency 'pg'
30
30
 
31
31
  gem.add_development_dependency 'rspec-rails'
@@ -2,7 +2,7 @@ class AddMissingUniqueIndices < ActiveRecord::Migration
2
2
  def self.up
3
3
  add_index :tags, :name, unique: true
4
4
 
5
- remove_index :taggings, :tag_id
5
+ remove_index :taggings, :tag_id if index_exists?(:taggings, :tag_id)
6
6
  remove_index :taggings, [:taggable_id, :taggable_type, :context]
7
7
  add_index :taggings,
8
8
  [:tag_id, :taggable_id, :taggable_type, :context, :tagger_id, :tagger_type],
@@ -13,7 +13,8 @@ class AddMissingUniqueIndices < ActiveRecord::Migration
13
13
  remove_index :tags, :name
14
14
 
15
15
  remove_index :taggings, name: 'taggings_idx'
16
- add_index :taggings, :tag_id
16
+
17
+ add_index :taggings, :tag_id unless index_exists?(:taggings, :tag_id)
17
18
  add_index :taggings, [:taggable_id, :taggable_type, :context]
18
19
  end
19
20
  end
@@ -0,0 +1,12 @@
1
+ class AddMissingIndexes < ActiveRecord::Migration
2
+ def change
3
+ add_index :taggings, :tag_id
4
+ add_index :taggings, :taggable_id
5
+ add_index :taggings, :taggable_type
6
+ add_index :taggings, :tagger_id
7
+ add_index :taggings, :context
8
+
9
+ add_index :taggings, [:tagger_id, :tagger_type]
10
+ add_index :taggings, [:taggable_id, :taggable_type, :tagger_id, :context], name: 'taggings_idy'
11
+ end
12
+ end
@@ -2,14 +2,15 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activerecord", :github => "rails/rails", :branch => "4-0-stable"
5
+ gem "activerecord", "~> 4.0.0"
6
+ gem "mysql2", "~> 0.3.21"
6
7
 
7
8
  group :local_development do
8
9
  gem "guard"
9
10
  gem "guard-rspec"
10
11
  gem "appraisal"
11
12
  gem "rake"
12
- gem "byebug", :platform => :mri_21
13
+ gem "byebug", :platforms => [:mri_21, :mri_22, :mri_23]
13
14
  end
14
15
 
15
16
  gemspec :path => "../"
@@ -2,14 +2,15 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activerecord", :github => "rails/rails", :branch => "4-1-stable"
5
+ gem "activerecord", "~> 4.1.0"
6
+ gem "mysql2", "~> 0.3.21"
6
7
 
7
8
  group :local_development do
8
9
  gem "guard"
9
10
  gem "guard-rspec"
10
11
  gem "appraisal"
11
12
  gem "rake"
12
- gem "byebug", :platform => :mri_21
13
+ gem "byebug", :platforms => [:mri_21, :mri_22, :mri_23]
13
14
  end
14
15
 
15
16
  gemspec :path => "../"
@@ -2,15 +2,14 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "railties", :github => "rails/rails", :branch => "4-2-stable"
6
- gem "activerecord", :github => "rails/rails", :branch => "4-2-stable"
5
+ gem "activerecord", "~> 4.2.0"
7
6
 
8
7
  group :local_development do
9
8
  gem "guard"
10
9
  gem "guard-rspec"
11
10
  gem "appraisal"
12
11
  gem "rake"
13
- gem "byebug", :platform => :mri_21
12
+ gem "byebug", :platforms => [:mri_21, :mri_22, :mri_23]
14
13
  end
15
14
 
16
15
  gemspec :path => "../"
@@ -2,14 +2,14 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activerecord", :github => "rails/rails", :branch => "3-2-stable"
5
+ gem "activerecord", "~> 5.0.0"
6
6
 
7
7
  group :local_development do
8
8
  gem "guard"
9
9
  gem "guard-rspec"
10
10
  gem "appraisal"
11
11
  gem "rake"
12
- gem "byebug", :platform => :mri_21
12
+ gem "byebug", :platforms => [:mri_21, :mri_22, :mri_23]
13
13
  end
14
14
 
15
15
  gemspec :path => "../"
@@ -2,7 +2,12 @@ require 'active_record'
2
2
  require 'active_record/version'
3
3
  require 'active_support/core_ext/module'
4
4
 
5
- require_relative 'acts_as_taggable_on/engine' if defined?(Rails)
5
+ begin
6
+ require 'rails/engine'
7
+ require 'acts_as_taggable_on/engine'
8
+ rescue LoadError
9
+
10
+ end
6
11
 
7
12
  require 'digest/sha1'
8
13
 
@@ -13,7 +18,6 @@ module ActsAsTaggableOn
13
18
  autoload :TagList
14
19
  autoload :GenericParser
15
20
  autoload :DefaultParser
16
- autoload :TagListParser
17
21
  autoload :Taggable
18
22
  autoload :Tagger
19
23
  autoload :Tagging
@@ -57,9 +61,10 @@ module ActsAsTaggableOn
57
61
  end
58
62
 
59
63
  class Configuration
60
- attr_accessor :delimiter, :force_lowercase, :force_parameterize,
61
- :strict_case_match, :remove_unused_tags, :default_parser,
64
+ attr_accessor :force_lowercase, :force_parameterize,
65
+ :remove_unused_tags, :default_parser,
62
66
  :tags_counter
67
+ attr_reader :delimiter, :strict_case_match
63
68
 
64
69
  def initialize
65
70
  @delimiter = ','
@@ -73,9 +78,7 @@ module ActsAsTaggableOn
73
78
  end
74
79
 
75
80
  def strict_case_match=(force_cs)
76
- if @force_binary_collation == false
77
- @strict_case_match = force_cs
78
- end
81
+ @strict_case_match = force_cs unless @force_binary_collation
79
82
  end
80
83
 
81
84
  def delimiter=(string)
@@ -89,7 +92,7 @@ WARNING
89
92
 
90
93
  def force_binary_collation=(force_bin)
91
94
  if Utils.using_mysql?
92
- if force_bin == true
95
+ if force_bin
93
96
  Configuration.apply_binary_collation(true)
94
97
  @force_binary_collation = true
95
98
  @strict_case_match = true
@@ -103,10 +106,12 @@ WARNING
103
106
  def self.apply_binary_collation(bincoll)
104
107
  if Utils.using_mysql?
105
108
  coll = 'utf8_general_ci'
106
- if bincoll == true
107
- coll = 'utf8_bin'
109
+ coll = 'utf8_bin' if bincoll
110
+ begin
111
+ ActiveRecord::Migration.execute("ALTER TABLE #{Tag.table_name} MODIFY name varchar(255) CHARACTER SET utf8 COLLATE #{coll};")
112
+ rescue Exception => e
113
+ puts "Trapping #{e.class}: collation parameter ignored while migrating for the first time."
108
114
  end
109
- ActiveRecord::Migration.execute("ALTER TABLE tags MODIFY name varchar(255) CHARACTER SET utf8 COLLATE #{coll};")
110
115
  end
111
116
  end
112
117
 
@@ -116,7 +121,6 @@ WARNING
116
121
  end
117
122
 
118
123
  ActiveSupport.on_load(:active_record) do
119
- extend ActsAsTaggableOn::Compatibility
120
124
  extend ActsAsTaggableOn::Taggable
121
125
  include ActsAsTaggableOn::Tagger
122
126
  end
@@ -1,4 +1,3 @@
1
- require 'rails/engine'
2
1
  module ActsAsTaggableOn
3
2
  class Engine < Rails::Engine
4
3
  end
@@ -2,8 +2,6 @@
2
2
  module ActsAsTaggableOn
3
3
  class Tag < ::ActiveRecord::Base
4
4
 
5
- attr_accessible :name if defined?(ActiveModel::MassAssignmentSecurity)
6
-
7
5
  ### ASSOCIATIONS:
8
6
 
9
7
  has_many :taggings, dependent: :destroy, class_name: '::ActsAsTaggableOn::Tagging'
@@ -50,6 +48,12 @@ module ActsAsTaggableOn
50
48
  where(clause)
51
49
  end
52
50
 
51
+ def self.for_context(context)
52
+ joins(:taggings).
53
+ where(["taggings.context = ?", context]).
54
+ select("DISTINCT tags.*")
55
+ end
56
+
53
57
  ### CLASS METHODS:
54
58
 
55
59
  def self.find_or_create_with_like_by_name(name)
@@ -84,7 +84,8 @@ module ActsAsTaggableOn
84
84
  map! { |tag| tag.mb_chars.downcase.to_s } if ActsAsTaggableOn.force_lowercase
85
85
  map!(&:parameterize) if ActsAsTaggableOn.force_parameterize
86
86
 
87
- uniq!
87
+ ActsAsTaggableOn.strict_case_match ? uniq! : uniq!{ |tag| tag.downcase }
88
+ self
88
89
  end
89
90
 
90
91
 
@@ -99,18 +100,6 @@ module ActsAsTaggableOn
99
100
  args.flatten!
100
101
  end
101
102
 
102
-
103
- ## DEPRECATED
104
- def self.from(string)
105
- ActiveRecord::Base.logger.warn <<WARNING
106
- ActsAsTaggableOn::TagList.from is deprecated \
107
- and will be removed from v4.0+, use \
108
- ActsAsTaggableOn::DefaultParser.new instead
109
- WARNING
110
- @parser.new(string).parse
111
- end
112
-
113
-
114
103
  end
115
104
  end
116
105
 
@@ -73,7 +73,7 @@ module ActsAsTaggableOn::Taggable
73
73
  tag_types.map(&:to_s).each do |tag_type|
74
74
  if self.class.send("caching_#{tag_type.singularize}_list?")
75
75
  if tag_list_cache_set_on(tag_type)
76
- list = tag_list_cache_on(tag_type).to_a.flatten.compact.join(', ')
76
+ list = tag_list_cache_on(tag_type).to_a.flatten.compact.join("#{ActsAsTaggableOn.delimiter} ")
77
77
  self["cached_#{tag_type.singularize}_list"] = list
78
78
  end
79
79
  end
@@ -138,7 +138,7 @@ module ActsAsTaggableOn::Taggable
138
138
  scoped_ids = pluck(table_name_pkey)
139
139
  tagging_scope = tagging_scope.where("#{ActsAsTaggableOn::Tagging.table_name}.taggable_id IN (?)", scoped_ids)
140
140
  else
141
- tagging_scope = tagging_scope.where("#{ActsAsTaggableOn::Tagging.table_name}.taggable_id IN(#{safe_to_sql(select(table_name_pkey))})")
141
+ tagging_scope = tagging_scope.where("#{ActsAsTaggableOn::Tagging.table_name}.taggable_id IN(#{safe_to_sql(except(:select).select(table_name_pkey))})")
142
142
  end
143
143
 
144
144
  tagging_scope
@@ -169,9 +169,12 @@ module ActsAsTaggableOn::Taggable
169
169
  end
170
170
 
171
171
  module CalculationMethods
172
- def count(column_name=:all, options = {})
172
+ # Rails 5 TODO: Remove options argument as soon we remove support to
173
+ # activerecord-deprecated_finders.
174
+ # See https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation/calculations.rb#L38
175
+ def count(column_name = :all, options = {})
173
176
  # https://github.com/rails/rails/commit/da9b5d4a8435b744fcf278fffd6d7f1e36d4a4f2
174
- super
177
+ ActsAsTaggableOn::Utils.active_record5? ? super(column_name) : super(column_name, options)
175
178
  end
176
179
  end
177
180
  end
@@ -23,18 +23,15 @@ module ActsAsTaggableOn::Taggable
23
23
  class_eval do
24
24
  # when preserving tag order, include order option so that for a 'tags' context
25
25
  # the associations tag_taggings & tags are always returned in created order
26
- has_many_with_taggable_compatibility context_taggings, as: :taggable,
27
- dependent: :destroy,
28
- class_name: 'ActsAsTaggableOn::Tagging',
29
- order: taggings_order,
30
- conditions: {context: tags_type},
31
- include: :tag
32
-
33
- has_many_with_taggable_compatibility context_tags, through: context_taggings,
34
- source: :tag,
35
- class_name: 'ActsAsTaggableOn::Tag',
36
- order: taggings_order
37
-
26
+ has_many context_taggings, -> { includes(:tag).order(taggings_order).where(context: tags_type) },
27
+ as: :taggable,
28
+ class_name: ActsAsTaggableOn::Tagging,
29
+ dependent: :destroy
30
+
31
+ has_many context_tags, -> { order(taggings_order) },
32
+ class_name: ActsAsTaggableOn::Tag,
33
+ through: context_taggings,
34
+ source: :tag
38
35
  end
39
36
 
40
37
  taggable_mixin.class_eval <<-RUBY, __FILE__, __LINE__ + 1
@@ -246,6 +243,14 @@ module ActsAsTaggableOn::Taggable
246
243
  def taggable_mixin
247
244
  @taggable_mixin ||= Module.new
248
245
  end
246
+
247
+ private
248
+
249
+ # Rails 5 has merged sanitize and quote_value
250
+ # See https://github.com/rails/rails/blob/master/activerecord/lib/active_record/sanitization.rb#L10
251
+ def quote_value(value, column = nil)
252
+ ActsAsTaggableOn::Utils.active_record5? ? super(value) : super(value, column)
253
+ end
249
254
  end
250
255
 
251
256
  # all column names are necessary for PostgreSQL group clause
@@ -254,7 +259,7 @@ module ActsAsTaggableOn::Taggable
254
259
  end
255
260
 
256
261
  def custom_contexts
257
- @custom_contexts ||= []
262
+ @custom_contexts ||= taggings.map(&:context).uniq
258
263
  end
259
264
 
260
265
  def is_taggable?
@@ -333,7 +338,7 @@ module ActsAsTaggableOn::Taggable
333
338
  end
334
339
 
335
340
  def tagging_contexts
336
- custom_contexts + self.class.tag_types.map(&:to_s)
341
+ self.class.tag_types.map(&:to_s) + custom_contexts
337
342
  end
338
343
 
339
344
  def process_dirty_object(context, new_list)
@@ -407,7 +412,7 @@ module ActsAsTaggableOn::Taggable
407
412
 
408
413
  # Destroy old taggings:
409
414
  if old_tags.present?
410
- taggings.not_owned.by_context(context).destroy_all(tag_id: old_tags)
415
+ taggings.not_owned.by_context(context).where(tag_id: old_tags).destroy_all
411
416
  end
412
417
 
413
418
  # Create new taggings:
@@ -432,7 +437,7 @@ module ActsAsTaggableOn::Taggable
432
437
  tag_lists = tag_types.map {|tags_type| "#{tags_type.to_s.singularize}_list"}
433
438
  super.delete_if {|attr| tag_lists.include? attr }
434
439
  end
435
-
440
+
436
441
  ##
437
442
  # Override this hook if you wish to subclass {ActsAsTaggableOn::Tag} --
438
443
  # context is provided so that you may conditionally use a Tag subclass
@@ -108,9 +108,9 @@ module ActsAsTaggableOn::Taggable
108
108
 
109
109
  # Find all taggings that belong to the taggable (self), are owned by the owner,
110
110
  # have the correct context, and are removed from the list.
111
- ActsAsTaggableOn::Tagging.destroy_all(taggable_id: id, taggable_type: self.class.base_class.to_s,
112
- tagger_type: owner.class.base_class.to_s, tagger_id: owner.id,
113
- tag_id: old_tags, context: context) if old_tags.present?
111
+ ActsAsTaggableOn::Tagging.where(taggable_id: id, taggable_type: self.class.base_class.to_s,
112
+ tagger_type: owner.class.base_class.to_s, tagger_id: owner.id,
113
+ tag_id: old_tags, context: context).destroy_all if old_tags.present?
114
114
 
115
115
  # Create new taggings:
116
116
  new_tags.each do |tag|
@@ -15,18 +15,19 @@ module ActsAsTaggableOn
15
15
  # end
16
16
  def acts_as_tagger(opts={})
17
17
  class_eval do
18
- has_many_with_taggable_compatibility :owned_taggings,
19
- opts.merge(
20
- as: :tagger,
21
- dependent: :destroy,
22
- class_name: '::ActsAsTaggableOn::Tagging'
23
- )
18
+ owned_taggings_scope = opts.delete(:scope)
24
19
 
25
- has_many_with_taggable_compatibility :owned_tags,
26
- through: :owned_taggings,
27
- source: :tag,
28
- class_name: '::ActsAsTaggableOn::Tag',
29
- uniq: true
20
+ has_many :owned_taggings, owned_taggings_scope,
21
+ opts.merge(
22
+ as: :tagger,
23
+ class_name: ::ActsAsTaggableOn::Tagging,
24
+ dependent: :destroy
25
+ )
26
+
27
+ has_many :owned_tags, -> { distinct },
28
+ class_name: ::ActsAsTaggableOn::Tag,
29
+ source: :tag,
30
+ through: :owned_taggings
30
31
  end
31
32
 
32
33
  include ActsAsTaggableOn::Tagger::InstanceMethods
@@ -1,25 +1,15 @@
1
1
  module ActsAsTaggableOn
2
2
  class Tagging < ::ActiveRecord::Base #:nodoc:
3
- #TODO, remove from 4.0.0
4
- attr_accessible :tag,
5
- :tag_id,
6
- :context,
7
- :taggable,
8
- :taggable_type,
9
- :taggable_id,
10
- :tagger,
11
- :tagger_type,
12
- :tagger_id if defined?(ActiveModel::MassAssignmentSecurity)
13
-
14
3
  belongs_to :tag, class_name: '::ActsAsTaggableOn::Tag', counter_cache: ActsAsTaggableOn.tags_counter
15
4
  belongs_to :taggable, polymorphic: true
16
- belongs_to :tagger, polymorphic: true
5
+
6
+ belongs_to :tagger, {polymorphic: true}.tap {|o| o.merge!(optional: true) if ActsAsTaggableOn::Utils.active_record5? }
17
7
 
18
8
  scope :owned_by, ->(owner) { where(tagger: owner) }
19
9
  scope :not_owned, -> { where(tagger_id: nil, tagger_type: nil) }
20
10
 
21
- scope :by_contexts, ->(contexts = ['tags']) { where(context: contexts) }
22
- scope :by_context, ->(context= 'tags') { by_contexts(context.to_s) }
11
+ scope :by_contexts, ->(contexts) { where(context: (contexts || 'tags')) }
12
+ scope :by_context, ->(context = 'tags') { by_contexts(context.to_s) }
23
13
 
24
14
  validates_presence_of :context
25
15
  validates_presence_of :tag_id
@@ -13,7 +13,6 @@ module ActsAsTaggableOn
13
13
  end
14
14
 
15
15
  def using_mysql?
16
- #We should probably use regex for mysql to support prehistoric adapters
17
16
  connection && connection.adapter_name == 'Mysql2'
18
17
  end
19
18
 
@@ -21,8 +20,8 @@ module ActsAsTaggableOn
21
20
  Digest::SHA1.hexdigest(string)[0..6]
22
21
  end
23
22
 
24
- def active_record4?
25
- ::ActiveRecord::VERSION::MAJOR == 4
23
+ def active_record5?
24
+ ::ActiveRecord::VERSION::MAJOR == 5
26
25
  end
27
26
 
28
27
  def like_operator
@@ -1,4 +1,4 @@
1
1
  module ActsAsTaggableOn
2
- VERSION = '3.5.0'
2
+ VERSION = '4.0.0.pre'
3
3
  end
4
4
 
@@ -154,7 +154,7 @@ describe 'Acts As Taggable On' do
154
154
  describe 'Tagging Contexts' do
155
155
  it 'should eliminate duplicate tagging contexts ' do
156
156
  TaggableModel.acts_as_taggable_on(:skills, :skills)
157
- expect(TaggableModel.tag_types.freq[:skills]).to_not eq(3)
157
+ expect(TaggableModel.tag_types.freq[:skills]).to eq(1)
158
158
  end
159
159
 
160
160
  it 'should not contain embedded/nested arrays' do
@@ -178,6 +178,15 @@ describe 'Acts As Taggable On' do
178
178
  TaggableModel.acts_as_taggable_on([nil])
179
179
  }).to_not raise_error
180
180
  end
181
+
182
+ it 'should include dynamic contexts in tagging_contexts' do
183
+ taggable = TaggableModel.create!(name: 'Dynamic Taggable')
184
+ taggable.set_tag_list_on :colors, 'tag1, tag2, tag3'
185
+ expect(taggable.tagging_contexts).to eq(%w(tags languages skills needs offerings array colors))
186
+ taggable.save
187
+ taggable = TaggableModel.where(name: 'Dynamic Taggable').first
188
+ expect(taggable.tagging_contexts).to eq(%w(tags languages skills needs offerings array colors))
189
+ end
181
190
  end
182
191
 
183
192
  context 'when tagging context ends in an "s" when singular (ex. "status", "glass", etc.)' do
@@ -72,7 +72,7 @@ describe 'acts_as_tagger' do
72
72
  expect(@taggable.tag_list_on(:foo_boo)).to be_empty
73
73
  expect(-> {
74
74
  @tagger.tag(@taggable, with: 'this, and, that', on: :foo_boo, force: false)
75
- }).to raise_error
75
+ }).to raise_error(RuntimeError)
76
76
  end
77
77
 
78
78
  it 'should not create the tag context on-the-fly when the default is over-ridden' do
@@ -77,6 +77,28 @@ describe 'Acts As Taggable On' do
77
77
  end
78
78
  end
79
79
 
80
+ describe 'with a custom delimiter' do
81
+ before(:each) do
82
+ @taggable = CachedModel.new(name: 'Bob Jones')
83
+ @another_taggable = OtherCachedModel.new(name: 'John Smith')
84
+ ActsAsTaggableOn.delimiter = ';'
85
+ end
86
+
87
+ after(:all) do
88
+ ActsAsTaggableOn.delimiter = ','
89
+ end
90
+
91
+ it 'should cache tags with custom delimiter' do
92
+ @taggable.update_attributes(tag_list: 'awesome; epic')
93
+ expect(@taggable.tag_list).to eq(['awesome', 'epic'])
94
+ expect(@taggable.cached_tag_list).to eq('awesome; epic')
95
+
96
+ @taggable = CachedModel.find_by_name('Bob Jones')
97
+ expect(@taggable.tag_list).to eq(['awesome', 'epic'])
98
+ expect(@taggable.cached_tag_list).to eq('awesome; epic')
99
+ end
100
+ end
101
+
80
102
  describe 'CachingWithArray' do
81
103
  pending '#TODO'
82
104
  end
@@ -83,6 +83,18 @@ describe ActsAsTaggableOn::TagList do
83
83
  new_tag_list = tag_list.concat(another_tag_list)
84
84
  expect(new_tag_list.class).to eq(ActsAsTaggableOn::TagList)
85
85
  end
86
+
87
+ context 'without duplicates' do
88
+ let(:arr) { ['crazy', 'alien'] }
89
+ let(:another_tag_list) { ActsAsTaggableOn::TagList.new(*arr) }
90
+ it 'adds other list' do
91
+ expect(tag_list.concat(another_tag_list)).to eq(%w[awesome radical crazy alien])
92
+ end
93
+
94
+ it 'adds other array' do
95
+ expect(tag_list.concat(arr)).to eq(%w[awesome radical crazy alien])
96
+ end
97
+ end
86
98
  end
87
99
 
88
100
  describe '#to_s' do
@@ -92,7 +104,7 @@ describe ActsAsTaggableOn::TagList do
92
104
 
93
105
  it 'should be able to call to_s on a frozen tag list' do
94
106
  tag_list.freeze
95
- expect(-> { tag_list.add('cool', 'rad,bodacious') }).to raise_error
107
+ expect(-> { tag_list.add('cool', 'rad,bodacious') }).to raise_error(RuntimeError)
96
108
  expect(-> { tag_list.to_s }).to_not raise_error
97
109
  end
98
110
  end
@@ -114,6 +126,20 @@ describe ActsAsTaggableOn::TagList do
114
126
 
115
127
  ActsAsTaggableOn.force_lowercase = false
116
128
  end
129
+
130
+ it 'should ignore case when removing duplicates if strict_case_match is false' do
131
+ tag_list = ActsAsTaggableOn::TagList.new('Junglist', 'JUNGLIST', 'Junglist', 'Massive', 'MASSIVE', 'MASSIVE')
132
+
133
+ expect(tag_list.to_s).to eq('Junglist, Massive')
134
+ end
135
+
136
+ it 'should not ignore case when removing duplicates if strict_case_match is true' do
137
+ ActsAsTaggableOn.strict_case_match = true
138
+ tag_list = ActsAsTaggableOn::TagList.new('Junglist', 'JUNGLIST', 'Junglist', 'Massive', 'MASSIVE', 'MASSIVE')
139
+
140
+ expect(tag_list.to_s).to eq('Junglist, JUNGLIST, Massive, MASSIVE')
141
+ ActsAsTaggableOn.strict_case_match = false
142
+ end
117
143
  end
118
144
 
119
145
  describe 'custom parser' do
@@ -55,6 +55,21 @@ describe ActsAsTaggableOn::Tag do
55
55
  end
56
56
  end
57
57
 
58
+ describe 'for context' do
59
+ before(:each) do
60
+ @user.skill_list.add('ruby')
61
+ @user.save
62
+ end
63
+
64
+ it 'should return tags that have been used in the given context' do
65
+ expect(ActsAsTaggableOn::Tag.for_context('skills').pluck(:name)).to include('ruby')
66
+ end
67
+
68
+ it 'should not return tags that have been used in other contexts' do
69
+ expect(ActsAsTaggableOn::Tag.for_context('needs').pluck(:name)).to_not include('ruby')
70
+ end
71
+ end
72
+
58
73
  describe 'find or create by name' do
59
74
  before(:each) do
60
75
  @tag.name = 'awesome'
@@ -119,6 +119,21 @@ describe 'Taggable' do
119
119
  expect(@taggable.tag_counts_on(:tags).length).to eq(2)
120
120
  end
121
121
 
122
+ context 'tag_counts on a collection' do
123
+ context 'a select clause is specified on the collection' do
124
+ it 'should return tag counts without raising an error' do
125
+ expect(TaggableModel.tag_counts_on(:tags)).to be_empty
126
+
127
+ @taggable.tag_list = %w(awesome epic)
128
+ @taggable.save
129
+
130
+ expect {
131
+ expect(TaggableModel.select(:name).tag_counts_on(:tags).length).to eq(2)
132
+ }.not_to raise_error
133
+ end
134
+ end
135
+ end
136
+
122
137
  it 'should have tags_on' do
123
138
  expect(TaggableModel.tags_on(:tags)).to be_empty
124
139
 
@@ -226,8 +241,10 @@ describe 'Taggable' do
226
241
  it "should be able to find a tag using dates" do
227
242
  @taggable.skill_list = "ruby"
228
243
  @taggable.save
244
+ today = Date.today.to_time.utc
245
+ tomorrow = Date.tomorrow.to_time.utc
229
246
 
230
- expect(TaggableModel.tagged_with("ruby", :start_at => Date.today, :end_at => Date.tomorrow).count).to eq(1)
247
+ expect(TaggableModel.tagged_with("ruby", :start_at => today, :end_at => tomorrow).count).to eq(1)
231
248
  end
232
249
 
233
250
  it "shouldn't be able to find a tag outside date range" do
@@ -380,7 +397,6 @@ describe 'Taggable' do
380
397
  # Test specific join syntaxes:
381
398
  frank.untaggable_models.create!
382
399
  expect(TaggableModel.tagged_with('rails').joins(:untaggable_models).all_tag_counts.size).to eq(2)
383
- expect(TaggableModel.tagged_with('rails').joins(untaggable_models: :taggable_model).all_tag_counts.size).to eq(2)
384
400
  expect(TaggableModel.tagged_with('rails').joins([:untaggable_models]).all_tag_counts.size).to eq(2)
385
401
  end
386
402
 
@@ -395,7 +411,6 @@ describe 'Taggable' do
395
411
  # Test specific join syntaxes:
396
412
  frank.untaggable_models.create!
397
413
  expect(TaggableModel.tagged_with('rails').joins(:untaggable_models).all_tags.size).to eq(2)
398
- expect(TaggableModel.tagged_with('rails').joins(untaggable_models: :taggable_model).all_tags.size).to eq(2)
399
414
  expect(TaggableModel.tagged_with('rails').joins([:untaggable_models]).all_tags.size).to eq(2)
400
415
  end
401
416
 
@@ -459,7 +474,7 @@ describe 'Taggable' do
459
474
 
460
475
  expect(TaggableModel.tagged_with(%w(bob tricia), wild: true, any: true).to_a.sort_by { |o| o.id }).to eq([bob, frank, steve])
461
476
  expect(TaggableModel.tagged_with(%w(bob tricia), wild: true, exclude: true).to_a).to eq([jim])
462
- expect(TaggableModel.tagged_with('ji', wild: true, any: true).to_a).to eq([frank, jim])
477
+ expect(TaggableModel.tagged_with('ji', wild: true, any: true).to_a =~ [frank, jim])
463
478
  end
464
479
  end
465
480
 
@@ -743,7 +758,6 @@ describe 'Taggable' do
743
758
 
744
759
  context 'Model.limit(x).tag_counts.sum(:tags_count)' do
745
760
  it 'should not break on Mysql' do
746
- # Activerecord 3.2 return a string
747
761
  expect(TaggableModel.limit(2).tag_counts.sum('tags_count').to_i).to eq(5)
748
762
  end
749
763
  end
@@ -49,15 +49,69 @@ describe ActsAsTaggableOn::Tagging do
49
49
  ActsAsTaggableOn.remove_unused_tags = previous_setting
50
50
  end
51
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
-
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
61
116
  end
62
-
63
117
  end
@@ -7,12 +7,15 @@ ActiveRecord::Schema.define version: 0 do
7
7
  add_index 'tags', ['name'], name: 'index_tags_on_name', unique: true
8
8
 
9
9
  create_table :taggings, force: true do |t|
10
- t.references :tag
10
+ t.integer :tag_id
11
11
 
12
12
  # You should make sure that the column created is
13
13
  # long enough to store the required class names.
14
- t.references :taggable, polymorphic: true
15
- t.references :tagger, polymorphic: true
14
+ t.string :taggable_type
15
+ t.integer :taggable_id
16
+
17
+ t.string :tagger_type
18
+ t.integer :tagger_id
16
19
 
17
20
  # Limit is created to prevent MySQL error on index
18
21
  # length for MyISAM table type: http://bit.ly/vgW2Ql
@@ -23,6 +26,7 @@ ActiveRecord::Schema.define version: 0 do
23
26
  add_index 'taggings',
24
27
  ['tag_id', 'taggable_id', 'taggable_type', 'context', 'tagger_id', 'tagger_type'],
25
28
  unique: true, name: 'taggings_idx'
29
+ add_index 'taggings', :tag_id , name: 'index_taggings_on_tag_id'
26
30
 
27
31
  # above copied from
28
32
  # generators/acts_as_taggable_on/migration/migration_generator
@@ -13,13 +13,7 @@ if File.exist?(database_yml)
13
13
  config = ActiveRecord::Base.configurations[db_name]
14
14
 
15
15
  begin
16
- #activerecord 4 uses symbol
17
- #TODO, remove when activerecord 3 support is dropped
18
- if ActsAsTaggableOn::Utils.active_record4?
19
- ActiveRecord::Base.establish_connection(db_name.to_sym)
20
- else
21
- ActiveRecord::Base.establish_connection(db_name)
22
- end
16
+ ActiveRecord::Base.establish_connection(db_name.to_sym)
23
17
  ActiveRecord::Base.connection
24
18
  rescue
25
19
  case db_name
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts-as-taggable-on
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.5.0
4
+ version: 4.0.0.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Bleigh
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-03-03 00:00:00.000000000 Z
12
+ date: 2016-07-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -17,20 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - ">="
19
19
  - !ruby/object:Gem::Version
20
- version: '3.2'
21
- - - "<"
22
- - !ruby/object:Gem::Version
23
- version: '5'
20
+ version: '4.0'
24
21
  type: :runtime
25
22
  prerelease: false
26
23
  version_requirements: !ruby/object:Gem::Requirement
27
24
  requirements:
28
25
  - - ">="
29
26
  - !ruby/object:Gem::Version
30
- version: '3.2'
31
- - - "<"
32
- - !ruby/object:Gem::Version
33
- version: '5'
27
+ version: '4.0'
34
28
  - !ruby/object:Gem::Dependency
35
29
  name: sqlite3
36
30
  requirement: !ruby/object:Gem::Requirement
@@ -51,14 +45,14 @@ dependencies:
51
45
  requirements:
52
46
  - - "~>"
53
47
  - !ruby/object:Gem::Version
54
- version: 0.3.7
48
+ version: '0.3'
55
49
  type: :development
56
50
  prerelease: false
57
51
  version_requirements: !ruby/object:Gem::Requirement
58
52
  requirements:
59
53
  - - "~>"
60
54
  - !ruby/object:Gem::Version
61
- version: 0.3.7
55
+ version: '0.3'
62
56
  - !ruby/object:Gem::Dependency
63
57
  name: pg
64
58
  requirement: !ruby/object:Gem::Requirement
@@ -170,19 +164,18 @@ files:
170
164
  - db/migrate/3_add_taggings_counter_cache_to_tags.rb
171
165
  - db/migrate/4_add_missing_taggable_index.rb
172
166
  - db/migrate/5_change_collation_for_tag_names.rb
173
- - gemfiles/activerecord_3.2.gemfile
167
+ - db/migrate/6_add_missing_indexes.rb
174
168
  - gemfiles/activerecord_4.0.gemfile
175
169
  - gemfiles/activerecord_4.1.gemfile
176
170
  - gemfiles/activerecord_4.2.gemfile
171
+ - gemfiles/activerecord_5.0.gemfile
177
172
  - lib/acts-as-taggable-on.rb
178
173
  - lib/acts_as_taggable_on.rb
179
- - lib/acts_as_taggable_on/compatibility.rb
180
174
  - lib/acts_as_taggable_on/default_parser.rb
181
175
  - lib/acts_as_taggable_on/engine.rb
182
176
  - lib/acts_as_taggable_on/generic_parser.rb
183
177
  - lib/acts_as_taggable_on/tag.rb
184
178
  - lib/acts_as_taggable_on/tag_list.rb
185
- - lib/acts_as_taggable_on/tag_list_parser.rb
186
179
  - lib/acts_as_taggable_on/taggable.rb
187
180
  - lib/acts_as_taggable_on/taggable/cache.rb
188
181
  - lib/acts_as_taggable_on/taggable/collection.rb
@@ -203,7 +196,6 @@ files:
203
196
  - spec/acts_as_taggable_on/generic_parser_spec.rb
204
197
  - spec/acts_as_taggable_on/related_spec.rb
205
198
  - spec/acts_as_taggable_on/single_table_inheritance_spec.rb
206
- - spec/acts_as_taggable_on/tag_list_parser_spec.rb
207
199
  - spec/acts_as_taggable_on/tag_list_spec.rb
208
200
  - spec/acts_as_taggable_on/tag_spec.rb
209
201
  - spec/acts_as_taggable_on/taggable/dirty_spec.rb
@@ -254,15 +246,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
254
246
  requirements:
255
247
  - - ">="
256
248
  - !ruby/object:Gem::Version
257
- version: 1.9.3
249
+ version: 2.0.0
258
250
  required_rubygems_version: !ruby/object:Gem::Requirement
259
251
  requirements:
260
- - - ">="
252
+ - - ">"
261
253
  - !ruby/object:Gem::Version
262
- version: '0'
254
+ version: 1.3.1
263
255
  requirements: []
264
256
  rubyforge_project:
265
- rubygems_version: 2.4.5
257
+ rubygems_version: 2.4.5.1
266
258
  signing_key:
267
259
  specification_version: 4
268
260
  summary: Advanced tagging for Rails.
@@ -274,7 +266,6 @@ test_files:
274
266
  - spec/acts_as_taggable_on/generic_parser_spec.rb
275
267
  - spec/acts_as_taggable_on/related_spec.rb
276
268
  - spec/acts_as_taggable_on/single_table_inheritance_spec.rb
277
- - spec/acts_as_taggable_on/tag_list_parser_spec.rb
278
269
  - spec/acts_as_taggable_on/tag_list_spec.rb
279
270
  - spec/acts_as_taggable_on/tag_spec.rb
280
271
  - spec/acts_as_taggable_on/taggable/dirty_spec.rb
@@ -1,35 +0,0 @@
1
- module ActsAsTaggableOn::Compatibility
2
- def has_many_with_taggable_compatibility(name, options = {}, &extention)
3
- if ActsAsTaggableOn::Utils.active_record4?
4
- scope, opts = build_taggable_scope_and_options(options)
5
- has_many(name, scope, opts, &extention)
6
- else
7
- has_many(name, options, &extention)
8
- end
9
- end
10
-
11
- def build_taggable_scope_and_options(opts)
12
- scope_opts, opts = parse_taggable_options(opts)
13
-
14
- unless scope_opts.empty?
15
- scope = -> {
16
- scope_opts.inject(self) { |result, hash| result.send(*hash) }
17
- }
18
- return [scope, opts]
19
- end
20
-
21
- [nil, opts]
22
- end
23
-
24
- def parse_taggable_options(opts)
25
- scope_opts = {}
26
- [:order, :having, :select, :group, :limit, :offset, :readonly].each do |o|
27
- scope_opts[o] = opts.delete o if opts[o]
28
- end
29
- scope_opts[:where] = opts.delete :conditions if opts[:conditions]
30
- scope_opts[:joins] = opts.delete :include if opts [:include]
31
- scope_opts[:distinct] = opts.delete :uniq if opts[:uniq]
32
-
33
- [scope_opts, opts]
34
- end
35
- end
@@ -1,21 +0,0 @@
1
- module ActsAsTaggableOn
2
- ##
3
- # Returns a new TagList using the given tag string.
4
- #
5
- # Example:
6
- # tag_list = ActsAsTaggableOn::TagListParser.parse("One , Two, Three")
7
- # tag_list # ["One", "Two", "Three"]
8
- module TagListParser
9
- class << self
10
- ## DEPRECATED
11
- def parse(string)
12
- ActiveRecord::Base.logger.warn <<WARNING
13
- ActsAsTaggableOn::TagListParser.parse is deprecated \
14
- and will be removed from v4.0+, use \
15
- ActsAsTaggableOn::TagListParser.new instead
16
- WARNING
17
- DefaultParser.new(string).parse
18
- end
19
- end
20
- end
21
- end
@@ -1,46 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- require 'spec_helper'
3
-
4
- describe ActsAsTaggableOn::TagListParser do
5
- it '#parse should return empty array if empty array is passed' do
6
- expect(ActsAsTaggableOn::TagListParser.parse([])).to be_empty
7
- end
8
-
9
- describe 'Multiple Delimiter' do
10
- before do
11
- @old_delimiter = ActsAsTaggableOn.delimiter
12
- end
13
-
14
- after do
15
- ActsAsTaggableOn.delimiter = @old_delimiter
16
- end
17
-
18
- it 'should separate tags by delimiters' do
19
- ActsAsTaggableOn.delimiter = [',', ' ', '\|']
20
- tag_list = ActsAsTaggableOn::TagListParser.parse('cool, data|I have')
21
- expect(tag_list.to_s).to eq('cool, data, I, have')
22
- end
23
-
24
- it 'should escape quote' do
25
- ActsAsTaggableOn.delimiter = [',', ' ', '\|']
26
- tag_list = ActsAsTaggableOn::TagListParser.parse "'I have'|cool, data"
27
- expect(tag_list.to_s).to eq('"I have", cool, data')
28
-
29
- tag_list = ActsAsTaggableOn::TagListParser.parse '"I, have"|cool, data'
30
- expect(tag_list.to_s).to eq('"I, have", cool, data')
31
- end
32
-
33
- it 'should work for utf8 delimiter and long delimiter' do
34
- ActsAsTaggableOn.delimiter = [',', '的', '可能是']
35
- tag_list = ActsAsTaggableOn::TagListParser.parse('我的东西可能是不见了,还好有备份')
36
- expect(tag_list.to_s).to eq('我, 东西, 不见了, 还好有备份')
37
- end
38
-
39
- it 'should work for multiple quoted tags' do
40
- ActsAsTaggableOn.delimiter = [',']
41
- tag_list = ActsAsTaggableOn::TagListParser.parse('"Ruby Monsters","eat Katzenzungen"')
42
- expect(tag_list.to_s).to eq('Ruby Monsters, eat Katzenzungen')
43
- end
44
- end
45
-
46
- end