acts-as-taggable-on 3.2.3 → 3.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +8 -7
  3. data/Gemfile +0 -1
  4. data/acts-as-taggable-on.gemspec +6 -7
  5. data/gemfiles/activerecord_3.2.gemfile +0 -1
  6. data/gemfiles/activerecord_4.0.gemfile +0 -1
  7. data/gemfiles/activerecord_4.1.gemfile +0 -1
  8. data/gemfiles/activerecord_edge.gemfile +0 -1
  9. data/lib/acts-as-taggable-on.rb +28 -20
  10. data/lib/acts_as_taggable_on/tag_list.rb +13 -77
  11. data/lib/acts_as_taggable_on/tag_list_parser.rb +78 -0
  12. data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/core.rb +14 -10
  13. data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/ownership.rb +1 -1
  14. data/lib/acts_as_taggable_on/taggable.rb +7 -6
  15. data/lib/acts_as_taggable_on/utils.rb +2 -26
  16. data/lib/acts_as_taggable_on/version.rb +1 -1
  17. data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +1 -1
  18. data/spec/acts_as_taggable_on/acts_as_tagger_spec.rb +1 -0
  19. data/spec/acts_as_taggable_on/caching_spec.rb +1 -0
  20. data/spec/acts_as_taggable_on/related_spec.rb +1 -0
  21. data/spec/acts_as_taggable_on/single_table_inheritance_spec.rb +1 -0
  22. data/spec/acts_as_taggable_on/tag_list_parser_spec.rb +46 -0
  23. data/spec/acts_as_taggable_on/tag_list_spec.rb +3 -40
  24. data/spec/acts_as_taggable_on/tag_spec.rb +29 -35
  25. data/spec/acts_as_taggable_on/taggable_spec.rb +55 -55
  26. data/spec/acts_as_taggable_on/tagger_spec.rb +1 -0
  27. data/spec/acts_as_taggable_on/tagging_spec.rb +2 -1
  28. data/spec/acts_as_taggable_on/tags_helper_spec.rb +1 -0
  29. data/spec/acts_as_taggable_on/utils_spec.rb +1 -0
  30. data/spec/internal/app/models/cached_model_with_array.rb +1 -1
  31. data/spec/internal/app/models/models.rb +2 -2
  32. data/spec/internal/db/schema.rb +2 -2
  33. data/spec/spec_helper.rb +0 -1
  34. data/spec/support/0-helpers.rb +32 -0
  35. metadata +36 -47
  36. data/spec/schema.rb +0 -82
  37. /data/lib/acts_as_taggable_on/{acts_as_taggable_on/compatibility.rb → compatibility.rb} +0 -0
  38. /data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/cache.rb +0 -0
  39. /data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/collection.rb +0 -0
  40. /data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/dirty.rb +0 -0
  41. /data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/related.rb +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 755e4d829ddc31ccd6ffb8385594ed8c5c64971f
4
- data.tar.gz: 1ce12972b7d9d436484d619843a7bdf316a5c3b7
3
+ metadata.gz: a20675bbbf6a845a9af63de544fd91aa3d0456c4
4
+ data.tar.gz: 525532eb66d8245b5d5e5f5e0b0bcafbd71f0165
5
5
  SHA512:
6
- metadata.gz: c8f129a07903598bcb765b260bd14db168b4a6fbf6989cef816157ae6350cadd733f75ca6cc0169e00fa8c19b59710198b868f52044f07efca451c44aa9a046c
7
- data.tar.gz: 578b3d36b654b9343a36df3a7086b40b3ef32f6b43973d92c0f31251ea095405b692d2ef131ba74086366d117eef0fcd2334b51ce8f7ce3c0266481819a0a2a1
6
+ metadata.gz: da3437561dbcb861750489d2abcff557bd2aa488a483ea73d242a51d08fa6df6be4b8a64b1f7fbbed9e3dd44ea63e9b7b6101bd4d52d5a0ee05658272d16e5d8
7
+ data.tar.gz: 4f34e61243d64b0f77c842dc929c3dc6e1039b65a388d0da2e0b31484b7c63637acc76764dc18c5fde11198199dcf5756460b322e38abd5cbb9a65ed1a510c1d
data/.travis.yml CHANGED
@@ -25,18 +25,19 @@ matrix:
25
25
  allow_failures:
26
26
  - gemfile: gemfiles/activerecord_edge.gemfile
27
27
  - rvm: rbx-2
28
+ - rvm: ruby-head
28
29
  exclude:
29
30
  - rvm: 1.9.3
30
- gemfile: ci/Gemfile.activerecord-4.0.x
31
+ gemfile: gemfiles/activerecord_4.0.gemfile
31
32
  - rvm: 1.9.3
32
- gemfile: ci/Gemfile.activerecord-4.1.x
33
+ gemfile: gemfiles/activerecord_4.1.gemfile
33
34
  - rvm: 1.9.3
34
- gemfile: ci/Gemfile.activerecord-edge
35
+ gemfile: gemfiles/activerecord_edge.gemfile
35
36
  - rvm: rbx-2
36
- gemfile: ci/Gemfile.activerecord-3.2.x
37
+ gemfile: gemfiles/activerecord_3.2.gemfile
37
38
  - rvm: ruby-head
38
- gemfile: ci/Gemfile.activerecord-3.2.x
39
+ gemfile: gemfiles/activerecord_3.2.gemfile
39
40
  - rvm: ruby-head
40
- gemfile: ci/Gemfile.activerecord-4.0.x
41
+ gemfile: gemfiles/activerecord_4.0.gemfile
41
42
  - rvm: ruby-head
42
- gemfile: ci/Gemfile.activerecord-4.1.x
43
+ gemfile: gemfiles/activerecord_4.1.gemfile
data/Gemfile CHANGED
@@ -7,5 +7,4 @@ group :local_development do
7
7
  gem 'guard-rspec'
8
8
  gem 'appraisal'
9
9
  gem 'rake'
10
- gem 'byebug'
11
10
  end
@@ -26,13 +26,12 @@ Gem::Specification.new do |gem|
26
26
  gem.add_runtime_dependency 'actionpack', ['>= 3', '< 5']
27
27
 
28
28
  gem.add_development_dependency 'sqlite3'
29
- gem.add_development_dependency 'mysql2'
29
+ gem.add_development_dependency 'mysql2', '~> 0.3.7'
30
30
  gem.add_development_dependency 'pg'
31
31
 
32
- gem.add_development_dependency 'rspec-rails' , '~> 3.0.0.beta1'
33
- gem.add_development_dependency 'rspec-its', '~> 1.0'
34
- gem.add_development_dependency 'rspec', '3.0.0.beta2'
35
- gem.add_development_dependency 'ammeter', '~> 1.0'
36
- gem.add_development_dependency 'barrier', '~> 1.0'
37
- gem.add_development_dependency 'database_cleaner', '~> 1.2'
32
+ gem.add_development_dependency 'rspec-rails' , '~> 3.0.0.beta'
33
+ gem.add_development_dependency 'rspec-its'
34
+ gem.add_development_dependency 'rspec'
35
+ gem.add_development_dependency 'barrier'
36
+ gem.add_development_dependency 'database_cleaner'
38
37
  end
@@ -10,7 +10,6 @@ group :local_development do
10
10
  gem "guard-rspec"
11
11
  gem "appraisal"
12
12
  gem "rake"
13
- gem "byebug"
14
13
  end
15
14
 
16
15
  gemspec :path => "../"
@@ -10,7 +10,6 @@ group :local_development do
10
10
  gem "guard-rspec"
11
11
  gem "appraisal"
12
12
  gem "rake"
13
- gem "byebug"
14
13
  end
15
14
 
16
15
  gemspec :path => "../"
@@ -10,7 +10,6 @@ group :local_development do
10
10
  gem "guard-rspec"
11
11
  gem "appraisal"
12
12
  gem "rake"
13
- gem "byebug"
14
13
  end
15
14
 
16
15
  gemspec :path => "../"
@@ -11,7 +11,6 @@ group :local_development do
11
11
  gem "guard-rspec"
12
12
  gem "appraisal"
13
13
  gem "rake"
14
- gem "byebug"
15
14
  end
16
15
 
17
16
  gemspec :path => "../"
@@ -3,9 +3,35 @@ require 'active_record/version'
3
3
  require 'active_support/core_ext/module'
4
4
  require 'action_view'
5
5
 
6
+ require_relative 'acts_as_taggable_on/engine'
7
+
6
8
  require 'digest/sha1'
7
9
 
8
10
  module ActsAsTaggableOn
11
+ extend ActiveSupport::Autoload
12
+
13
+ autoload :Tag
14
+ autoload :TagList
15
+ autoload :TagListParser
16
+ autoload :Taggable
17
+ autoload :Tagger
18
+ autoload :Tagging
19
+ autoload :TagsHelper
20
+ autoload :VERSION
21
+
22
+ autoload_under 'taggable' do
23
+ autoload :Cache
24
+ autoload :Collection
25
+ autoload :Core
26
+ autoload :Dirty
27
+ autoload :Ownership
28
+ autoload :Related
29
+ end
30
+
31
+ autoload :Utils
32
+ autoload :Compatibility
33
+
34
+
9
35
  class DuplicateTagError < StandardError
10
36
  end
11
37
 
@@ -16,7 +42,7 @@ module ActsAsTaggableOn
16
42
 
17
43
  def self.method_missing(method_name, *args, &block)
18
44
  @configuration.respond_to?(method_name) ?
19
- @configuration.send(method_name, *args, &block) : super
45
+ @configuration.send(method_name, *args, &block) : super
20
46
  end
21
47
 
22
48
  def self.respond_to?(method_name, include_private=false)
@@ -31,7 +57,7 @@ module ActsAsTaggableOn
31
57
 
32
58
  class Configuration
33
59
  attr_accessor :delimiter, :force_lowercase, :force_parameterize,
34
- :strict_case_match, :remove_unused_tags
60
+ :strict_case_match, :remove_unused_tags
35
61
 
36
62
  def initialize
37
63
  @delimiter = ','
@@ -45,24 +71,6 @@ module ActsAsTaggableOn
45
71
  setup
46
72
  end
47
73
 
48
- require 'acts_as_taggable_on/utils'
49
-
50
- require 'acts_as_taggable_on/taggable'
51
- require 'acts_as_taggable_on/acts_as_taggable_on/compatibility'
52
- require 'acts_as_taggable_on/acts_as_taggable_on/core'
53
- require 'acts_as_taggable_on/acts_as_taggable_on/collection'
54
- require 'acts_as_taggable_on/acts_as_taggable_on/cache'
55
- require 'acts_as_taggable_on/acts_as_taggable_on/ownership'
56
- require 'acts_as_taggable_on/acts_as_taggable_on/related'
57
- require 'acts_as_taggable_on/acts_as_taggable_on/dirty'
58
-
59
- require 'acts_as_taggable_on/tagger'
60
- require 'acts_as_taggable_on/tag'
61
- require 'acts_as_taggable_on/tag_list'
62
- require 'acts_as_taggable_on/tags_helper'
63
- require 'acts_as_taggable_on/tagging'
64
- require 'acts_as_taggable_on/engine'
65
-
66
74
  ActiveSupport.on_load(:active_record) do
67
75
  extend ActsAsTaggableOn::Compatibility
68
76
  extend ActsAsTaggableOn::Taggable
@@ -1,3 +1,4 @@
1
+
1
2
  require 'active_support/core_ext/module/delegation'
2
3
 
3
4
  module ActsAsTaggableOn
@@ -8,82 +9,6 @@ module ActsAsTaggableOn
8
9
  add(*args)
9
10
  end
10
11
 
11
- class << self
12
- ##
13
- # Returns a new TagList using the given tag string.
14
- #
15
- # Example:
16
- # tag_list = ActsAsTaggableOn::TagList.from("One , Two, Three")
17
- # tag_list # ["One", "Two", "Three"]
18
- def from(string)
19
- string = string.join(ActsAsTaggableOn.glue) if string.respond_to?(:join)
20
-
21
- new.tap do |tag_list|
22
- string = string.to_s.dup
23
-
24
-
25
- string.gsub!(double_quote_pattern) {
26
- # Append the matched tag to the tag list
27
- tag_list << Regexp.last_match[2]
28
- # Return the matched delimiter ($3) to replace the matched items
29
- ''
30
- }
31
-
32
- string.gsub!(single_quote_pattern) {
33
- # Append the matched tag ($2) to the tag list
34
- tag_list << Regexp.last_match[2]
35
- # Return an empty string to replace the matched items
36
- ''
37
- }
38
-
39
- # split the string by the delimiter
40
- # and add to the tag_list
41
- tag_list.add(string.split(Regexp.new delimiter))
42
- end
43
- end
44
-
45
- def delimiter
46
- # Parse the quoted tags
47
- d = ActsAsTaggableOn.delimiter
48
- # Separate multiple delimiters by bitwise operator
49
- d = d.join('|') if d.kind_of?(Array)
50
-
51
- d
52
- end
53
-
54
- def single_quote_pattern
55
- %r{
56
- ( # Tag start delimiter ($1)
57
- \A | # Either string start or
58
- #{delimiter} # a delimiter
59
- )
60
- \s*' # quote (') optionally preceded by whitespace
61
- (.*?) # Tag ($2)
62
- '\s* # quote (') optionally followed by whitespace
63
- (?= # Tag end delimiter (not consumed; is zero-length lookahead)
64
- #{delimiter}\s* | # Either a delimiter optionally followed by whitespace or
65
- \z # string end
66
- )
67
- }x
68
- end
69
-
70
- def double_quote_pattern
71
- %r{
72
- ( # Tag start delimiter ($1)
73
- \A | # Either string start or
74
- #{delimiter} # a delimiter
75
- )
76
- \s*" # quote (") optionally preceded by whitespace
77
- (.*?) # Tag ($2)
78
- "\s* # quote (") optionally followed by whitespace
79
- (?= # Tag end delimiter (not consumed; is zero-length lookahead)
80
- #{delimiter}\s* | # Either a delimiter optionally followed by whitespace or
81
- \z # string end
82
- )
83
- }x
84
- end
85
-
86
- end
87
12
  ##
88
13
  # Add tags to the tag_list. Duplicate or blank tags will be ignored.
89
14
  # Use the <tt>:parse</tt> option to add an unparsed tag string.
@@ -165,12 +90,23 @@ module ActsAsTaggableOn
165
90
  options = args.last.is_a?(Hash) ? args.pop : {}
166
91
  options.assert_valid_keys :parse
167
92
 
168
- args.map! { |a| self.class.from(a) } if options[:parse]
93
+ args.map! { |a| TagListParser.parse(a) } if options[:parse]
169
94
 
170
95
  args.flatten!
171
96
  end
172
97
 
173
98
 
99
+ ## DEPRECATED
100
+ def self.from(string)
101
+ ActiveRecord::Base.logger.warn <<WARNING
102
+ ActsAsTaggableOn::TagList.from is deprecated \
103
+ and will be removed from v4.0+, use \
104
+ ActsAsTaggableOn::TagListParser.parse instead
105
+ WARNING
106
+ TagListParser.parse(string)
107
+ end
108
+
109
+
174
110
  end
175
111
  end
176
112
 
@@ -0,0 +1,78 @@
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
+ def parse(string)
11
+ string = string.join(ActsAsTaggableOn.glue) if string.respond_to?(:join)
12
+ TagList.new.tap do |tag_list|
13
+ string = string.to_s.dup
14
+
15
+
16
+ string.gsub!(double_quote_pattern) {
17
+ # Append the matched tag to the tag list
18
+ tag_list << Regexp.last_match[2]
19
+ # Return the matched delimiter ($3) to replace the matched items
20
+ ''
21
+ }
22
+
23
+ string.gsub!(single_quote_pattern) {
24
+ # Append the matched tag ($2) to the tag list
25
+ tag_list << Regexp.last_match[2]
26
+ # Return an empty string to replace the matched items
27
+ ''
28
+ }
29
+
30
+ # split the string by the delimiter
31
+ # and add to the tag_list
32
+ tag_list.add(string.split(Regexp.new delimiter))
33
+ end
34
+ end
35
+
36
+
37
+ # private
38
+ def delimiter
39
+ # Parse the quoted tags
40
+ d = ActsAsTaggableOn.delimiter
41
+ # Separate multiple delimiters by bitwise operator
42
+ d = d.join('|') if d.kind_of?(Array)
43
+ d
44
+ end
45
+
46
+ # ( # Tag start delimiter ($1)
47
+ # \A | # Either string start or
48
+ # #{delimiter} # a delimiter
49
+ # )
50
+ # \s*" # quote (") optionally preceded by whitespace
51
+ # (.*?) # Tag ($2)
52
+ # "\s* # quote (") optionally followed by whitespace
53
+ # (?= # Tag end delimiter (not consumed; is zero-length lookahead)
54
+ # #{delimiter}\s* | # Either a delimiter optionally followed by whitespace or
55
+ # \z # string end
56
+ # )
57
+ def double_quote_pattern
58
+ /(\A|#{delimiter})\s*"(.*?)"\s*(?=#{delimiter}\s*|\z)/
59
+ end
60
+
61
+ # ( # Tag start delimiter ($1)
62
+ # \A | # Either string start or
63
+ # #{delimiter} # a delimiter
64
+ # )
65
+ # \s*' # quote (') optionally preceded by whitespace
66
+ # (.*?) # Tag ($2)
67
+ # '\s* # quote (') optionally followed by whitespace
68
+ # (?= # Tag end delimiter (not consumed; is zero-length lookahead)
69
+ # #{delimiter}\s* | d # Either a delimiter optionally followed by whitespace or
70
+ # \z # string end
71
+ # )
72
+ def single_quote_pattern
73
+ /(\A|#{delimiter})\s*'(.*?)'\s*(?=#{delimiter}\s*|\z)/
74
+ end
75
+
76
+ end
77
+ end
78
+ end
@@ -82,7 +82,7 @@ module ActsAsTaggableOn::Taggable
82
82
  # User.tagged_with("awesome", "cool", :match_all => true) # Users that are tagged with just awesome and cool
83
83
  # User.tagged_with("awesome", "cool", :owned_by => foo ) # Users that are tagged with just awesome and cool by 'foo'
84
84
  def tagged_with(tags, options = {})
85
- tag_list = ActsAsTaggableOn::TagList.from(tags)
85
+ tag_list = ActsAsTaggableOn::TagListParser.parse(tags)
86
86
  options = options.dup
87
87
  empty_result = where('1 = 0')
88
88
 
@@ -116,7 +116,7 @@ module ActsAsTaggableOn::Taggable
116
116
  " AND #{ActsAsTaggableOn::Tagging.table_name}.tagger_type = #{quote_value(owned_by.class.base_class.to_s, nil)}"
117
117
  end
118
118
 
119
- elsif options.delete(:any)
119
+ elsif any = options.delete(:any)
120
120
  # get tags, drop out if nothing returned (we need at least one)
121
121
  tags = if options.delete(:wild)
122
122
  ActsAsTaggableOn::Tag.named_like_any(tag_list)
@@ -141,7 +141,7 @@ module ActsAsTaggableOn::Taggable
141
141
 
142
142
  # don't need to sanitize sql, map all ids and join with OR logic
143
143
  conditions << tags.map { |t| "#{taggings_alias}.tag_id = #{quote_value(t.id, nil)}" }.join(' OR ')
144
- select_clause = " #{table_name}.*" unless context and tag_types.one?
144
+ select_clause << " #{table_name}.*" unless context and tag_types.one?
145
145
 
146
146
  if owned_by
147
147
  tagging_join << ' AND ' +
@@ -153,7 +153,10 @@ module ActsAsTaggableOn::Taggable
153
153
  end
154
154
 
155
155
  joins << tagging_join
156
- group = "#{table_name}.#{primary_key}"
156
+ unless any == 'distinct' # Fix issue #544
157
+ group = "#{table_name}.#{primary_key}"
158
+ select_clause << group
159
+ end
157
160
  else
158
161
  tags = ActsAsTaggableOn::Tag.named_any(tag_list)
159
162
 
@@ -183,7 +186,7 @@ module ActsAsTaggableOn::Taggable
183
186
 
184
187
  group ||= [] # Rails interprets this as a no-op in the group() call below
185
188
  if options.delete(:order_by_matching_tag_count)
186
- select_clause = "#{table_name}.*, COUNT(#{taggings_alias}.tag_id) AS #{taggings_alias}_count"
189
+ select_clause << "#{table_name}.*, COUNT(#{taggings_alias}.tag_id) AS #{taggings_alias}_count"
187
190
  group_columns = ActsAsTaggableOn::Utils.using_postgresql? ? grouped_column_names_for(self) : "#{table_name}.#{primary_key}"
188
191
  group = group_columns
189
192
  order_by << "#{taggings_alias}_count DESC"
@@ -203,8 +206,9 @@ module ActsAsTaggableOn::Taggable
203
206
 
204
207
  order_by << options[:order] if options[:order].present?
205
208
 
206
- select(select_clause)
207
- .joins(joins.join(' '))
209
+ query = self
210
+ query = self.select(select_clause.join(',')) unless select_clause.empty?
211
+ query.joins(joins.join(' '))
208
212
  .where(conditions.join(' AND '))
209
213
  .group(group)
210
214
  .having(having)
@@ -259,7 +263,7 @@ module ActsAsTaggableOn::Taggable
259
263
  if instance_variable_get(variable_name)
260
264
  instance_variable_get(variable_name)
261
265
  elsif cached_tag_list_on(context) && self.class.caching_tag_list_on?(context)
262
- instance_variable_set(variable_name, ActsAsTaggableOn::TagList.from(cached_tag_list_on(context)))
266
+ instance_variable_set(variable_name, ActsAsTaggableOn::TagListParser.parse(cached_tag_list_on(context)))
263
267
  else
264
268
  instance_variable_set(variable_name, ActsAsTaggableOn::TagList.new(tags_on(context).map(&:name)))
265
269
  end
@@ -309,7 +313,7 @@ module ActsAsTaggableOn::Taggable
309
313
  variable_name = "@#{context.to_s.singularize}_list"
310
314
  process_dirty_object(context, new_list) unless custom_contexts.include?(context.to_s)
311
315
 
312
- instance_variable_set(variable_name, ActsAsTaggableOn::TagList.from(new_list))
316
+ instance_variable_set(variable_name, ActsAsTaggableOn::TagListParser.parse(new_list))
313
317
  end
314
318
 
315
319
  def tagging_contexts
@@ -383,7 +387,7 @@ module ActsAsTaggableOn::Taggable
383
387
 
384
388
  # Destroy old taggings:
385
389
  if old_tags.present?
386
- self.taggings.not_owned.by_context(context).destroy_all(tag_id: old_tags)
390
+ taggings.not_owned.by_context(context).destroy_all(tag_id: old_tags)
387
391
  end
388
392
 
389
393
  # Create new taggings:
@@ -63,7 +63,7 @@ module ActsAsTaggableOn::Taggable
63
63
 
64
64
  cache = cached_owned_tag_list_on(context)
65
65
 
66
- cache[owner] = ActsAsTaggableOn::TagList.from(new_list)
66
+ cache[owner] = ActsAsTaggableOn::TagListParser.parse(new_list)
67
67
  end
68
68
 
69
69
  def reload(*args)
@@ -1,5 +1,6 @@
1
1
  module ActsAsTaggableOn
2
2
  module Taggable
3
+
3
4
  def taggable?
4
5
  false
5
6
  end
@@ -90,12 +91,12 @@ module ActsAsTaggableOn
90
91
 
91
92
  # each of these add context-specific methods and must be
92
93
  # called on each call of taggable_on
93
- include ActsAsTaggableOn::Taggable::Core
94
- include ActsAsTaggableOn::Taggable::Collection
95
- include ActsAsTaggableOn::Taggable::Cache
96
- include ActsAsTaggableOn::Taggable::Ownership
97
- include ActsAsTaggableOn::Taggable::Related
98
- include ActsAsTaggableOn::Taggable::Dirty
94
+ include Core
95
+ include Collection
96
+ include Cache
97
+ include Ownership
98
+ include Related
99
+ include Dirty
99
100
  end
100
101
  end
101
102
  end
@@ -1,3 +1,5 @@
1
+ # This module is deprecated and will be removed in the incoming versions
2
+
1
3
  module ActsAsTaggableOn
2
4
  module Utils
3
5
  class << self
@@ -10,33 +12,11 @@ module ActsAsTaggableOn
10
12
  connection && connection.adapter_name == 'PostgreSQL'
11
13
  end
12
14
 
13
- def postgresql_version
14
- if using_postgresql?
15
- connection.execute('SHOW SERVER_VERSION').first['server_version'].to_f
16
- end
17
- end
18
-
19
- def postgresql_support_json?
20
- postgresql_version >= 9.2
21
- end
22
-
23
- def using_sqlite?
24
- connection && connection.adapter_name == 'SQLite'
25
- end
26
-
27
15
  def using_mysql?
28
16
  #We should probably use regex for mysql to support prehistoric adapters
29
17
  connection && connection.adapter_name == 'Mysql2'
30
18
  end
31
19
 
32
- def using_case_insensitive_collation?
33
- using_mysql? && connection.collation =~ /_ci\Z/
34
- end
35
-
36
- def supports_concurrency?
37
- !using_sqlite?
38
- end
39
-
40
20
  def sha_prefix(string)
41
21
  Digest::SHA1.hexdigest("#{string}#{rand}")[0..6]
42
22
  end
@@ -45,10 +25,6 @@ module ActsAsTaggableOn
45
25
  ::ActiveRecord::VERSION::MAJOR == 4
46
26
  end
47
27
 
48
- def active_record42?
49
- active_record4? && ::ActiveRecord::VERSION::MINOR >= 2
50
- end
51
-
52
28
  def like_operator
53
29
  using_postgresql? ? 'ILIKE' : 'LIKE'
54
30
  end
@@ -1,4 +1,4 @@
1
1
  module ActsAsTaggableOn
2
- VERSION = '3.2.3'
2
+ VERSION = '3.2.5'
3
3
  end
4
4
 
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # -*- encoding : utf-8 -*-
2
2
  require 'spec_helper'
3
3
 
4
4
  describe 'Acts As Taggable On' do
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  require 'spec_helper'
2
3
 
3
4
  describe 'acts_as_tagger' do
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  require 'spec_helper'
2
3
 
3
4
  describe 'Acts As Taggable On' do
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  require 'spec_helper'
2
3
 
3
4
  describe 'Acts As Taggable On' do
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  require 'spec_helper'
2
3
 
3
4
  describe 'Single Table Inheritance' do
@@ -0,0 +1,46 @@
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