sb-acts-as-taggable-on 6.5.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 +7 -0
- data/.gitignore +13 -0
- data/.rspec +2 -0
- data/.travis.yml +39 -0
- data/Appraisals +15 -0
- data/CHANGELOG.md +330 -0
- data/CONTRIBUTING.md +57 -0
- data/Gemfile +11 -0
- data/Guardfile +5 -0
- data/LICENSE.md +20 -0
- data/README.md +555 -0
- data/Rakefile +21 -0
- data/UPGRADING.md +8 -0
- data/acts-as-taggable-on.gemspec +32 -0
- data/db/migrate/1_acts_as_taggable_on_migration.rb +36 -0
- data/db/migrate/2_add_missing_unique_indices.rb +25 -0
- data/db/migrate/3_add_taggings_counter_cache_to_tags.rb +19 -0
- data/db/migrate/4_add_missing_taggable_index.rb +14 -0
- data/db/migrate/5_change_collation_for_tag_names.rb +14 -0
- data/db/migrate/6_add_missing_indexes_on_taggings.rb +22 -0
- data/gemfiles/activerecord_5.0.gemfile +21 -0
- 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/lib/acts-as-taggable-on.rb +133 -0
- data/lib/acts_as_taggable_on.rb +6 -0
- data/lib/acts_as_taggable_on/default_parser.rb +79 -0
- data/lib/acts_as_taggable_on/engine.rb +4 -0
- data/lib/acts_as_taggable_on/generic_parser.rb +19 -0
- data/lib/acts_as_taggable_on/tag.rb +139 -0
- data/lib/acts_as_taggable_on/tag_list.rb +106 -0
- data/lib/acts_as_taggable_on/taggable.rb +101 -0
- data/lib/acts_as_taggable_on/taggable/cache.rb +90 -0
- data/lib/acts_as_taggable_on/taggable/collection.rb +183 -0
- data/lib/acts_as_taggable_on/taggable/core.rb +322 -0
- data/lib/acts_as_taggable_on/taggable/ownership.rb +136 -0
- data/lib/acts_as_taggable_on/taggable/related.rb +71 -0
- 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 +89 -0
- data/lib/acts_as_taggable_on/tagging.rb +36 -0
- data/lib/acts_as_taggable_on/tags_helper.rb +15 -0
- data/lib/acts_as_taggable_on/utils.rb +37 -0
- data/lib/acts_as_taggable_on/version.rb +3 -0
- data/lib/tasks/tags_collate_utf8.rake +21 -0
- data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +285 -0
- data/spec/acts_as_taggable_on/acts_as_tagger_spec.rb +112 -0
- data/spec/acts_as_taggable_on/caching_spec.rb +129 -0
- data/spec/acts_as_taggable_on/default_parser_spec.rb +47 -0
- data/spec/acts_as_taggable_on/dirty_spec.rb +142 -0
- data/spec/acts_as_taggable_on/generic_parser_spec.rb +14 -0
- data/spec/acts_as_taggable_on/related_spec.rb +99 -0
- data/spec/acts_as_taggable_on/single_table_inheritance_spec.rb +231 -0
- data/spec/acts_as_taggable_on/tag_list_spec.rb +176 -0
- data/spec/acts_as_taggable_on/tag_spec.rb +340 -0
- data/spec/acts_as_taggable_on/taggable_spec.rb +817 -0
- data/spec/acts_as_taggable_on/tagger_spec.rb +153 -0
- data/spec/acts_as_taggable_on/tagging_spec.rb +117 -0
- data/spec/acts_as_taggable_on/tags_helper_spec.rb +45 -0
- data/spec/acts_as_taggable_on/utils_spec.rb +23 -0
- data/spec/internal/app/models/altered_inheriting_taggable_model.rb +5 -0
- data/spec/internal/app/models/cached_model.rb +3 -0
- data/spec/internal/app/models/cached_model_with_array.rb +11 -0
- data/spec/internal/app/models/columns_override_model.rb +5 -0
- data/spec/internal/app/models/company.rb +15 -0
- data/spec/internal/app/models/inheriting_taggable_model.rb +4 -0
- data/spec/internal/app/models/market.rb +2 -0
- data/spec/internal/app/models/non_standard_id_taggable_model.rb +8 -0
- data/spec/internal/app/models/ordered_taggable_model.rb +4 -0
- data/spec/internal/app/models/other_cached_model.rb +3 -0
- data/spec/internal/app/models/other_taggable_model.rb +4 -0
- data/spec/internal/app/models/student.rb +4 -0
- data/spec/internal/app/models/taggable_model.rb +14 -0
- data/spec/internal/app/models/untaggable_model.rb +3 -0
- data/spec/internal/app/models/user.rb +3 -0
- data/spec/internal/config/database.yml.sample +19 -0
- data/spec/internal/db/schema.rb +110 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/support/0-helpers.rb +32 -0
- data/spec/support/array.rb +9 -0
- data/spec/support/database.rb +36 -0
- data/spec/support/database_cleaner.rb +21 -0
- metadata +269 -0
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
import "./lib/tasks/tags_collate_utf8.rake"
|
5
|
+
|
6
|
+
desc 'Default: run specs'
|
7
|
+
task default: :spec
|
8
|
+
|
9
|
+
desc 'Copy sample spec database.yml over if not exists'
|
10
|
+
task :copy_db_config do
|
11
|
+
cp 'spec/internal/config/database.yml.sample', 'spec/internal/config/database.yml'
|
12
|
+
end
|
13
|
+
|
14
|
+
task spec: [:copy_db_config]
|
15
|
+
|
16
|
+
require 'rspec/core/rake_task'
|
17
|
+
RSpec::Core::RakeTask.new do |t|
|
18
|
+
t.pattern = 'spec/**/*_spec.rb'
|
19
|
+
end
|
20
|
+
|
21
|
+
Bundler::GemHelper.install_tasks
|
data/UPGRADING.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'acts_as_taggable_on/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = 'sb-acts-as-taggable-on'
|
8
|
+
gem.version = ActsAsTaggableOn::VERSION
|
9
|
+
gem.authors = ['Michael Bleigh', 'Joost Baaij', 'Hernan Velasquez']
|
10
|
+
gem.email = %w(michael@intridea.com joost@spacebabies.nl hernamvel@gmail.com)
|
11
|
+
gem.description = %q{For SB, with ActsAsTaggableOn, you can tag a single model on several contexts, such as skills, interests, and awards. It also provides other advanced functionality.}
|
12
|
+
gem.summary = 'Advanced tagging for Rails.'
|
13
|
+
gem.homepage = 'https://github.com/hernamvel/acts-as-taggable-on'
|
14
|
+
gem.license = 'MIT'
|
15
|
+
|
16
|
+
gem.files = `git ls-files`.split($/)
|
17
|
+
gem.test_files = gem.files.grep(%r{^spec/})
|
18
|
+
gem.require_paths = ['lib']
|
19
|
+
gem.required_ruby_version = '>= 2.3.7'
|
20
|
+
|
21
|
+
if File.exist?('UPGRADING.md')
|
22
|
+
gem.post_install_message = File.read('UPGRADING.md')
|
23
|
+
end
|
24
|
+
|
25
|
+
gem.add_runtime_dependency 'activerecord', '>= 5.0', '< 6.1'
|
26
|
+
|
27
|
+
gem.add_development_dependency 'rspec-rails'
|
28
|
+
gem.add_development_dependency 'rspec-its'
|
29
|
+
gem.add_development_dependency 'rspec'
|
30
|
+
gem.add_development_dependency 'barrier'
|
31
|
+
gem.add_development_dependency 'database_cleaner'
|
32
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
if ActiveRecord.gem_version >= Gem::Version.new('5.0')
|
2
|
+
class ActsAsTaggableOnMigration < ActiveRecord::Migration[4.2]; end
|
3
|
+
else
|
4
|
+
class ActsAsTaggableOnMigration < ActiveRecord::Migration; end
|
5
|
+
end
|
6
|
+
ActsAsTaggableOnMigration.class_eval do
|
7
|
+
def self.up
|
8
|
+
create_table ActsAsTaggableOn.tags_table do |t|
|
9
|
+
t.string :name
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
|
13
|
+
create_table ActsAsTaggableOn.taggings_table do |t|
|
14
|
+
t.references :tag, foreign_key: { to_table: ActsAsTaggableOn.tags_table }
|
15
|
+
|
16
|
+
# You should make sure that the column created is
|
17
|
+
# long enough to store the required class names.
|
18
|
+
t.references :taggable, polymorphic: true
|
19
|
+
t.references :tagger, polymorphic: true
|
20
|
+
|
21
|
+
# Limit is created to prevent MySQL error on index
|
22
|
+
# length for MyISAM table type: http://bit.ly/vgW2Ql
|
23
|
+
t.string :context, limit: 128
|
24
|
+
|
25
|
+
t.datetime :created_at
|
26
|
+
end
|
27
|
+
|
28
|
+
add_index ActsAsTaggableOn.taggings_table, :tag_id
|
29
|
+
add_index ActsAsTaggableOn.taggings_table, [:taggable_id, :taggable_type, :context], name: 'taggings_taggable_context_idx'
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.down
|
33
|
+
drop_table ActsAsTaggableOn.taggings_table
|
34
|
+
drop_table ActsAsTaggableOn.tags_table
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
if ActiveRecord.gem_version >= Gem::Version.new('5.0')
|
2
|
+
class AddMissingUniqueIndices < ActiveRecord::Migration[4.2]; end
|
3
|
+
else
|
4
|
+
class AddMissingUniqueIndices < ActiveRecord::Migration; end
|
5
|
+
end
|
6
|
+
AddMissingUniqueIndices.class_eval do
|
7
|
+
def self.up
|
8
|
+
add_index ActsAsTaggableOn.tags_table, :name, unique: true
|
9
|
+
|
10
|
+
remove_index ActsAsTaggableOn.taggings_table, :tag_id if index_exists?(ActsAsTaggableOn.taggings_table, :tag_id)
|
11
|
+
remove_index ActsAsTaggableOn.taggings_table, name: 'taggings_taggable_context_idx'
|
12
|
+
add_index ActsAsTaggableOn.taggings_table,
|
13
|
+
[:tag_id, :taggable_id, :taggable_type, :context, :tagger_id, :tagger_type],
|
14
|
+
unique: true, name: 'taggings_idx'
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.down
|
18
|
+
remove_index ActsAsTaggableOn.tags_table, :name
|
19
|
+
|
20
|
+
remove_index ActsAsTaggableOn.taggings_table, name: 'taggings_idx'
|
21
|
+
|
22
|
+
add_index ActsAsTaggableOn.taggings_table, :tag_id unless index_exists?(ActsAsTaggableOn.taggings_table, :tag_id)
|
23
|
+
add_index ActsAsTaggableOn.taggings_table, [:taggable_id, :taggable_type, :context], name: 'taggings_taggable_context_idx'
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
if ActiveRecord.gem_version >= Gem::Version.new('5.0')
|
2
|
+
class AddTaggingsCounterCacheToTags < ActiveRecord::Migration[4.2]; end
|
3
|
+
else
|
4
|
+
class AddTaggingsCounterCacheToTags < ActiveRecord::Migration; end
|
5
|
+
end
|
6
|
+
AddTaggingsCounterCacheToTags.class_eval do
|
7
|
+
def self.up
|
8
|
+
add_column ActsAsTaggableOn.tags_table, :taggings_count, :integer, default: 0
|
9
|
+
|
10
|
+
ActsAsTaggableOn::Tag.reset_column_information
|
11
|
+
ActsAsTaggableOn::Tag.find_each do |tag|
|
12
|
+
ActsAsTaggableOn::Tag.reset_counters(tag.id, ActsAsTaggableOn.taggings_table)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.down
|
17
|
+
remove_column ActsAsTaggableOn.tags_table, :taggings_count
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
if ActiveRecord.gem_version >= Gem::Version.new('5.0')
|
2
|
+
class AddMissingTaggableIndex < ActiveRecord::Migration[4.2]; end
|
3
|
+
else
|
4
|
+
class AddMissingTaggableIndex < ActiveRecord::Migration; end
|
5
|
+
end
|
6
|
+
AddMissingTaggableIndex.class_eval do
|
7
|
+
def self.up
|
8
|
+
add_index ActsAsTaggableOn.taggings_table, [:taggable_id, :taggable_type, :context], name: 'taggings_taggable_context_idx'
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.down
|
12
|
+
remove_index ActsAsTaggableOn.taggings_table, name: 'taggings_taggable_context_idx'
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# This migration is added to circumvent issue #623 and have special characters
|
2
|
+
# work properly
|
3
|
+
if ActiveRecord.gem_version >= Gem::Version.new('5.0')
|
4
|
+
class ChangeCollationForTagNames < ActiveRecord::Migration[4.2]; end
|
5
|
+
else
|
6
|
+
class ChangeCollationForTagNames < ActiveRecord::Migration; end
|
7
|
+
end
|
8
|
+
ChangeCollationForTagNames.class_eval do
|
9
|
+
def up
|
10
|
+
if ActsAsTaggableOn::Utils.using_mysql?
|
11
|
+
execute("ALTER TABLE #{ActsAsTaggableOn.tags_table} MODIFY name varchar(255) CHARACTER SET utf8 COLLATE utf8_bin;")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
if ActiveRecord.gem_version >= Gem::Version.new('5.0')
|
2
|
+
class AddMissingIndexesOnTaggings < ActiveRecord::Migration[4.2]; end
|
3
|
+
else
|
4
|
+
class AddMissingIndexesOnTaggings < ActiveRecord::Migration; end
|
5
|
+
end
|
6
|
+
AddMissingIndexesOnTaggings.class_eval do
|
7
|
+
def change
|
8
|
+
add_index ActsAsTaggableOn.taggings_table, :tag_id unless index_exists? ActsAsTaggableOn.taggings_table, :tag_id
|
9
|
+
add_index ActsAsTaggableOn.taggings_table, :taggable_id unless index_exists? ActsAsTaggableOn.taggings_table, :taggable_id
|
10
|
+
add_index ActsAsTaggableOn.taggings_table, :taggable_type unless index_exists? ActsAsTaggableOn.taggings_table, :taggable_type
|
11
|
+
add_index ActsAsTaggableOn.taggings_table, :tagger_id unless index_exists? ActsAsTaggableOn.taggings_table, :tagger_id
|
12
|
+
add_index ActsAsTaggableOn.taggings_table, :context unless index_exists? ActsAsTaggableOn.taggings_table, :context
|
13
|
+
|
14
|
+
unless index_exists? ActsAsTaggableOn.taggings_table, [:tagger_id, :tagger_type]
|
15
|
+
add_index ActsAsTaggableOn.taggings_table, [:tagger_id, :tagger_type]
|
16
|
+
end
|
17
|
+
|
18
|
+
unless index_exists? ActsAsTaggableOn.taggings_table, [:taggable_id, :taggable_type, :tagger_id, :context], name: 'taggings_idy'
|
19
|
+
add_index ActsAsTaggableOn.taggings_table, [:taggable_id, :taggable_type, :tagger_id, :context], name: 'taggings_idy'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
gem "activerecord", "~> 5.0.3"
|
4
|
+
case ENV["DB"]
|
5
|
+
when "postgresql"
|
6
|
+
gem 'pg'
|
7
|
+
when "mysql"
|
8
|
+
gem 'mysql2', '~> 0.3'
|
9
|
+
else
|
10
|
+
gem "sqlite3", "~> 1.3", "< 1.4"
|
11
|
+
end
|
12
|
+
|
13
|
+
group :local_development do
|
14
|
+
gem "guard"
|
15
|
+
gem "guard-rspec"
|
16
|
+
gem "appraisal"
|
17
|
+
gem "rake"
|
18
|
+
gem "byebug", platforms: [:mri]
|
19
|
+
end
|
20
|
+
|
21
|
+
gemspec path: "../"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
gem "activerecord", "~> 5.1.1"
|
4
|
+
case ENV["DB"]
|
5
|
+
when "postgresql"
|
6
|
+
gem 'pg'
|
7
|
+
when "mysql"
|
8
|
+
gem 'mysql2', '~> 0.3'
|
9
|
+
else
|
10
|
+
gem "sqlite3", "~> 1.3", "< 1.4"
|
11
|
+
end
|
12
|
+
|
13
|
+
group :local_development do
|
14
|
+
gem "guard"
|
15
|
+
gem "guard-rspec"
|
16
|
+
gem "appraisal"
|
17
|
+
gem "rake"
|
18
|
+
gem "byebug", platforms: [:mri]
|
19
|
+
end
|
20
|
+
|
21
|
+
gemspec path: "../"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
gem "activerecord", "~> 5.2.0"
|
4
|
+
case ENV["DB"]
|
5
|
+
when "postgresql"
|
6
|
+
gem 'pg'
|
7
|
+
when "mysql"
|
8
|
+
gem 'mysql2', '~> 0.3'
|
9
|
+
else
|
10
|
+
gem "sqlite3", "~> 1.3", "< 1.4"
|
11
|
+
end
|
12
|
+
|
13
|
+
group :local_development do
|
14
|
+
gem "guard"
|
15
|
+
gem "guard-rspec"
|
16
|
+
gem "appraisal"
|
17
|
+
gem "rake"
|
18
|
+
gem "byebug", platforms: [:mri]
|
19
|
+
end
|
20
|
+
|
21
|
+
gemspec path: "../"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
gem "activerecord", "~> 6.0.0"
|
4
|
+
case ENV["DB"]
|
5
|
+
when "postgresql"
|
6
|
+
gem 'pg'
|
7
|
+
when "mysql"
|
8
|
+
gem 'mysql2', '~> 0.3'
|
9
|
+
else
|
10
|
+
gem 'sqlite3'
|
11
|
+
end
|
12
|
+
|
13
|
+
group :local_development do
|
14
|
+
gem "guard"
|
15
|
+
gem "guard-rspec"
|
16
|
+
gem "appraisal"
|
17
|
+
gem "rake"
|
18
|
+
gem "byebug", platforms: [:mri]
|
19
|
+
end
|
20
|
+
|
21
|
+
gemspec path: "../"
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'active_record/version'
|
3
|
+
require 'active_support/core_ext/module'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'rails/engine'
|
7
|
+
require 'acts_as_taggable_on/engine'
|
8
|
+
rescue LoadError
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'digest/sha1'
|
13
|
+
|
14
|
+
module ActsAsTaggableOn
|
15
|
+
extend ActiveSupport::Autoload
|
16
|
+
|
17
|
+
autoload :Tag
|
18
|
+
autoload :TagList
|
19
|
+
autoload :GenericParser
|
20
|
+
autoload :DefaultParser
|
21
|
+
autoload :Taggable
|
22
|
+
autoload :Tagger
|
23
|
+
autoload :Tagging
|
24
|
+
autoload :TagsHelper
|
25
|
+
autoload :VERSION
|
26
|
+
|
27
|
+
autoload_under 'taggable' do
|
28
|
+
autoload :Cache
|
29
|
+
autoload :Collection
|
30
|
+
autoload :Core
|
31
|
+
autoload :Dirty
|
32
|
+
autoload :Ownership
|
33
|
+
autoload :Related
|
34
|
+
autoload :TagListType
|
35
|
+
end
|
36
|
+
|
37
|
+
autoload :Utils
|
38
|
+
autoload :Compatibility
|
39
|
+
|
40
|
+
|
41
|
+
class DuplicateTagError < StandardError
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.setup
|
45
|
+
@configuration ||= Configuration.new
|
46
|
+
yield @configuration if block_given?
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.method_missing(method_name, *args, &block)
|
50
|
+
@configuration.respond_to?(method_name) ?
|
51
|
+
@configuration.send(method_name, *args, &block) : super
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.respond_to?(method_name, include_private=false)
|
55
|
+
@configuration.respond_to? method_name
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.glue
|
59
|
+
setting = @configuration.delimiter
|
60
|
+
delimiter = setting.kind_of?(Array) ? setting[0] : setting
|
61
|
+
delimiter.ends_with?(' ') ? delimiter : "#{delimiter} "
|
62
|
+
end
|
63
|
+
|
64
|
+
class Configuration
|
65
|
+
attr_accessor :force_lowercase, :force_parameterize,
|
66
|
+
:remove_unused_tags, :default_parser,
|
67
|
+
:tags_counter, :tags_table,
|
68
|
+
:taggings_table
|
69
|
+
attr_reader :delimiter, :strict_case_match
|
70
|
+
|
71
|
+
def initialize
|
72
|
+
@delimiter = ','
|
73
|
+
@force_lowercase = false
|
74
|
+
@force_parameterize = false
|
75
|
+
@strict_case_match = false
|
76
|
+
@remove_unused_tags = false
|
77
|
+
@tags_counter = true
|
78
|
+
@default_parser = DefaultParser
|
79
|
+
@force_binary_collation = false
|
80
|
+
@tags_table = :tags
|
81
|
+
@taggings_table = :taggings
|
82
|
+
end
|
83
|
+
|
84
|
+
def strict_case_match=(force_cs)
|
85
|
+
@strict_case_match = force_cs unless @force_binary_collation
|
86
|
+
end
|
87
|
+
|
88
|
+
def delimiter=(string)
|
89
|
+
ActiveRecord::Base.logger.warn <<WARNING
|
90
|
+
ActsAsTaggableOn.delimiter is deprecated \
|
91
|
+
and will be removed from v4.0+, use \
|
92
|
+
a ActsAsTaggableOn.default_parser instead
|
93
|
+
WARNING
|
94
|
+
@delimiter = string
|
95
|
+
end
|
96
|
+
|
97
|
+
def force_binary_collation=(force_bin)
|
98
|
+
if Utils.using_mysql?
|
99
|
+
if force_bin
|
100
|
+
Configuration.apply_binary_collation(true)
|
101
|
+
@force_binary_collation = true
|
102
|
+
@strict_case_match = true
|
103
|
+
else
|
104
|
+
Configuration.apply_binary_collation(false)
|
105
|
+
@force_binary_collation = false
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.apply_binary_collation(bincoll)
|
111
|
+
if Utils.using_mysql?
|
112
|
+
coll = 'utf8_general_ci'
|
113
|
+
coll = 'utf8_bin' if bincoll
|
114
|
+
begin
|
115
|
+
ActiveRecord::Migration.execute("ALTER TABLE #{Tag.table_name} MODIFY name varchar(255) CHARACTER SET utf8 COLLATE #{coll};")
|
116
|
+
rescue Exception => e
|
117
|
+
puts "Trapping #{e.class}: collation parameter ignored while migrating for the first time."
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
setup
|
125
|
+
end
|
126
|
+
|
127
|
+
ActiveSupport.on_load(:active_record) do
|
128
|
+
extend ActsAsTaggableOn::Taggable
|
129
|
+
include ActsAsTaggableOn::Tagger
|
130
|
+
end
|
131
|
+
ActiveSupport.on_load(:action_view) do
|
132
|
+
include ActsAsTaggableOn::TagsHelper
|
133
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module ActsAsTaggableOn
|
2
|
+
##
|
3
|
+
# Returns a new TagList using the given tag string.
|
4
|
+
#
|
5
|
+
# Example:
|
6
|
+
# tag_list = ActsAsTaggableOn::DefaultParser.parse("One , Two, Three")
|
7
|
+
# tag_list # ["One", "Two", "Three"]
|
8
|
+
class DefaultParser < GenericParser
|
9
|
+
|
10
|
+
def parse
|
11
|
+
string = @tag_list
|
12
|
+
|
13
|
+
string = string.join(ActsAsTaggableOn.glue) if string.respond_to?(:join)
|
14
|
+
TagList.new.tap do |tag_list|
|
15
|
+
string = string.to_s.dup
|
16
|
+
|
17
|
+
string.gsub!(double_quote_pattern) {
|
18
|
+
# Append the matched tag to the tag list
|
19
|
+
tag_list << Regexp.last_match[2]
|
20
|
+
# Return the matched delimiter ($3) to replace the matched items
|
21
|
+
''
|
22
|
+
}
|
23
|
+
|
24
|
+
string.gsub!(single_quote_pattern) {
|
25
|
+
# Append the matched tag ($2) to the tag list
|
26
|
+
tag_list << Regexp.last_match[2]
|
27
|
+
# Return an empty string to replace the matched items
|
28
|
+
''
|
29
|
+
}
|
30
|
+
|
31
|
+
# split the string by the delimiter
|
32
|
+
# and add to the tag_list
|
33
|
+
tag_list.add(string.split(Regexp.new delimiter))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
# private
|
39
|
+
def delimiter
|
40
|
+
# Parse the quoted tags
|
41
|
+
d = ActsAsTaggableOn.delimiter
|
42
|
+
# Separate multiple delimiters by bitwise operator
|
43
|
+
d = d.join('|') if d.kind_of?(Array)
|
44
|
+
d
|
45
|
+
end
|
46
|
+
|
47
|
+
# ( # Tag start delimiter ($1)
|
48
|
+
# \A | # Either string start or
|
49
|
+
# #{delimiter} # a delimiter
|
50
|
+
# )
|
51
|
+
# \s*" # quote (") optionally preceded by whitespace
|
52
|
+
# (.*?) # Tag ($2)
|
53
|
+
# "\s* # quote (") optionally followed by whitespace
|
54
|
+
# (?= # Tag end delimiter (not consumed; is zero-length lookahead)
|
55
|
+
# #{delimiter}\s* | # Either a delimiter optionally followed by whitespace or
|
56
|
+
# \z # string end
|
57
|
+
# )
|
58
|
+
def double_quote_pattern
|
59
|
+
/(\A|#{delimiter})\s*"(.*?)"\s*(?=#{delimiter}\s*|\z)/
|
60
|
+
end
|
61
|
+
|
62
|
+
# ( # Tag start delimiter ($1)
|
63
|
+
# \A | # Either string start or
|
64
|
+
# #{delimiter} # a delimiter
|
65
|
+
# )
|
66
|
+
# \s*' # quote (') optionally preceded by whitespace
|
67
|
+
# (.*?) # Tag ($2)
|
68
|
+
# '\s* # quote (') optionally followed by whitespace
|
69
|
+
# (?= # Tag end delimiter (not consumed; is zero-length lookahead)
|
70
|
+
# #{delimiter}\s* | d # Either a delimiter optionally followed by whitespace or
|
71
|
+
# \z # string end
|
72
|
+
# )
|
73
|
+
def single_quote_pattern
|
74
|
+
/(\A|#{delimiter})\s*'(.*?)'\s*(?=#{delimiter}\s*|\z)/
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|