acts-as-taggable-on 6.0.0 → 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 +4 -4
- data/.travis.yml +17 -7
- data/Appraisals +4 -0
- data/CHANGELOG.md +179 -140
- data/README.md +10 -1
- data/acts-as-taggable-on.gemspec +2 -2
- data/db/migrate/1_acts_as_taggable_on_migration.rb +8 -7
- data/db/migrate/2_add_missing_unique_indices.rb +8 -8
- data/db/migrate/3_add_taggings_counter_cache_to_tags.rb +3 -3
- data/db/migrate/4_add_missing_taggable_index.rb +2 -2
- data/db/migrate/5_change_collation_for_tag_names.rb +1 -1
- data/db/migrate/6_add_missing_indexes_on_taggings.rb +9 -9
- data/gemfiles/activerecord_5.0.gemfile +2 -4
- data/gemfiles/activerecord_5.1.gemfile +2 -4
- data/gemfiles/activerecord_5.2.gemfile +2 -4
- data/gemfiles/activerecord_6.0.gemfile +21 -0
- data/lib/acts-as-taggable-on.rb +5 -1
- data/lib/acts_as_taggable_on/tag.rb +9 -18
- data/lib/acts_as_taggable_on/taggable/cache.rb +38 -34
- data/lib/acts_as_taggable_on/taggable/collection.rb +8 -6
- data/lib/acts_as_taggable_on/taggable/core.rb +11 -5
- data/lib/acts_as_taggable_on/taggable/tag_list_type.rb +4 -0
- data/lib/acts_as_taggable_on/tagging.rb +3 -1
- data/lib/acts_as_taggable_on/utils.rb +4 -0
- data/lib/acts_as_taggable_on/version.rb +1 -2
- data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +4 -12
- data/spec/acts_as_taggable_on/caching_spec.rb +16 -10
- data/spec/acts_as_taggable_on/single_table_inheritance_spec.rb +12 -7
- data/spec/acts_as_taggable_on/taggable_spec.rb +9 -9
- data/spec/acts_as_taggable_on/tagger_spec.rb +2 -2
- data/spec/internal/app/models/altered_inheriting_taggable_model.rb +2 -0
- data/spec/internal/app/models/cached_model_with_array.rb +6 -0
- data/spec/internal/app/models/columns_override_model.rb +5 -0
- data/spec/internal/app/models/company.rb +1 -1
- data/spec/internal/app/models/inheriting_taggable_model.rb +2 -0
- data/spec/internal/app/models/market.rb +1 -1
- data/spec/internal/app/models/non_standard_id_taggable_model.rb +1 -1
- data/spec/internal/app/models/student.rb +2 -0
- data/spec/internal/app/models/taggable_model.rb +1 -0
- data/spec/internal/app/models/user.rb +1 -1
- data/spec/internal/db/schema.rb +11 -5
- data/spec/spec_helper.rb +0 -1
- data/spec/support/database.rb +3 -3
- metadata +16 -9
- data/spec/internal/app/models/models.rb +0 -90
data/README.md
CHANGED
@@ -57,7 +57,7 @@ was used.
|
|
57
57
|
To use it, add it to your Gemfile:
|
58
58
|
|
59
59
|
```ruby
|
60
|
-
gem 'acts-as-taggable-on', '~>
|
60
|
+
gem 'acts-as-taggable-on', '~> 6.0'
|
61
61
|
```
|
62
62
|
|
63
63
|
and bundle:
|
@@ -121,6 +121,7 @@ Add and remove a single tag
|
|
121
121
|
```ruby
|
122
122
|
@user.tag_list.add("awesome") # add a single tag. alias for <<
|
123
123
|
@user.tag_list.remove("awesome") # remove a single tag
|
124
|
+
@user.save # save to persist tag_list
|
124
125
|
```
|
125
126
|
|
126
127
|
Add and remove multiple tags in an array
|
@@ -128,6 +129,7 @@ Add and remove multiple tags in an array
|
|
128
129
|
```ruby
|
129
130
|
@user.tag_list.add("awesome", "slick")
|
130
131
|
@user.tag_list.remove("awesome", "slick")
|
132
|
+
@user.save
|
131
133
|
```
|
132
134
|
|
133
135
|
You can also add and remove tags in format of String. This would
|
@@ -486,6 +488,13 @@ If you would like to have an exact match covering special characters with MySql:
|
|
486
488
|
ActsAsTaggableOn.force_binary_collation = true
|
487
489
|
```
|
488
490
|
|
491
|
+
If you would like to specify table names:
|
492
|
+
|
493
|
+
```ruby
|
494
|
+
ActsAsTaggableOn.tags_table = 'aato_tags'
|
495
|
+
ActsAsTaggableOn.taggings_table = 'aato_taggings'
|
496
|
+
```
|
497
|
+
|
489
498
|
If you want to change the default delimiter (it defaults to ','). You can also pass in an array of delimiters such as ([',', '|']):
|
490
499
|
|
491
500
|
```ruby
|
data/acts-as-taggable-on.gemspec
CHANGED
@@ -16,13 +16,13 @@ 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 = '>= 2.
|
19
|
+
gem.required_ruby_version = '>= 2.3.7'
|
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',
|
25
|
+
gem.add_runtime_dependency 'activerecord', '>= 5.0', '< 6.1'
|
26
26
|
|
27
27
|
gem.add_development_dependency 'rspec-rails'
|
28
28
|
gem.add_development_dependency 'rspec-its'
|
@@ -5,12 +5,13 @@ else
|
|
5
5
|
end
|
6
6
|
ActsAsTaggableOnMigration.class_eval do
|
7
7
|
def self.up
|
8
|
-
create_table
|
8
|
+
create_table ActsAsTaggableOn.tags_table do |t|
|
9
9
|
t.string :name
|
10
|
+
t.timestamps
|
10
11
|
end
|
11
12
|
|
12
|
-
create_table
|
13
|
-
t.references :tag
|
13
|
+
create_table ActsAsTaggableOn.taggings_table do |t|
|
14
|
+
t.references :tag, foreign_key: { to_table: ActsAsTaggableOn.tags_table }
|
14
15
|
|
15
16
|
# You should make sure that the column created is
|
16
17
|
# long enough to store the required class names.
|
@@ -24,12 +25,12 @@ ActsAsTaggableOnMigration.class_eval do
|
|
24
25
|
t.datetime :created_at
|
25
26
|
end
|
26
27
|
|
27
|
-
add_index
|
28
|
-
add_index
|
28
|
+
add_index ActsAsTaggableOn.taggings_table, :tag_id
|
29
|
+
add_index ActsAsTaggableOn.taggings_table, [:taggable_id, :taggable_type, :context], name: 'taggings_taggable_context_idx'
|
29
30
|
end
|
30
31
|
|
31
32
|
def self.down
|
32
|
-
drop_table
|
33
|
-
drop_table
|
33
|
+
drop_table ActsAsTaggableOn.taggings_table
|
34
|
+
drop_table ActsAsTaggableOn.tags_table
|
34
35
|
end
|
35
36
|
end
|
@@ -5,21 +5,21 @@ else
|
|
5
5
|
end
|
6
6
|
AddMissingUniqueIndices.class_eval do
|
7
7
|
def self.up
|
8
|
-
add_index
|
8
|
+
add_index ActsAsTaggableOn.tags_table, :name, unique: true
|
9
9
|
|
10
|
-
remove_index
|
11
|
-
remove_index
|
12
|
-
add_index
|
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
13
|
[:tag_id, :taggable_id, :taggable_type, :context, :tagger_id, :tagger_type],
|
14
14
|
unique: true, name: 'taggings_idx'
|
15
15
|
end
|
16
16
|
|
17
17
|
def self.down
|
18
|
-
remove_index
|
18
|
+
remove_index ActsAsTaggableOn.tags_table, :name
|
19
19
|
|
20
|
-
remove_index
|
20
|
+
remove_index ActsAsTaggableOn.taggings_table, name: 'taggings_idx'
|
21
21
|
|
22
|
-
add_index
|
23
|
-
add_index
|
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
24
|
end
|
25
25
|
end
|
@@ -5,15 +5,15 @@ else
|
|
5
5
|
end
|
6
6
|
AddTaggingsCounterCacheToTags.class_eval do
|
7
7
|
def self.up
|
8
|
-
add_column
|
8
|
+
add_column ActsAsTaggableOn.tags_table, :taggings_count, :integer, default: 0
|
9
9
|
|
10
10
|
ActsAsTaggableOn::Tag.reset_column_information
|
11
11
|
ActsAsTaggableOn::Tag.find_each do |tag|
|
12
|
-
ActsAsTaggableOn::Tag.reset_counters(tag.id,
|
12
|
+
ActsAsTaggableOn::Tag.reset_counters(tag.id, ActsAsTaggableOn.taggings_table)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
def self.down
|
17
|
-
remove_column
|
17
|
+
remove_column ActsAsTaggableOn.tags_table, :taggings_count
|
18
18
|
end
|
19
19
|
end
|
@@ -5,10 +5,10 @@ else
|
|
5
5
|
end
|
6
6
|
AddMissingTaggableIndex.class_eval do
|
7
7
|
def self.up
|
8
|
-
add_index
|
8
|
+
add_index ActsAsTaggableOn.taggings_table, [:taggable_id, :taggable_type, :context], name: 'taggings_taggable_context_idx'
|
9
9
|
end
|
10
10
|
|
11
11
|
def self.down
|
12
|
-
remove_index
|
12
|
+
remove_index ActsAsTaggableOn.taggings_table, name: 'taggings_taggable_context_idx'
|
13
13
|
end
|
14
14
|
end
|
@@ -8,7 +8,7 @@ end
|
|
8
8
|
ChangeCollationForTagNames.class_eval do
|
9
9
|
def up
|
10
10
|
if ActsAsTaggableOn::Utils.using_mysql?
|
11
|
-
execute("ALTER TABLE
|
11
|
+
execute("ALTER TABLE #{ActsAsTaggableOn.tags_table} MODIFY name varchar(255) CHARACTER SET utf8 COLLATE utf8_bin;")
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
@@ -5,18 +5,18 @@ else
|
|
5
5
|
end
|
6
6
|
AddMissingIndexesOnTaggings.class_eval do
|
7
7
|
def change
|
8
|
-
add_index
|
9
|
-
add_index
|
10
|
-
add_index
|
11
|
-
add_index
|
12
|
-
add_index
|
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
13
|
|
14
|
-
unless index_exists?
|
15
|
-
add_index
|
14
|
+
unless index_exists? ActsAsTaggableOn.taggings_table, [:tagger_id, :tagger_type]
|
15
|
+
add_index ActsAsTaggableOn.taggings_table, [:tagger_id, :tagger_type]
|
16
16
|
end
|
17
17
|
|
18
|
-
unless index_exists?
|
19
|
-
add_index
|
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
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
1
|
source "https://rubygems.org"
|
4
2
|
|
5
3
|
gem "activerecord", "~> 5.0.3"
|
@@ -9,7 +7,7 @@ when "postgresql"
|
|
9
7
|
when "mysql"
|
10
8
|
gem 'mysql2', '~> 0.3'
|
11
9
|
else
|
12
|
-
gem
|
10
|
+
gem "sqlite3", "~> 1.3", "< 1.4"
|
13
11
|
end
|
14
12
|
|
15
13
|
group :local_development do
|
@@ -17,7 +15,7 @@ group :local_development do
|
|
17
15
|
gem "guard-rspec"
|
18
16
|
gem "appraisal"
|
19
17
|
gem "rake"
|
20
|
-
gem "byebug", platforms: [:
|
18
|
+
gem "byebug", platforms: [:mri]
|
21
19
|
end
|
22
20
|
|
23
21
|
gemspec path: "../"
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
1
|
source "https://rubygems.org"
|
4
2
|
|
5
3
|
gem "activerecord", "~> 5.1.1"
|
@@ -9,7 +7,7 @@ when "postgresql"
|
|
9
7
|
when "mysql"
|
10
8
|
gem 'mysql2', '~> 0.3'
|
11
9
|
else
|
12
|
-
gem
|
10
|
+
gem "sqlite3", "~> 1.3", "< 1.4"
|
13
11
|
end
|
14
12
|
|
15
13
|
group :local_development do
|
@@ -17,7 +15,7 @@ group :local_development do
|
|
17
15
|
gem "guard-rspec"
|
18
16
|
gem "appraisal"
|
19
17
|
gem "rake"
|
20
|
-
gem "byebug", platforms: [:
|
18
|
+
gem "byebug", platforms: [:mri]
|
21
19
|
end
|
22
20
|
|
23
21
|
gemspec path: "../"
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
1
|
source "https://rubygems.org"
|
4
2
|
|
5
3
|
gem "activerecord", "~> 5.2.0"
|
@@ -9,7 +7,7 @@ when "postgresql"
|
|
9
7
|
when "mysql"
|
10
8
|
gem 'mysql2', '~> 0.3'
|
11
9
|
else
|
12
|
-
gem
|
10
|
+
gem "sqlite3", "~> 1.3", "< 1.4"
|
13
11
|
end
|
14
12
|
|
15
13
|
group :local_development do
|
@@ -17,7 +15,7 @@ group :local_development do
|
|
17
15
|
gem "guard-rspec"
|
18
16
|
gem "appraisal"
|
19
17
|
gem "rake"
|
20
|
-
gem "byebug", platforms: [:
|
18
|
+
gem "byebug", platforms: [:mri]
|
21
19
|
end
|
22
20
|
|
23
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: "../"
|
data/lib/acts-as-taggable-on.rb
CHANGED
@@ -31,6 +31,7 @@ module ActsAsTaggableOn
|
|
31
31
|
autoload :Dirty
|
32
32
|
autoload :Ownership
|
33
33
|
autoload :Related
|
34
|
+
autoload :TagListType
|
34
35
|
end
|
35
36
|
|
36
37
|
autoload :Utils
|
@@ -63,7 +64,8 @@ module ActsAsTaggableOn
|
|
63
64
|
class Configuration
|
64
65
|
attr_accessor :force_lowercase, :force_parameterize,
|
65
66
|
:remove_unused_tags, :default_parser,
|
66
|
-
:tags_counter
|
67
|
+
:tags_counter, :tags_table,
|
68
|
+
:taggings_table
|
67
69
|
attr_reader :delimiter, :strict_case_match
|
68
70
|
|
69
71
|
def initialize
|
@@ -75,6 +77,8 @@ module ActsAsTaggableOn
|
|
75
77
|
@tags_counter = true
|
76
78
|
@default_parser = DefaultParser
|
77
79
|
@force_binary_collation = false
|
80
|
+
@tags_table = :tags
|
81
|
+
@taggings_table = :taggings
|
78
82
|
end
|
79
83
|
|
80
84
|
def strict_case_match=(force_cs)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module ActsAsTaggableOn
|
3
3
|
class Tag < ::ActiveRecord::Base
|
4
|
+
self.table_name = ActsAsTaggableOn.tags_table
|
4
5
|
|
5
6
|
### ASSOCIATIONS:
|
6
7
|
|
@@ -50,8 +51,8 @@ module ActsAsTaggableOn
|
|
50
51
|
|
51
52
|
def self.for_context(context)
|
52
53
|
joins(:taggings).
|
53
|
-
where(["
|
54
|
-
select("DISTINCT
|
54
|
+
where(["#{ActsAsTaggableOn.taggings_table}.context = ?", context]).
|
55
|
+
select("DISTINCT #{ActsAsTaggableOn.tags_table}.*")
|
55
56
|
end
|
56
57
|
|
57
58
|
### CLASS METHODS:
|
@@ -69,17 +70,17 @@ module ActsAsTaggableOn
|
|
69
70
|
|
70
71
|
return [] if list.empty?
|
71
72
|
|
73
|
+
existing_tags = named_any(list)
|
72
74
|
list.map do |tag_name|
|
73
75
|
begin
|
74
76
|
tries ||= 3
|
75
|
-
|
76
|
-
existing_tags = named_any(list)
|
77
77
|
comparable_tag_name = comparable_name(tag_name)
|
78
78
|
existing_tag = existing_tags.find { |tag| comparable_name(tag.name) == comparable_tag_name }
|
79
79
|
existing_tag || create(name: tag_name)
|
80
80
|
rescue ActiveRecord::RecordNotUnique
|
81
81
|
if (tries -= 1).positive?
|
82
82
|
ActiveRecord::Base.connection.execute 'ROLLBACK'
|
83
|
+
existing_tags = named_any(list)
|
83
84
|
retry
|
84
85
|
end
|
85
86
|
|
@@ -104,8 +105,6 @@ module ActsAsTaggableOn
|
|
104
105
|
|
105
106
|
class << self
|
106
107
|
|
107
|
-
|
108
|
-
|
109
108
|
private
|
110
109
|
|
111
110
|
def comparable_name(str)
|
@@ -120,20 +119,12 @@ module ActsAsTaggableOn
|
|
120
119
|
ActsAsTaggableOn::Utils.using_mysql? ? 'BINARY ' : nil
|
121
120
|
end
|
122
121
|
|
123
|
-
def
|
124
|
-
|
125
|
-
ActiveSupport::Multibyte::Unicode.downcase(string)
|
126
|
-
else
|
127
|
-
ActiveSupport::Multibyte::Chars.new(string).downcase.to_s
|
128
|
-
end
|
122
|
+
def as_8bit_ascii(string)
|
123
|
+
string.to_s.mb_chars
|
129
124
|
end
|
130
125
|
|
131
|
-
def
|
132
|
-
|
133
|
-
string.to_s.dup.force_encoding('BINARY')
|
134
|
-
else
|
135
|
-
string.to_s.mb_chars
|
136
|
-
end
|
126
|
+
def unicode_downcase(string)
|
127
|
+
as_8bit_ascii(string).downcase
|
137
128
|
end
|
138
129
|
|
139
130
|
def sanitize_sql_for_named_any(tag)
|
@@ -3,47 +3,51 @@ module ActsAsTaggableOn::Taggable
|
|
3
3
|
def self.included(base)
|
4
4
|
# When included, conditionally adds tag caching methods when the model
|
5
5
|
# has any "cached_#{tag_type}_list" column
|
6
|
-
base.
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
base.extend Columns
|
7
|
+
end
|
8
|
+
|
9
|
+
module Columns
|
10
|
+
# ActiveRecord::Base.columns makes a database connection and caches the
|
11
|
+
# calculated columns hash for the record as @columns. Since we don't
|
12
|
+
# want to add caching methods until we confirm the presence of a
|
13
|
+
# caching column, and we don't want to force opening a database
|
14
|
+
# connection when the class is loaded, here we intercept and cache
|
15
|
+
# the call to :columns as @acts_as_taggable_on_cache_columns
|
16
|
+
# to mimic the underlying behavior. While processing this first
|
17
|
+
# call to columns, we do the caching column check and dynamically add
|
18
|
+
# the class and instance methods
|
19
|
+
# FIXME: this method cannot compile in rubinius
|
20
|
+
def columns
|
21
|
+
@acts_as_taggable_on_cache_columns ||= begin
|
22
|
+
db_columns = super
|
23
|
+
_add_tags_caching_methods if _has_tags_cache_columns?(db_columns)
|
24
|
+
db_columns
|
13
25
|
end
|
26
|
+
end
|
14
27
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
28
|
+
def reset_column_information
|
29
|
+
super
|
30
|
+
@acts_as_taggable_on_cache_columns = nil
|
31
|
+
end
|
19
32
|
|
20
|
-
|
33
|
+
private
|
21
34
|
|
22
|
-
|
35
|
+
# @private
|
36
|
+
def _has_tags_cache_columns?(db_columns)
|
37
|
+
db_column_names = db_columns.map(&:name)
|
38
|
+
tag_types.any? do |context|
|
39
|
+
db_column_names.include?("cached_#{context.to_s.singularize}_list")
|
23
40
|
end
|
41
|
+
end
|
24
42
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
# connection when the class is loaded, here we intercept and cache
|
30
|
-
# the call to :columns as @acts_as_taggable_on_cache_columns
|
31
|
-
# to mimic the underlying behavior. While processing this first
|
32
|
-
# call to columns, we do the caching column check and dynamically add
|
33
|
-
# the class and instance methods
|
34
|
-
# FIXME: this method cannot compile in rubinius
|
35
|
-
def columns
|
36
|
-
@acts_as_taggable_on_cache_columns ||= begin
|
37
|
-
db_columns = super
|
38
|
-
_add_tags_caching_methods if _has_tags_cache_columns?(db_columns)
|
39
|
-
db_columns
|
40
|
-
end
|
41
|
-
end
|
43
|
+
# @private
|
44
|
+
def _add_tags_caching_methods
|
45
|
+
send :include, ActsAsTaggableOn::Taggable::Cache::InstanceMethods
|
46
|
+
extend ActsAsTaggableOn::Taggable::Cache::ClassMethods
|
42
47
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
end
|
48
|
+
before_save :save_cached_tag_list
|
49
|
+
|
50
|
+
initialize_tags_cache
|
47
51
|
end
|
48
52
|
end
|
49
53
|
|