acts-as-taggable-on 1.1.9 → 2.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -2
- data/Gemfile +8 -0
- data/README.rdoc +0 -10
- data/Rakefile +6 -5
- data/VERSION +1 -1
- data/lib/acts-as-taggable-on.rb +27 -7
- data/lib/acts_as_taggable_on/acts_as_taggable_on.rb +66 -85
- data/lib/acts_as_taggable_on/acts_as_tagger.rb +21 -13
- data/lib/acts_as_taggable_on/group_helper.rb +2 -0
- data/lib/acts_as_taggable_on/tag.rb +23 -22
- data/lib/acts_as_taggable_on/tag_list.rb +24 -19
- data/lib/acts_as_taggable_on/tagging.rb +15 -7
- data/lib/acts_as_taggable_on/tags_helper.rb +6 -2
- data/lib/generators/acts_as_taggable_on/migration/migration_generator.rb +31 -0
- data/{generators/acts_as_taggable_on_migration/templates → lib/generators/acts_as_taggable_on/migration/templates/active_record}/migration.rb +12 -13
- data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +5 -9
- data/spec/acts_as_taggable_on/group_helper_spec.rb +1 -1
- data/spec/acts_as_taggable_on/tag_spec.rb +20 -20
- data/spec/acts_as_taggable_on/taggable_spec.rb +26 -45
- data/spec/acts_as_taggable_on/tagger_spec.rb +0 -16
- data/spec/acts_as_taggable_on/tagging_spec.rb +5 -5
- data/spec/schema.rb +2 -4
- data/spec/spec.opts +1 -2
- data/spec/spec_helper.rb +6 -10
- metadata +20 -10
- data/generators/acts_as_taggable_on_migration/acts_as_taggable_on_migration_generator.rb +0 -7
- data/rails/init.rb +0 -5
data/CHANGELOG
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
== 2010-02-17
|
2
|
+
* Converted the plugin to be compatible with Rails3
|
3
|
+
|
1
4
|
== 2009-12-02
|
2
5
|
|
3
6
|
* PostgreSQL is now supported (via morgoth)
|
@@ -12,10 +15,10 @@
|
|
12
15
|
* Removed extraneous down migration cruft (azabaj)
|
13
16
|
|
14
17
|
== 2008-06-09
|
15
|
-
|
18
|
+
|
16
19
|
* Added support for Single Table Inheritance
|
17
20
|
* Adding gemspec and rails/init.rb for gemified plugin
|
18
|
-
|
21
|
+
|
19
22
|
== 2007-12-12
|
20
23
|
|
21
24
|
* Added ability to use dynamic tag contexts
|
data/Gemfile
ADDED
data/README.rdoc
CHANGED
@@ -31,16 +31,6 @@ To install the gem, add this to your config/environment.rb:
|
|
31
31
|
|
32
32
|
After that, you can run "rake gems:install" to install the gem if you don't already have it.
|
33
33
|
|
34
|
-
== Rails 3.0
|
35
|
-
|
36
|
-
Acts As Taggable On is now useable in Rails 3.0, thanks to the excellent work of Szymon Nowak
|
37
|
-
and Jelle Vandebeeck. Because backwards compatibility is hard to maintain, their work is available
|
38
|
-
in the feature/rails3_compatibility branch.
|
39
|
-
|
40
|
-
A Rails 3.0 compatible version of the gem is also available:
|
41
|
-
|
42
|
-
gem install acts-as-taggable-on -v=2.0.0.pre1
|
43
|
-
|
44
34
|
=== Post Installation (Rails)
|
45
35
|
|
46
36
|
1. script/generate acts_as_taggable_on_migration
|
data/Rakefile
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
gem 'rspec', '2.0.0.beta.1'
|
2
|
+
require 'rspec/core/rake_task'
|
2
3
|
|
3
4
|
begin
|
4
5
|
require 'jeweler'
|
@@ -18,12 +19,12 @@ end
|
|
18
19
|
|
19
20
|
desc 'Default: run specs'
|
20
21
|
task :default => :spec
|
21
|
-
|
22
|
-
t.
|
22
|
+
Rspec::Core::RakeTask.new do |t|
|
23
|
+
t.pattern = "spec/**/*_spec.rb"
|
23
24
|
end
|
24
25
|
|
25
|
-
|
26
|
-
t.
|
26
|
+
Rspec::Core::RakeTask.new('rcov') do |t|
|
27
|
+
t.pattern = "spec/**/*_spec.rb"
|
27
28
|
t.rcov = true
|
28
29
|
t.rcov_opts = ['--exclude', 'spec']
|
29
30
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.0.0.pre1
|
data/lib/acts-as-taggable-on.rb
CHANGED
@@ -1,7 +1,27 @@
|
|
1
|
-
|
2
|
-
require
|
3
|
-
require
|
4
|
-
|
5
|
-
|
6
|
-
require
|
7
|
-
require
|
1
|
+
begin
|
2
|
+
# Try to require the preresolved locked set of gems.
|
3
|
+
require File.expand_path("../.bundle/environment", __FILE__)
|
4
|
+
rescue LoadError
|
5
|
+
# Fall back on doing an unlocked resolve at runtime.
|
6
|
+
require "rubygems"
|
7
|
+
require "bundler"
|
8
|
+
Bundler.setup
|
9
|
+
end
|
10
|
+
|
11
|
+
Bundler.require
|
12
|
+
|
13
|
+
require "active_record"
|
14
|
+
require "action_view"
|
15
|
+
|
16
|
+
require "acts_as_taggable_on/group_helper"
|
17
|
+
require "acts_as_taggable_on/acts_as_taggable_on"
|
18
|
+
require "acts_as_taggable_on/acts_as_tagger"
|
19
|
+
require "acts_as_taggable_on/tag"
|
20
|
+
require "acts_as_taggable_on/tag_list"
|
21
|
+
require "acts_as_taggable_on/tags_helper"
|
22
|
+
require "acts_as_taggable_on/tagging"
|
23
|
+
|
24
|
+
ActiveRecord::Base.send :include, ActiveRecord::Acts::TaggableOn
|
25
|
+
ActiveRecord::Base.send :include, ActiveRecord::Acts::Tagger
|
26
|
+
|
27
|
+
ActionView::Base.send :include, TagsHelper
|
@@ -1,11 +1,13 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module Acts
|
3
3
|
module TaggableOn
|
4
|
+
|
4
5
|
def self.included(base)
|
5
6
|
base.extend(ClassMethods)
|
6
7
|
end
|
7
8
|
|
8
9
|
module ClassMethods
|
10
|
+
|
9
11
|
def taggable?
|
10
12
|
false
|
11
13
|
end
|
@@ -17,6 +19,7 @@ module ActiveRecord
|
|
17
19
|
def acts_as_taggable_on(*args)
|
18
20
|
args.flatten! if args
|
19
21
|
args.compact! if args
|
22
|
+
|
20
23
|
for tag_type in args
|
21
24
|
tag_type = tag_type.to_s
|
22
25
|
# use aliased_join_table_name for context condition so that sphinx can join multiple
|
@@ -28,6 +31,7 @@ module ActiveRecord
|
|
28
31
|
end
|
29
32
|
|
30
33
|
class_eval <<-RUBY
|
34
|
+
|
31
35
|
def self.taggable?
|
32
36
|
true
|
33
37
|
end
|
@@ -43,10 +47,6 @@ module ActiveRecord
|
|
43
47
|
def #{tag_type.singularize}_list
|
44
48
|
tag_list_on('#{tag_type}')
|
45
49
|
end
|
46
|
-
|
47
|
-
def all_#{tag_type}_list
|
48
|
-
all_tags_list_on('#{tag_type}')
|
49
|
-
end
|
50
50
|
|
51
51
|
def #{tag_type.singularize}_list=(new_tags)
|
52
52
|
set_tag_list_on('#{tag_type}',new_tags)
|
@@ -72,7 +72,7 @@ module ActiveRecord
|
|
72
72
|
def find_matching_contexts(search_context, result_context, options = {})
|
73
73
|
matching_contexts_for(search_context.to_s, result_context.to_s, self.class, options)
|
74
74
|
end
|
75
|
-
|
75
|
+
|
76
76
|
def find_matching_contexts_for(klass, search_context, result_context, options = {})
|
77
77
|
matching_contexts_for(search_context.to_s, result_context.to_s, klass, options)
|
78
78
|
end
|
@@ -84,8 +84,10 @@ module ActiveRecord
|
|
84
84
|
def self.top_#{tag_type}(limit = 10)
|
85
85
|
tag_counts_on('#{tag_type}', :order => 'count desc', :limit => limit.to_i)
|
86
86
|
end
|
87
|
+
|
87
88
|
RUBY
|
88
89
|
end
|
90
|
+
|
89
91
|
if respond_to?(:tag_types)
|
90
92
|
write_inheritable_attribute( :tag_types, (tag_types + args).uniq )
|
91
93
|
else
|
@@ -99,23 +101,26 @@ module ActiveRecord
|
|
99
101
|
attr_writer :custom_contexts
|
100
102
|
|
101
103
|
before_save :save_cached_tag_list
|
102
|
-
after_save :save_tags
|
103
104
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
105
|
+
after_save:save_tags
|
106
|
+
|
107
|
+
scope :tagged_with, lambda{ |*args|
|
108
|
+
find_options_for_find_tagged_with(*args)
|
109
|
+
}
|
109
110
|
end
|
110
111
|
|
111
112
|
include ActiveRecord::Acts::TaggableOn::InstanceMethods
|
112
113
|
extend ActiveRecord::Acts::TaggableOn::SingletonMethods
|
114
|
+
alias_method_chain :reload, :tag_list
|
113
115
|
end
|
114
116
|
end
|
117
|
+
|
115
118
|
end
|
116
119
|
|
117
120
|
module SingletonMethods
|
121
|
+
|
118
122
|
include ActiveRecord::Acts::TaggableOn::GroupHelper
|
123
|
+
|
119
124
|
# Pass either a tag string, or an array of strings or tags
|
120
125
|
#
|
121
126
|
# Options:
|
@@ -124,21 +129,20 @@ module ActiveRecord
|
|
124
129
|
# :match_all - Find models that match all of the given tags, not just one
|
125
130
|
# :conditions - A piece of SQL conditions to add to the query
|
126
131
|
# :on - scopes the find to a context
|
127
|
-
def find_tagged_with(*args)
|
128
|
-
|
129
|
-
|
130
|
-
end
|
132
|
+
# def find_tagged_with(*args)
|
133
|
+
# find_options_for_find_tagged_with(*args)
|
134
|
+
# end
|
131
135
|
|
132
136
|
def caching_tag_list_on?(context)
|
133
137
|
column_names.include?("cached_#{context.to_s.singularize}_list")
|
134
138
|
end
|
135
139
|
|
136
140
|
def tag_counts_on(context, options = {})
|
137
|
-
|
141
|
+
find_for_tag_counts(options.merge({:on => context.to_s}))
|
138
142
|
end
|
139
143
|
|
140
144
|
def all_tag_counts(options = {})
|
141
|
-
|
145
|
+
find_for_tag_counts(options)
|
142
146
|
end
|
143
147
|
|
144
148
|
def find_options_for_find_tagged_with(tags, options = {})
|
@@ -151,7 +155,6 @@ module ActiveRecord
|
|
151
155
|
|
152
156
|
context = options.delete(:on)
|
153
157
|
|
154
|
-
|
155
158
|
if options.delete(:exclude)
|
156
159
|
tags_conditions = tag_list.map { |t| sanitize_sql(["#{Tag.table_name}.name LIKE ?", t]) }.join(" OR ")
|
157
160
|
conditions << "#{table_name}.#{primary_key} NOT IN (SELECT #{Tagging.table_name}.taggable_id FROM #{Tagging.table_name} JOIN #{Tag.table_name} ON #{Tagging.table_name}.tag_id = #{Tag.table_name}.id AND (#{tags_conditions}) WHERE #{Tagging.table_name}.taggable_type = #{quote_value(base_class.name)})"
|
@@ -163,7 +166,7 @@ module ActiveRecord
|
|
163
166
|
else
|
164
167
|
tags = Tag.named_any(tag_list)
|
165
168
|
return { :conditions => "1 = 0" } unless tags.length == tag_list.length
|
166
|
-
|
169
|
+
|
167
170
|
tags.each do |tag|
|
168
171
|
safe_tag = tag.name.gsub(/[^a-zA-Z0-9]/, '')
|
169
172
|
prefix = "#{safe_tag}_#{rand(1024)}"
|
@@ -190,10 +193,12 @@ module ActiveRecord
|
|
190
193
|
group = "#{grouped_column_names_for(self)} HAVING COUNT(#{taggings_alias}.taggable_id) = #{tags.size}"
|
191
194
|
end
|
192
195
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
196
|
+
Tag.joins(joins.join(" ")).group(group).where(conditions.join(" AND ")).readonly(false)
|
197
|
+
|
198
|
+
# { :joins => joins.join(" "),
|
199
|
+
# :group => group,
|
200
|
+
# :conditions => conditions.join(" AND "),
|
201
|
+
# :readonly => false }.update(options)
|
197
202
|
end
|
198
203
|
|
199
204
|
# Calculate the tag counts for all tags.
|
@@ -207,10 +212,9 @@ module ActiveRecord
|
|
207
212
|
# :at_least - Exclude tags with a frequency less than the given value
|
208
213
|
# :at_most - Exclude tags with a frequency greater than the given value
|
209
214
|
# :on - Scope the find to only include a certain context
|
210
|
-
def
|
215
|
+
def find_for_tag_counts(options = {})
|
211
216
|
options.assert_valid_keys :start_at, :end_at, :conditions, :at_least, :at_most, :order, :limit, :on, :id
|
212
217
|
|
213
|
-
scope = scope(:find)
|
214
218
|
start_at = sanitize_sql(["#{Tagging.table_name}.created_at >= ?", options.delete(:start_at)]) if options[:start_at]
|
215
219
|
end_at = sanitize_sql(["#{Tagging.table_name}.created_at <= ?", options.delete(:end_at)]) if options[:end_at]
|
216
220
|
|
@@ -227,58 +231,34 @@ module ActiveRecord
|
|
227
231
|
]
|
228
232
|
|
229
233
|
conditions = conditions.compact.join(' AND ')
|
230
|
-
conditions = merge_conditions(conditions, scope[:conditions]) if scope
|
231
234
|
|
232
235
|
joins = ["LEFT OUTER JOIN #{Tagging.table_name} ON #{Tag.table_name}.id = #{Tagging.table_name}.tag_id"]
|
233
236
|
joins << sanitize_sql(["AND #{Tagging.table_name}.context = ?",options.delete(:on).to_s]) unless options[:on].nil?
|
234
237
|
joins << " INNER JOIN #{table_name} ON #{table_name}.#{primary_key} = #{Tagging.table_name}.taggable_id"
|
235
|
-
|
238
|
+
|
236
239
|
unless descends_from_active_record?
|
237
240
|
# Current model is STI descendant, so add type checking to the join condition
|
238
241
|
joins << " AND #{table_name}.#{inheritance_column} = '#{name}'"
|
239
242
|
end
|
240
243
|
|
241
|
-
# Based on a proposed patch by donV to ActiveRecord Base
|
242
|
-
# This is needed because merge_joins and construct_join are private in ActiveRecord Base
|
243
|
-
if scope && scope[:joins]
|
244
|
-
case scope[:joins]
|
245
|
-
when Array
|
246
|
-
scope_joins = scope[:joins].flatten
|
247
|
-
strings = scope_joins.select{|j| j.is_a? String}
|
248
|
-
joins << strings.join(' ') + " "
|
249
|
-
symbols = scope_joins - strings
|
250
|
-
join_dependency = ActiveRecord::Associations::ClassMethods::InnerJoinDependency.new(self, symbols, nil)
|
251
|
-
joins << " #{join_dependency.join_associations.collect { |assoc| assoc.association_join }.join} "
|
252
|
-
joins.flatten!
|
253
|
-
when Symbol, Hash
|
254
|
-
join_dependency = ActiveRecord::Associations::ClassMethods::InnerJoinDependency.new(self, scope[:joins], nil)
|
255
|
-
joins << " #{join_dependency.join_associations.collect { |assoc| assoc.association_join }.join} "
|
256
|
-
when String
|
257
|
-
joins << scope[:joins]
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
244
|
at_least = sanitize_sql(['COUNT(*) >= ?', options.delete(:at_least)]) if options[:at_least]
|
262
245
|
at_most = sanitize_sql(['COUNT(*) <= ?', options.delete(:at_most)]) if options[:at_most]
|
263
246
|
having = [at_least, at_most].compact.join(' AND ')
|
264
247
|
group_by = "#{grouped_column_names_for(Tag)} HAVING COUNT(*) > 0"
|
265
248
|
group_by << " AND #{having}" unless having.blank?
|
266
249
|
|
267
|
-
|
268
|
-
|
269
|
-
:conditions => conditions,
|
270
|
-
:group => group_by,
|
271
|
-
:limit => options[:limit],
|
272
|
-
:order => options[:order]
|
273
|
-
}
|
250
|
+
Tag.select("#{Tag.table_name}.*, COUNT(*) AS count").joins(joins.join(" ")).where(conditions).group(group_by).limit(options[:limit]).order(options[:order])
|
251
|
+
|
274
252
|
end
|
275
253
|
|
276
254
|
def is_taggable?
|
277
255
|
true
|
278
256
|
end
|
257
|
+
|
279
258
|
end
|
280
259
|
|
281
260
|
module InstanceMethods
|
261
|
+
|
282
262
|
include ActiveRecord::Acts::TaggableOn::GroupHelper
|
283
263
|
|
284
264
|
def custom_contexts
|
@@ -288,7 +268,7 @@ module ActiveRecord
|
|
288
268
|
def is_taggable?
|
289
269
|
self.class.is_taggable?
|
290
270
|
end
|
291
|
-
|
271
|
+
|
292
272
|
def add_custom_context(value)
|
293
273
|
custom_contexts << value.to_s unless custom_contexts.include?(value.to_s) or self.class.tag_types.map(&:to_s).include?(value.to_s)
|
294
274
|
end
|
@@ -297,40 +277,38 @@ module ActiveRecord
|
|
297
277
|
add_custom_context(context)
|
298
278
|
cache = tag_list_cache_on(context)
|
299
279
|
return owner ? cache[owner] : cache[owner] if cache[owner]
|
300
|
-
|
280
|
+
|
301
281
|
if !owner && self.class.caching_tag_list_on?(context) and !(cached_value = cached_tag_list_on(context)).nil?
|
302
282
|
cache[owner] = TagList.from(cached_tag_list_on(context))
|
303
283
|
else
|
304
284
|
cache[owner] = TagList.new(*tags_on(context, owner).map(&:name))
|
305
285
|
end
|
306
286
|
end
|
307
|
-
|
287
|
+
|
308
288
|
def all_tags_list_on(context)
|
309
289
|
variable_name = "@all_#{context.to_s.singularize}_list"
|
310
290
|
return instance_variable_get(variable_name) if instance_variable_get(variable_name)
|
311
291
|
instance_variable_set(variable_name, TagList.new(all_tags_on(context).map(&:name)).freeze)
|
312
292
|
end
|
313
|
-
|
293
|
+
|
314
294
|
def all_tags_on(context)
|
315
|
-
opts =
|
316
|
-
base_tags.
|
295
|
+
opts = ["#{Tagging.table_name}.context = ?", context.to_s]
|
296
|
+
base_tags.where(opts).order("#{Tagging.table_name}.created_at")
|
317
297
|
end
|
318
298
|
|
319
299
|
def tags_on(context, owner = nil)
|
320
300
|
if owner
|
321
|
-
opts =
|
322
|
-
context.to_s, owner.id, owner.class.to_s]}
|
301
|
+
opts = ["#{Tagging.table_name}.context = ? AND #{Tagging.table_name}.tagger_id = ? AND #{Tagging.table_name}.tagger_type = ?", context.to_s, owner.id, owner.class.to_s]
|
323
302
|
else
|
324
|
-
opts =
|
303
|
+
opts = ["#{Tagging.table_name}.context = ? AND #{Tagging.table_name}.tagger_id IS NULL", context.to_s]
|
325
304
|
end
|
326
|
-
|
327
|
-
base_tags.find(:all, opts)
|
305
|
+
base_tags.where(opts)
|
328
306
|
end
|
329
307
|
|
330
308
|
def cached_tag_list_on(context)
|
331
309
|
self["cached_#{context.to_s.singularize}_list"]
|
332
310
|
end
|
333
|
-
|
311
|
+
|
334
312
|
def tag_list_cache_on(context)
|
335
313
|
variable_name = "@#{context.to_s.singularize}_list"
|
336
314
|
cache = instance_variable_get(variable_name)
|
@@ -350,7 +328,7 @@ module ActiveRecord
|
|
350
328
|
def related_tags_for(context, klass, options = {})
|
351
329
|
search_conditions = related_search_options(context, klass, options)
|
352
330
|
|
353
|
-
klass.
|
331
|
+
klass.select(search_conditions[:select]).from(search_conditions[:from]).where(search_conditions[:conditions]).group(search_conditions[:group]).order(search_conditions[:order])
|
354
332
|
end
|
355
333
|
|
356
334
|
def related_search_options(context, klass, options = {})
|
@@ -365,13 +343,13 @@ module ActiveRecord
|
|
365
343
|
:order => "count DESC"
|
366
344
|
}.update(options)
|
367
345
|
end
|
368
|
-
|
346
|
+
|
369
347
|
def matching_contexts_for(search_context, result_context, klass, options = {})
|
370
348
|
search_conditions = matching_context_search_options(search_context, result_context, klass, options)
|
371
349
|
|
372
|
-
klass.
|
350
|
+
klass.select(search_conditions[:select]).from(search_conditions[:from]).where(search_conditions[:conditions]).group(search_conditions[:group]).order(search_conditions[:order])
|
373
351
|
end
|
374
|
-
|
352
|
+
|
375
353
|
def matching_context_search_options(search_context, result_context, klass, options = {})
|
376
354
|
tags_to_find = tags_on(search_context).collect { |t| t.name }
|
377
355
|
|
@@ -388,7 +366,7 @@ module ActiveRecord
|
|
388
366
|
def save_cached_tag_list
|
389
367
|
self.class.tag_types.map(&:to_s).each do |tag_type|
|
390
368
|
if self.class.send("caching_#{tag_type.singularize}_list?")
|
391
|
-
|
369
|
+
self["cached_#{tag_type.singularize}_list"] = tag_list_cache_on(tag_type.singularize).to_a.flatten.compact.join(', ')
|
392
370
|
end
|
393
371
|
end
|
394
372
|
end
|
@@ -399,28 +377,22 @@ module ActiveRecord
|
|
399
377
|
transaction do
|
400
378
|
contexts.each do |context|
|
401
379
|
cache = tag_list_cache_on(context)
|
402
|
-
|
380
|
+
|
403
381
|
cache.each do |owner, list|
|
404
382
|
new_tags = Tag.find_or_create_all_with_like_by_name(list.uniq)
|
405
|
-
taggings = Tagging.
|
383
|
+
taggings = Tagging.where({ :taggable_id => self.id, :taggable_type => self.class.base_class.to_s })
|
406
384
|
|
407
385
|
# Destroy old taggings:
|
408
386
|
if owner
|
409
387
|
old_tags = tags_on(context, owner) - new_tags
|
410
|
-
old_taggings = Tagging.
|
388
|
+
old_taggings = Tagging.where({ :taggable_id => self.id, :taggable_type => self.class.base_class.to_s, :tag_id => old_tags, :tagger_id => owner.id, :tagger_type => owner.class.to_s, :context => context })
|
411
389
|
|
412
|
-
|
413
|
-
Tagging.destroy_all :id => old_taggings.map(&:id)
|
414
|
-
end
|
390
|
+
Tagging.destroy_all :id => old_taggings.map(&:id)
|
415
391
|
else
|
416
392
|
old_tags = tags_on(context) - new_tags
|
417
|
-
|
418
|
-
|
419
|
-
if old_taggings.present?
|
420
|
-
Tagging.destroy_all :id => old_taggings.map(&:id)
|
421
|
-
end
|
393
|
+
base_tags.delete(*old_tags)
|
422
394
|
end
|
423
|
-
|
395
|
+
|
424
396
|
new_tags.reject! { |tag| taggings.any? { |tagging|
|
425
397
|
tagging.tag_id == tag.id &&
|
426
398
|
tagging.tagger_id == (owner ? owner.id : nil) &&
|
@@ -428,17 +400,26 @@ module ActiveRecord
|
|
428
400
|
tagging.context == context
|
429
401
|
}
|
430
402
|
}
|
431
|
-
|
403
|
+
|
432
404
|
# create new taggings:
|
433
405
|
new_tags.each do |tag|
|
434
406
|
Tagging.create!(:tag_id => tag.id, :context => context, :tagger => owner, :taggable => self)
|
435
407
|
end
|
436
408
|
end
|
437
409
|
end
|
438
|
-
end
|
410
|
+
end
|
439
411
|
|
440
412
|
true
|
441
413
|
end
|
414
|
+
|
415
|
+
def reload_with_tag_list(*args)
|
416
|
+
self.class.tag_types.each do |tag_type|
|
417
|
+
instance_variable_set("@#{tag_type.to_s.singularize}_list", nil)
|
418
|
+
end
|
419
|
+
|
420
|
+
reload_without_tag_list(*args)
|
421
|
+
end
|
422
|
+
|
442
423
|
end
|
443
424
|
end
|
444
425
|
end
|