acts-as-taggable-on 1.0.13 → 1.1.1

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.
data/README.rdoc CHANGED
@@ -151,6 +151,12 @@ A helper is included to assist with generating tag clouds.
151
151
 
152
152
  Here is an example that generates a tag cloud.
153
153
 
154
+ Helper:
155
+
156
+ module PostsHelper
157
+ include TagsHelper
158
+ end
159
+
154
160
  Controller:
155
161
 
156
162
  class PostController < ApplicationController
@@ -160,7 +166,8 @@ Controller:
160
166
  end
161
167
 
162
168
  View:
163
- <% tag_cloud @tags, %w(css1 css2 css3 css4) do |tag, css_class| %>
169
+
170
+ <% tag_cloud(@tags, %w(css1 css2 css3 css4)) do |tag, css_class| %>
164
171
  <%= link_to tag.name, { :action => :tag, :id => tag.name }, :class => css_class %>
165
172
  <% end %>
166
173
 
@@ -187,5 +194,6 @@ CSS:
187
194
  * slainer68 - STI fix
188
195
  * harrylove - migration instructions and fix-ups
189
196
  * lawrencepit - cached tag work
197
+ * sobrinho - fixed tag_cloud helper
190
198
 
191
199
  Copyright (c) 2007-2009 Michael Bleigh (http://mbleigh.com/) and Intridea Inc. (http://intridea.com/), released under the MIT license
data/Rakefile CHANGED
@@ -9,7 +9,7 @@ begin
9
9
  gemspec.email = "michael@intridea.com"
10
10
  gemspec.homepage = "http://github.com/mbleigh/acts-as-taggable-on"
11
11
  gemspec.authors = ["Michael Bleigh"]
12
- gemspec.files = FileList["[A-Z]*", "{lib,spec,rails}/**/*"] - FileList["**/*.log"]
12
+ gemspec.files = FileList["[A-Z]*", "{generators,lib,spec,rails}/**/*"] - FileList["**/*.log"]
13
13
  end
14
14
  Jeweler::GemcutterTasks.new
15
15
  rescue LoadError
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.13
1
+ 1.1.1
@@ -0,0 +1,7 @@
1
+ class ActsAsTaggableOnMigrationGenerator < Rails::Generator::Base
2
+ def manifest
3
+ record do |m|
4
+ m.migration_template 'migration.rb', 'db/migrate', :migration_file_name => "acts_as_taggable_on_migration"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,29 @@
1
+ class ActsAsTaggableOnMigration < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :tags do |t|
4
+ t.column :name, :string
5
+ end
6
+
7
+ create_table :taggings do |t|
8
+ t.column :tag_id, :integer
9
+ t.column :taggable_id, :integer
10
+ t.column :tagger_id, :integer
11
+ t.column :tagger_type, :string
12
+
13
+ # You should make sure that the column created is
14
+ # long enough to store the required class names.
15
+ t.column :taggable_type, :string
16
+ t.column :context, :string
17
+
18
+ t.column :created_at, :datetime
19
+ end
20
+
21
+ add_index :taggings, :tag_id
22
+ add_index :taggings, [:taggable_id, :taggable_type, :context]
23
+ end
24
+
25
+ def self.down
26
+ drop_table :taggings
27
+ drop_table :tags
28
+ end
29
+ end
@@ -19,15 +19,15 @@ module ActiveRecord
19
19
  args.compact! if args
20
20
  for tag_type in args
21
21
  tag_type = tag_type.to_s
22
- # use aliased_join_table_name for context condition so that sphix can join multiple
22
+ # use aliased_join_table_name for context condition so that sphinx can join multiple
23
23
  # tag references from same model without getting an ambiguous column error
24
- self.class_eval do
24
+ class_eval do
25
25
  has_many "#{tag_type.singularize}_taggings".to_sym, :as => :taggable, :dependent => :destroy,
26
- :include => :tag, :conditions => ['#{aliased_join_table_name rescue "taggings"}.context = ?',tag_type], :class_name => "Tagging"
26
+ :include => :tag, :conditions => ['#{aliased_join_table_name || Tagging.table_name rescue Tagging.table_name}.context = ?',tag_type], :class_name => "Tagging"
27
27
  has_many "#{tag_type}".to_sym, :through => "#{tag_type.singularize}_taggings".to_sym, :source => :tag
28
28
  end
29
29
 
30
- self.class_eval <<-RUBY
30
+ class_eval <<-RUBY
31
31
  def self.taggable?
32
32
  true
33
33
  end
@@ -82,11 +82,10 @@ module ActiveRecord
82
82
  end
83
83
  RUBY
84
84
  end
85
-
86
85
  if respond_to?(:tag_types)
87
86
  write_inheritable_attribute( :tag_types, (tag_types + args).uniq )
88
87
  else
89
- self.class_eval do
88
+ class_eval do
90
89
  write_inheritable_attribute(:tag_types, args.uniq)
91
90
  class_inheritable_reader :tag_types
92
91
 
@@ -117,6 +116,7 @@ module ActiveRecord
117
116
  # Pass either a tag string, or an array of strings or tags
118
117
  #
119
118
  # Options:
119
+ # :any - find models that match any of the given tags
120
120
  # :exclude - Find models that are not tagged with the given tags
121
121
  # :match_all - Find models that match all of the given tags, not just one
122
122
  # :conditions - A piece of SQL conditions to add to the query
@@ -139,9 +139,9 @@ module ActiveRecord
139
139
  end
140
140
 
141
141
  def find_options_for_find_tagged_with(tags, options = {})
142
- tags = TagList.from(tags)
142
+ tag_list = TagList.from(tags)
143
143
 
144
- return {} if tags.empty?
144
+ return {} if tag_list.empty?
145
145
 
146
146
  joins = []
147
147
  conditions = []
@@ -150,28 +150,30 @@ module ActiveRecord
150
150
 
151
151
 
152
152
  if options.delete(:exclude)
153
- tags_conditions = tags.map { |t| sanitize_sql(["#{Tag.table_name}.name LIKE ?", t]) }.join(" OR ")
153
+ tags_conditions = tag_list.map { |t| sanitize_sql(["#{Tag.table_name}.name LIKE ?", t]) }.join(" OR ")
154
154
  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)})"
155
155
 
156
+ elsif options.delete(:any)
157
+ tags_conditions = tag_list.map { |t| sanitize_sql(["#{Tag.table_name}.name LIKE ?", t]) }.join(" OR ")
158
+ conditions << "#{table_name}.#{primary_key} 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)})"
159
+
156
160
  else
161
+ tags = Tag.named_like_any(tag_list)
162
+ return { :conditions => "1 = 0" } unless tags.length == tag_list.length
163
+
157
164
  tags.each do |tag|
158
- safe_tag = tag.gsub(/[^a-zA-Z0-9]/, '')
165
+ safe_tag = tag.name.gsub(/[^a-zA-Z0-9]/, '')
159
166
  prefix = "#{safe_tag}_#{rand(1024)}"
160
167
 
161
168
  taggings_alias = "#{table_name}_taggings_#{prefix}"
162
- tags_alias = "#{table_name}_tags_#{prefix}"
163
169
 
164
170
  tagging_join = "JOIN #{Tagging.table_name} #{taggings_alias}" +
165
171
  " ON #{taggings_alias}.taggable_id = #{table_name}.#{primary_key}" +
166
- " AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}"
172
+ " AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}" +
173
+ " AND #{taggings_alias}.tag_id = #{tag.id}"
167
174
  tagging_join << " AND " + sanitize_sql(["#{taggings_alias}.context = ?", context.to_s]) if context
168
175
 
169
- tag_join = "JOIN #{Tag.table_name} #{tags_alias}" +
170
- " ON #{tags_alias}.id = #{taggings_alias}.tag_id" +
171
- " AND " + sanitize_sql(["#{tags_alias}.name like ?", tag])
172
-
173
176
  joins << tagging_join
174
- joins << tag_join
175
177
  end
176
178
  end
177
179
 
@@ -187,7 +189,8 @@ module ActiveRecord
187
189
 
188
190
  { :joins => joins.join(" "),
189
191
  :group => group,
190
- :conditions => conditions.join(" AND ") }.update(options)
192
+ :conditions => conditions.join(" AND "),
193
+ :readonly => false }.update(options)
191
194
  end
192
195
 
193
196
  # Calculate the tag counts for all tags.
@@ -225,14 +228,32 @@ module ActiveRecord
225
228
 
226
229
  joins = ["LEFT OUTER JOIN #{Tagging.table_name} ON #{Tag.table_name}.id = #{Tagging.table_name}.tag_id"]
227
230
  joins << sanitize_sql(["AND #{Tagging.table_name}.context = ?",options.delete(:on).to_s]) unless options[:on].nil?
228
-
229
231
  joins << " INNER JOIN #{table_name} ON #{table_name}.#{primary_key} = #{Tagging.table_name}.taggable_id"
230
- unless self.descends_from_active_record?
232
+
233
+ unless descends_from_active_record?
231
234
  # Current model is STI descendant, so add type checking to the join condition
232
- joins << " AND #{table_name}.#{self.inheritance_column} = '#{self.name}'"
235
+ joins << " AND #{table_name}.#{inheritance_column} = '#{name}'"
233
236
  end
234
237
 
235
- joins << scope[:joins] if scope && scope[:joins]
238
+ # Based on a proposed patch by donV to ActiveRecord Base
239
+ # This is needed because merge_joins and construct_join are private in ActiveRecord Base
240
+ if scope && scope[:joins]
241
+ case scope[:joins]
242
+ when Array
243
+ scope_joins = scope[:joins].flatten
244
+ strings = scope_joins.select{|j| j.is_a? String}
245
+ joins << strings.join(' ') + " "
246
+ symbols = scope_joins - strings
247
+ join_dependency = ActiveRecord::Associations::ClassMethods::InnerJoinDependency.new(self, symbols, nil)
248
+ joins << " #{join_dependency.join_associations.collect { |assoc| assoc.association_join }.join} "
249
+ joins.flatten!
250
+ when Symbol, Hash
251
+ join_dependency = ActiveRecord::Associations::ClassMethods::InnerJoinDependency.new(self, scope[:joins], nil)
252
+ joins << " #{join_dependency.join_associations.collect { |assoc| assoc.association_join }.join} "
253
+ when String
254
+ joins << scope[:joins]
255
+ end
256
+ end
236
257
 
237
258
  at_least = sanitize_sql(['COUNT(*) >= ?', options.delete(:at_least)]) if options[:at_least]
238
259
  at_most = sanitize_sql(['COUNT(*) <= ?', options.delete(:at_most)]) if options[:at_most]
@@ -264,29 +285,40 @@ module ActiveRecord
264
285
  def is_taggable?
265
286
  self.class.is_taggable?
266
287
  end
267
-
288
+
268
289
  def add_custom_context(value)
269
290
  custom_contexts << value.to_s unless custom_contexts.include?(value.to_s) or self.class.tag_types.map(&:to_s).include?(value.to_s)
270
291
  end
271
292
 
272
- def tag_list_on(context, owner=nil)
273
- var_name = context.to_s.singularize + "_list"
293
+ def tag_list_on(context, owner = nil)
274
294
  add_custom_context(context)
275
- return instance_variable_get("@#{var_name}") unless instance_variable_get("@#{var_name}").nil?
276
-
295
+ cache = tag_list_cache_on(context)
296
+ return owner ? cache[owner] : cache[owner] if cache[owner]
297
+
277
298
  if !owner && self.class.caching_tag_list_on?(context) and !(cached_value = cached_tag_list_on(context)).nil?
278
- instance_variable_set("@#{var_name}", TagList.from(self["cached_#{var_name}"]))
299
+ cache[owner] = TagList.from(cached_tag_list_on(context))
279
300
  else
280
- instance_variable_set("@#{var_name}", TagList.new(*tags_on(context, owner).map(&:name)))
301
+ cache[owner] = TagList.new(*tags_on(context, owner).map(&:name))
281
302
  end
282
303
  end
304
+
305
+ def all_tags_list_on(context)
306
+ variable_name = "@all_#{context.to_s.singularize}_list"
307
+ return instance_variable_get(variable_name) if instance_variable_get(variable_name)
308
+ instance_variable_set(variable_name, TagList.new(all_tags_on(context).map(&:name)).freeze)
309
+ end
310
+
311
+ def all_tags_on(context)
312
+ opts = {:conditions => ["#{Tagging.table_name}.context = ?", context.to_s]}
313
+ base_tags.find(:all, opts.merge(:order => "#{Tagging.table_name}.created_at"))
314
+ end
283
315
 
284
- def tags_on(context, owner=nil)
316
+ def tags_on(context, owner = nil)
285
317
  if owner
286
318
  opts = {:conditions => ["#{Tagging.table_name}.context = ? AND #{Tagging.table_name}.tagger_id = ? AND #{Tagging.table_name}.tagger_type = ?",
287
319
  context.to_s, owner.id, owner.class.to_s]}
288
320
  else
289
- opts = {:conditions => ["#{Tagging.table_name}.context = ?", context.to_s]}
321
+ opts = {:conditions => ["#{Tagging.table_name}.context = ? AND #{Tagging.table_name}.tagger_id IS NULL", context.to_s]}
290
322
  end
291
323
  base_tags.find(:all, opts)
292
324
  end
@@ -294,14 +326,21 @@ module ActiveRecord
294
326
  def cached_tag_list_on(context)
295
327
  self["cached_#{context.to_s.singularize}_list"]
296
328
  end
329
+
330
+ def tag_list_cache_on(context)
331
+ variable_name = "@#{context.to_s.singularize}_list"
332
+ cache = instance_variable_get(variable_name)
333
+ instance_variable_set(variable_name, cache = {}) unless cache
334
+ cache
335
+ end
297
336
 
298
- def set_tag_list_on(context,new_list, tagger=nil)
299
- instance_variable_set("@#{context.to_s.singularize}_list", TagList.from_owner(tagger, new_list))
337
+ def set_tag_list_on(context, new_list, tagger = nil)
338
+ tag_list_cache_on(context)[tagger] = TagList.from(new_list)
300
339
  add_custom_context(context)
301
340
  end
302
341
 
303
342
  def tag_counts_on(context, options={})
304
- self.class.tag_counts_on(context, options.merge(:id => self.id))
343
+ self.class.tag_counts_on(context, options.merge(:id => id))
305
344
  end
306
345
 
307
346
  def related_tags_for(context, klass, options = {})
@@ -311,9 +350,9 @@ module ActiveRecord
311
350
  end
312
351
 
313
352
  def related_search_options(context, klass, options = {})
314
- tags_to_find = self.tags_on(context).collect { |t| t.name }
353
+ tags_to_find = tags_on(context).collect { |t| t.name }
315
354
 
316
- exclude_self = "#{klass.table_name}.id != #{self.id} AND" if self.class == klass
355
+ exclude_self = "#{klass.table_name}.id != #{id} AND" if self.class == klass
317
356
 
318
357
  { :select => "#{klass.table_name}.*, COUNT(#{Tag.table_name}.id) AS count",
319
358
  :from => "#{klass.table_name}, #{Tag.table_name}, #{Tagging.table_name}",
@@ -330,9 +369,9 @@ module ActiveRecord
330
369
  end
331
370
 
332
371
  def matching_context_search_options(search_context, result_context, klass, options = {})
333
- tags_to_find = self.tags_on(search_context).collect { |t| t.name }
372
+ tags_to_find = tags_on(search_context).collect { |t| t.name }
334
373
 
335
- exclude_self = "#{klass.table_name}.id != #{self.id} AND" if self.class == klass
374
+ exclude_self = "#{klass.table_name}.id != #{id} AND" if self.class == klass
336
375
 
337
376
  { :select => "#{klass.table_name}.*, COUNT(#{Tag.table_name}.id) AS count",
338
377
  :from => "#{klass.table_name}, #{Tag.table_name}, #{Tagging.table_name}",
@@ -345,34 +384,49 @@ module ActiveRecord
345
384
  def save_cached_tag_list
346
385
  self.class.tag_types.map(&:to_s).each do |tag_type|
347
386
  if self.class.send("caching_#{tag_type.singularize}_list?")
348
- self["cached_#{tag_type.singularize}_list"] = send("#{tag_type.singularize}_list").to_s
387
+ self["cached_#{tag_type.singularize}_list"] = tag_list_cache_on(tag_type.singularize).tags.join(', ')
349
388
  end
350
389
  end
351
390
  end
352
391
 
353
392
  def save_tags
354
- (custom_contexts + self.class.tag_types.map(&:to_s)).each do |tag_type|
355
- next unless instance_variable_get("@#{tag_type.singularize}_list")
356
- owner = instance_variable_get("@#{tag_type.singularize}_list").owner
357
- new_tag_names = instance_variable_get("@#{tag_type.singularize}_list") - tags_on(tag_type).map(&:name)
358
- old_tags = tags_on(tag_type, owner).reject { |tag| instance_variable_get("@#{tag_type.singularize}_list").include?(tag.name) }
359
-
360
- self.class.transaction do
361
- base_tags.delete(*old_tags) if old_tags.any?
362
- new_tag_names.each do |new_tag_name|
363
- new_tag = Tag.find_or_create_with_like_by_name(new_tag_name)
364
- Tagging.create(:tag_id => new_tag.id, :context => tag_type,
365
- :taggable => self, :tagger => owner)
393
+ contexts = custom_contexts + self.class.tag_types.map(&:to_s)
394
+
395
+ transaction do
396
+ contexts.each do |context|
397
+ cache = tag_list_cache_on(context)
398
+
399
+ cache.each do |owner, list|
400
+ new_tags = Tag.find_or_create_all_with_like_by_name(list.uniq)
401
+
402
+ # Destroy old taggings:
403
+ if owner
404
+ old_tags = tags_on(context, owner) - new_tags
405
+ old_taggings = taggings.find(:all, :conditions => { :tag_id => old_tags, :tagger_id => owner, :tagger_type => owner.class.to_s, :context => context })
406
+ old_taggings.each(&:destroy)
407
+ else
408
+ old_tags = tags_on(context) - new_tags
409
+ base_tags.delete(*old_tags)
410
+ end
411
+
412
+ new_tags.reject! { |tag| taggings.any? { |tagging| tagging.tag == tag &&
413
+ tagging.tagger == owner &&
414
+ tagging.context == context } }
415
+
416
+ # create new taggings:
417
+ new_tags.each do |tag|
418
+ taggings.create!(:tag_id => tag.id, :context => context, :tagger => owner)
419
+ end
366
420
  end
367
421
  end
368
- end
422
+ end
369
423
 
370
424
  true
371
425
  end
372
426
 
373
427
  def reload_with_tag_list(*args)
374
428
  self.class.tag_types.each do |tag_type|
375
- self.instance_variable_set("@#{tag_type.to_s.singularize}_list", nil)
429
+ instance_variable_set("@#{tag_type.to_s.singularize}_list", nil)
376
430
  end
377
431
 
378
432
  reload_without_tag_list(*args)
@@ -1,17 +1,41 @@
1
1
  class Tag < ActiveRecord::Base
2
+
3
+ attr_accessible :name
4
+
5
+ ### ASSOCIATIONS:
6
+
2
7
  has_many :taggings, :dependent => :destroy
3
8
 
9
+ ### VALIDATIONS:
10
+
4
11
  validates_presence_of :name
5
12
  validates_uniqueness_of :name
6
13
 
7
- named_scope :named, lambda { |name| { :conditions => ["name = ?", name] } }
14
+ ### NAMED SCOPES:
15
+
16
+ named_scope :named, lambda { |name| { :conditions => ["name LIKE ?", name] } }
17
+ named_scope :named_any, lambda { |list| { :conditions => list.map { |tag| sanitize_sql(["name LIKE ?", tag.to_s]) }.join(" OR ") } }
8
18
  named_scope :named_like, lambda { |name| { :conditions => ["name LIKE ?", "%#{name}%"] } }
19
+ named_scope :named_like_any, lambda { |list| { :conditions => list.map { |tag| sanitize_sql(["name LIKE ?", "%#{tag.to_s}%"]) }.join(" OR ") } }
20
+
21
+ ### CLASS METHODS:
9
22
 
10
- # LIKE is used for cross-database case-insensitivity
11
23
  def self.find_or_create_with_like_by_name(name)
12
- find(:first, :conditions => ["name LIKE ?", name]) || create(:name => name)
24
+ named_like(name).first || create(:name => name)
13
25
  end
14
26
 
27
+ def self.find_or_create_all_with_like_by_name(*list)
28
+ list = [list].flatten
29
+
30
+ existing_tags = Tag.named_any(list).all
31
+ new_tag_names = list.reject { |name| existing_tags.any? { |tag| tag.name.downcase == name.downcase } }
32
+ created_tags = new_tag_names.map { |name| Tag.create(:name => name) }
33
+
34
+ existing_tags + created_tags
35
+ end
36
+
37
+ ### INSTANCE METHODS:
38
+
15
39
  def ==(object)
16
40
  super || (object.is_a?(Tag) && name == object.name)
17
41
  end
@@ -41,9 +41,10 @@ class TagList < Array
41
41
  # tag_list = TagList.new("Round", "Square,Cube")
42
42
  # tag_list.to_s # 'Round, "Square,Cube"'
43
43
  def to_s
44
- clean!
44
+ tags = frozen? ? self.dup : self
45
+ tags.send(:clean!)
45
46
 
46
- map do |name|
47
+ tags.map do |name|
47
48
  name.include?(delimiter) ? "\"#{name}\"" : name
48
49
  end.join(delimiter.ends_with?(" ") ? delimiter : "#{delimiter} ")
49
50
  end
@@ -55,7 +56,7 @@ class TagList < Array
55
56
  map!(&:strip)
56
57
  uniq!
57
58
  end
58
-
59
+
59
60
  def extract_and_apply_options!(args)
60
61
  options = args.last.is_a?(Hash) ? args.pop : {}
61
62
  options.assert_valid_keys :parse
@@ -79,17 +80,11 @@ class TagList < Array
79
80
  string = string.to_s.dup
80
81
 
81
82
  # Parse the quoted tags
82
- string.gsub!(/"(.*?)"\s*#{delimiter}?\s*/) { tag_list << $1; "" }
83
- string.gsub!(/'(.*?)'\s*#{delimiter}?\s*/) { tag_list << $1; "" }
83
+ string.gsub!(/(\A|#{delimiter})\s*"(.*?)"\s*(#{delimiter}\s*|\z)/) { tag_list << $2; $3 }
84
+ string.gsub!(/(\A|#{delimiter})\s*'(.*?)'\s*(#{delimiter}\s*|\z)/) { tag_list << $2; $3 }
84
85
 
85
86
  tag_list.add(string.split(delimiter))
86
87
  end
87
88
  end
88
-
89
- def from_owner(owner, *tags)
90
- returning from(*tags) do |taglist|
91
- taglist.owner = owner
92
- end
93
- end
94
89
  end
95
90
  end
@@ -1,8 +1,14 @@
1
1
  class Tagging < ActiveRecord::Base #:nodoc:
2
+ attr_accessible :tag, :tag_id, :context,
3
+ :taggable, :taggable_type, :taggable_id,
4
+ :tagger, :tagger_type, :tagger_id
5
+
2
6
  belongs_to :tag
3
7
  belongs_to :taggable, :polymorphic => true
4
8
  belongs_to :tagger, :polymorphic => true
5
9
 
6
10
  validates_presence_of :context
7
11
  validates_presence_of :tag_id
12
+
13
+ validates_uniqueness_of :tag_id, :scope => [:taggable_type, :taggable_id, :context, :tagger_id, :tagger_type]
8
14
  end
@@ -1,6 +1,8 @@
1
1
  module TagsHelper
2
2
  # See the README for an example using tag_cloud.
3
3
  def tag_cloud(tags, classes)
4
+ return [] if tags.empty?
5
+
4
6
  max_count = tags.sort_by(&:count).last.count.to_f
5
7
 
6
8
  tags.each do |tag|
data/rails/init.rb CHANGED
@@ -2,6 +2,4 @@ require 'acts-as-taggable-on'
2
2
 
3
3
  ActiveRecord::Base.send :include, ActiveRecord::Acts::TaggableOn
4
4
  ActiveRecord::Base.send :include, ActiveRecord::Acts::Tagger
5
- ActionView::Base.send :include, TagsHelper if defined?(ActionView::Base)
6
-
7
- RAILS_DEFAULT_LOGGER.info "** acts_as_taggable_on: initialized properly."
5
+ ActionView::Base.send :include, TagsHelper if defined?(ActionView::Base)
@@ -176,16 +176,6 @@ describe "Acts As Taggable On" do
176
176
  end
177
177
 
178
178
  describe 'Tagging Contexts' do
179
- before(:all) do
180
- class Array
181
- def freq
182
- k=Hash.new(0)
183
- self.each {|e| k[e]+=1}
184
- k
185
- end
186
- end
187
- end
188
-
189
179
  it 'should eliminate duplicate tagging contexts ' do
190
180
  TaggableModel.acts_as_taggable_on(:skills, :skills)
191
181
  TaggableModel.tag_types.freq[:skills].should_not == 3
@@ -212,10 +202,6 @@ describe "Acts As Taggable On" do
212
202
  TaggableModel.acts_as_taggable_on([nil])
213
203
  }.should_not raise_error
214
204
  end
215
-
216
- after(:all) do
217
- class Array; remove_method :freq; end
218
- end
219
205
  end
220
206
 
221
207
  end
@@ -1,8 +1,11 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
2
 
3
3
  describe "acts_as_tagger" do
4
+ before(:each) do
5
+ [TaggableUser, TaggableModel, Tagging, Tag].each(&:destroy_all)
6
+ end
7
+
4
8
  context "Tagger Method Generation" do
5
-
6
9
  before(:each) do
7
10
  @tagger = TaggableUser.new()
8
11
  end
@@ -48,8 +51,22 @@ describe "acts_as_tagger" do
48
51
 
49
52
  it 'should by default create the tag context on-the-fly' do
50
53
  @taggable.tag_list_on(:here_ond_now).should be_empty
51
- @tagger.tag(@taggable, :with=>'that', :on=>:here_ond_now)
52
- @taggable.tag_list_on(:here_ond_now).should include('that')
54
+ @tagger.tag(@taggable, :with=>'that', :on => :here_ond_now)
55
+ @taggable.tag_list_on(:here_ond_now).should_not include('that')
56
+ @taggable.all_tags_list_on(:here_ond_now).should include('that')
57
+ end
58
+
59
+ it "should show all the tag list when both public and owned tags exist" do
60
+ @taggable.tag_list = 'ruby, python'
61
+ @tagger.tag(@taggable, :with => 'java, lisp', :on => :tags)
62
+ @taggable.all_tags_on(:tags).map(&:name).sort.should == %w(ruby python java lisp).sort
63
+ end
64
+
65
+ it "should not add owned tags to the common list" do
66
+ @taggable.tag_list = 'ruby, python'
67
+ @tagger.tag(@taggable, :with => 'java, lisp', :on => :foo)
68
+ @tagger.tag(@taggable, :with => '', :on => :foo)
69
+ @taggable.tag_list.should == %w(ruby python)
53
70
  end
54
71
 
55
72
  it "should throw an exception when the default is over-ridden" do
@@ -64,9 +81,28 @@ describe "acts_as_tagger" do
64
81
  @tagger.tag(@taggable, :with=>'this, and, that', :on=>:foo_boo, :force=>false) rescue
65
82
  @taggable.tag_list_on(:foo_boo).should be_empty
66
83
  end
67
-
68
84
  end
69
-
85
+
86
+ context "when called by multiple tagger's" do
87
+ before(:each) do
88
+ @user_x = TaggableUser.new
89
+ @user_y = TaggableUser.new
90
+ @taggable = TaggableModel.new(:name => 'acts_as_taggable_on', :tag_list => 'plugin')
91
+
92
+ @user_x.tag(@taggable, :with => 'ruby, rails', :on => :tags)
93
+ @user_y.tag(@taggable, :with => 'ruby, plugin', :on => :tags)
94
+ end
95
+
96
+ it "should not delete other taggers tags" do
97
+ @user_y.tag(@taggable, :with => '', :on => :tags)
98
+ @taggable.all_tags_list_on(:tags).should include('ruby')
99
+ end
100
+
101
+ it "should not delete original tags" do
102
+ @user_y.tag(@taggable, :with => '', :on => :tags)
103
+ @taggable.all_tags_list_on(:tags).should include('plugin')
104
+ end
105
+ end
70
106
  end
71
107
 
72
108
  end
@@ -20,6 +20,18 @@ describe TagList do
20
20
  @tag_list.include?("wicked").should be_true
21
21
  end
22
22
 
23
+ it "should be able to add delimited list of words with quoted delimiters" do
24
+ @tag_list.add("'cool, wicked', \"really cool, really wicked\"", :parse => true)
25
+ @tag_list.include?("cool, wicked").should be_true
26
+ @tag_list.include?("really cool, really wicked").should be_true
27
+ end
28
+
29
+ it "should be able to handle other uses of quotation marks correctly" do
30
+ @tag_list.add("john's cool car, mary's wicked toy", :parse => true)
31
+ @tag_list.include?("john's cool car").should be_true
32
+ @tag_list.include?("mary's wicked toy").should be_true
33
+ end
34
+
23
35
  it "should be able to add an array of words" do
24
36
  @tag_list.add(["cool", "wicked"], :parse => true)
25
37
  @tag_list.include?("cool").should be_true
@@ -49,4 +61,10 @@ describe TagList do
49
61
  @tag_list.add("cool","rad,bodacious")
50
62
  @tag_list.to_s.should == "awesome, radical, cool, \"rad,bodacious\""
51
63
  end
64
+
65
+ it "should be able to call to_s on a frozen tag list" do
66
+ @tag_list.freeze
67
+ lambda { @tag_list.add("cool","rad,bodacious") }.should raise_error
68
+ lambda { @tag_list.to_s }.should_not raise_error
69
+ end
52
70
  end
@@ -7,6 +7,17 @@ describe Tag do
7
7
  Tag.delete_all
8
8
  end
9
9
 
10
+ describe "named like any" do
11
+ before(:each) do
12
+ Tag.create(:name => "awesome")
13
+ Tag.create(:name => "epic")
14
+ end
15
+
16
+ it "should find both tags" do
17
+ Tag.named_like_any(["awesome", "epic"]).should have(2).items
18
+ end
19
+ end
20
+
10
21
  describe "find or create by name" do
11
22
  before(:each) do
12
23
  @tag.name = "awesome"
@@ -27,6 +38,33 @@ describe Tag do
27
38
  }.should change(Tag, :count).by(1)
28
39
  end
29
40
  end
41
+
42
+ describe "find or create all by any name" do
43
+ before(:each) do
44
+ @tag.name = "awesome"
45
+ @tag.save
46
+ end
47
+
48
+ it "should find by name" do
49
+ Tag.find_or_create_all_with_like_by_name("awesome").should == [@tag]
50
+ end
51
+
52
+ it "should find by name case insensitive" do
53
+ Tag.find_or_create_all_with_like_by_name("AWESOME").should == [@tag]
54
+ end
55
+
56
+ it "should create by name" do
57
+ lambda {
58
+ Tag.find_or_create_all_with_like_by_name("epic")
59
+ }.should change(Tag, :count).by(1)
60
+ end
61
+
62
+ it "should find or create by name" do
63
+ lambda {
64
+ Tag.find_or_create_all_with_like_by_name("awesome", "epic").map(&:name).should == ["awesome", "epic"]
65
+ }.should change(Tag, :count).by(1)
66
+ end
67
+ end
30
68
 
31
69
  it "should require a name" do
32
70
  @tag.valid?
@@ -7,44 +7,49 @@ describe "Taggable" do
7
7
  end
8
8
 
9
9
  it "should have tag types" do
10
- TaggableModel.tag_types.should == [:tags, :languages, :skills, :needs, :offerings]
11
- @taggable.tag_types.should == TaggableModel.tag_types
10
+ for type in [:tags, :languages, :skills, :needs, :offerings]
11
+ TaggableModel.tag_types.should include type
12
+ end
13
+ @taggable.tag_types.should == TaggableModel.tag_types
12
14
  end
13
15
 
14
16
  it "should have tag_counts_on" do
15
17
  TaggableModel.tag_counts_on(:tags).should be_empty
16
-
18
+
17
19
  @taggable.tag_list = ["awesome", "epic"]
18
20
  @taggable.save
19
21
 
20
22
  TaggableModel.tag_counts_on(:tags).count.should == 2
21
23
  @taggable.tag_counts_on(:tags).count.should == 2
22
24
  end
23
-
25
+
24
26
  it "should be able to create tags" do
25
27
  @taggable.skill_list = "ruby, rails, css"
26
- @taggable.instance_variable_get("@skill_list").instance_of?(TagList).should be_true
28
+ @taggable.instance_variable_get("@skill_list").instance_of?(Hash).should be_true
29
+ @taggable.instance_variable_get("@skill_list")[nil].instance_of?(TagList).should be_true
27
30
  @taggable.save
28
-
31
+
29
32
  Tag.find(:all).size.should == 3
30
33
  end
31
-
34
+
32
35
  it "should be able to create tags through the tag list directly" do
33
36
  @taggable.tag_list_on(:test).add("hello")
34
- @taggable.save
37
+ @taggable.tag_list_cache_on(:test).should_not be_empty
38
+ @taggable.save
39
+ @taggable.save_tags
35
40
  @taggable.reload
36
41
  @taggable.tag_list_on(:test).should == ["hello"]
37
42
  end
38
-
43
+
39
44
  it "should differentiate between contexts" do
40
45
  @taggable.skill_list = "ruby, rails, css"
41
46
  @taggable.tag_list = "ruby, bob, charlie"
42
47
  @taggable.save
43
48
  @taggable.reload
44
- @taggable.skill_list.include?("ruby").should be_true
45
- @taggable.skill_list.include?("bob").should be_false
49
+ @taggable.skill_list.should include("ruby")
50
+ @taggable.skill_list.should_not include("bob")
46
51
  end
47
-
52
+
48
53
  it "should be able to remove tags through list alone" do
49
54
  @taggable.skill_list = "ruby, rails, css"
50
55
  @taggable.save
@@ -55,13 +60,13 @@ describe "Taggable" do
55
60
  @taggable.reload
56
61
  @taggable.should have(2).skills
57
62
  end
58
-
63
+
59
64
  it "should be able to find by tag" do
60
65
  @taggable.skill_list = "ruby, rails, css"
61
66
  @taggable.save
62
67
  TaggableModel.find_tagged_with("ruby").first.should == @taggable
63
68
  end
64
-
69
+
65
70
  it "should be able to find by tag with context" do
66
71
  @taggable.skill_list = "ruby, rails, css"
67
72
  @taggable.tag_list = "bob, charlie"
@@ -70,25 +75,27 @@ describe "Taggable" do
70
75
  TaggableModel.find_tagged_with("bob", :on => :skills).first.should_not == @taggable
71
76
  TaggableModel.find_tagged_with("bob", :on => :tags).first.should == @taggable
72
77
  end
73
-
78
+
74
79
  it "should be able to use the tagged_with named scope" do
75
80
  @taggable.skill_list = "ruby, rails, css"
76
81
  @taggable.tag_list = "bob, charlie"
77
82
  @taggable.save
78
-
83
+
79
84
  TaggableModel.tagged_with("ruby").first.should == @taggable
85
+ TaggableModel.tagged_with("ruby, css").first.should == @taggable
86
+ TaggableModel.tagged_with("ruby, nonexistingtag").should be_empty
80
87
  TaggableModel.tagged_with("bob", :on => :skills).first.should_not == @taggable
81
88
  TaggableModel.tagged_with("bob", :on => :tags).first.should == @taggable
82
89
  end
83
-
90
+
84
91
  it "should not care about case" do
85
92
  bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby")
86
93
  frank = TaggableModel.create(:name => "Frank", :tag_list => "Ruby")
87
-
94
+
88
95
  Tag.find(:all).size.should == 1
89
96
  TaggableModel.find_tagged_with("ruby").should == TaggableModel.find_tagged_with("Ruby")
90
97
  end
91
-
98
+
92
99
  it "should be able to get tag counts on model as a whole" do
93
100
  bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css")
94
101
  frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails")
@@ -96,33 +103,39 @@ describe "Taggable" do
96
103
  TaggableModel.tag_counts.should_not be_empty
97
104
  TaggableModel.skill_counts.should_not be_empty
98
105
  end
99
-
106
+
100
107
  it "should be able to get all tag counts on model as whole" do
101
108
  bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css")
102
109
  frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails")
103
110
  charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby")
104
-
111
+
105
112
  TaggableModel.all_tag_counts.should_not be_empty
106
113
  TaggableModel.all_tag_counts.first.count.should == 3 # ruby
107
114
  end
108
-
115
+
116
+ it "should not return read-only records" do
117
+ TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css")
118
+
119
+ TaggableModel.tagged_with("ruby").first.should_not be_readonly
120
+ end
121
+
109
122
  it "should be able to get scoped tag counts" do
110
123
  bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css")
111
124
  frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails")
112
125
  charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby")
113
-
126
+
114
127
  TaggableModel.tagged_with("ruby").tag_counts.first.count.should == 2 # ruby
115
128
  TaggableModel.tagged_with("ruby").skill_counts.first.count.should == 1 # ruby
116
129
  end
117
-
130
+
118
131
  it "should be able to get all scoped tag counts" do
119
132
  bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css")
120
133
  frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails")
121
134
  charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby")
122
-
135
+
123
136
  TaggableModel.tagged_with("ruby").all_tag_counts.first.count.should == 3 # ruby
124
137
  end
125
-
138
+
126
139
  it "should be able to set a custom tag context list" do
127
140
  bob = TaggableModel.create(:name => "Bob")
128
141
  bob.set_tag_list_on(:rotors, "spinning, jumping")
@@ -131,17 +144,27 @@ describe "Taggable" do
131
144
  bob.reload
132
145
  bob.tags_on(:rotors).should_not be_empty
133
146
  end
134
-
147
+
135
148
  it "should be able to find tagged" do
136
149
  bob = TaggableModel.create(:name => "Bob", :tag_list => "fitter, happier, more productive", :skill_list => "ruby, rails, css")
137
150
  frank = TaggableModel.create(:name => "Frank", :tag_list => "weaker, depressed, inefficient", :skill_list => "ruby, rails, css")
138
151
  steve = TaggableModel.create(:name => 'Steve', :tag_list => 'fitter, happier, more productive', :skill_list => 'c++, java, ruby')
139
-
152
+
140
153
  TaggableModel.find_tagged_with("ruby", :order => 'taggable_models.name').should == [bob, frank, steve]
141
154
  TaggableModel.find_tagged_with("ruby, rails", :order => 'taggable_models.name').should == [bob, frank]
142
155
  TaggableModel.find_tagged_with(["ruby", "rails"], :order => 'taggable_models.name').should == [bob, frank]
143
156
  end
144
-
157
+
158
+ it "should be able to find tagged with any tag" do
159
+ bob = TaggableModel.create(:name => "Bob", :tag_list => "fitter, happier, more productive", :skill_list => "ruby, rails, css")
160
+ frank = TaggableModel.create(:name => "Frank", :tag_list => "weaker, depressed, inefficient", :skill_list => "ruby, rails, css")
161
+ steve = TaggableModel.create(:name => 'Steve', :tag_list => 'fitter, happier, more productive', :skill_list => 'c++, java, ruby')
162
+
163
+ TaggableModel.find_tagged_with(["ruby", "java"], :order => 'taggable_models.name', :any => true).should == [bob, frank, steve]
164
+ TaggableModel.find_tagged_with(["c++", "fitter"], :order => 'taggable_models.name', :any => true).should == [bob, steve]
165
+ TaggableModel.find_tagged_with(["depressed", "css"], :order => 'taggable_models.name', :any => true).should == [bob, frank]
166
+ end
167
+
145
168
  it "should be able to find tagged on a custom tag context" do
146
169
  bob = TaggableModel.create(:name => "Bob")
147
170
  bob.set_tag_list_on(:rotors, "spinning, jumping")
@@ -154,29 +177,38 @@ describe "Taggable" do
154
177
  bob = TaggableModel.create(:name => "Bob", :tag_list => "fitter, happier, more productive", :skill_list => "ruby, rails, css")
155
178
  frank = TaggableModel.create(:name => "Frank", :tag_list => "weaker, depressed, inefficient", :skill_list => "ruby, rails, css")
156
179
  steve = TaggableModel.create(:name => 'Steve', :tag_list => 'fitter, happier, more productive', :skill_list => 'c++, java, python')
157
-
180
+
158
181
  # Let's only find those productive Rails developers
159
182
  TaggableModel.tagged_with('rails', :on => :skills, :order => 'taggable_models.name').should == [bob, frank]
160
183
  TaggableModel.tagged_with('happier', :on => :tags, :order => 'taggable_models.name').should == [bob, steve]
161
184
  TaggableModel.tagged_with('rails', :on => :skills).tagged_with('happier', :on => :tags).should == [bob]
162
185
  TaggableModel.tagged_with('rails').tagged_with('happier', :on => :tags).should == [bob]
163
186
  end
164
-
187
+
165
188
  it "should be able to find tagged with only the matching tags" do
166
189
  bob = TaggableModel.create(:name => "Bob", :tag_list => "lazy, happier")
167
190
  frank = TaggableModel.create(:name => "Frank", :tag_list => "fitter, happier, inefficient")
168
191
  steve = TaggableModel.create(:name => 'Steve', :tag_list => "fitter, happier")
169
-
192
+
170
193
  TaggableModel.find_tagged_with("fitter, happier", :match_all => true).should == [steve]
171
194
  end
172
-
195
+
173
196
  it "should be able to find tagged with some excluded tags" do
174
197
  bob = TaggableModel.create(:name => "Bob", :tag_list => "happier, lazy")
175
198
  frank = TaggableModel.create(:name => "Frank", :tag_list => "happier")
176
199
  steve = TaggableModel.create(:name => 'Steve', :tag_list => "happier")
177
-
200
+
178
201
  TaggableModel.find_tagged_with("lazy", :exclude => true).should == [frank, steve]
179
202
  end
203
+
204
+ it "should not create duplicate taggings" do
205
+ bob = TaggableModel.create(:name => "Bob")
206
+ lambda {
207
+ bob.tag_list << "happier"
208
+ bob.tag_list << "happier"
209
+ bob.save
210
+ }.should change(Tagging, :count).by(1)
211
+ end
180
212
 
181
213
  describe "Single Table Inheritance" do
182
214
  before do
@@ -185,32 +217,32 @@ describe "Taggable" do
185
217
  @inherited_same = InheritingTaggableModel.new(:name => "inherited same")
186
218
  @inherited_different = AlteredInheritingTaggableModel.new(:name => "inherited different")
187
219
  end
188
-
220
+
189
221
  it "should be able to save tags for inherited models" do
190
222
  @inherited_same.tag_list = "bob, kelso"
191
223
  @inherited_same.save
192
224
  InheritingTaggableModel.find_tagged_with("bob").first.should == @inherited_same
193
225
  end
194
-
226
+
195
227
  it "should find STI tagged models on the superclass" do
196
228
  @inherited_same.tag_list = "bob, kelso"
197
229
  @inherited_same.save
198
230
  TaggableModel.find_tagged_with("bob").first.should == @inherited_same
199
231
  end
200
-
232
+
201
233
  it "should be able to add on contexts only to some subclasses" do
202
234
  @inherited_different.part_list = "fork, spoon"
203
235
  @inherited_different.save
204
236
  InheritingTaggableModel.find_tagged_with("fork", :on => :parts).should be_empty
205
237
  AlteredInheritingTaggableModel.find_tagged_with("fork", :on => :parts).first.should == @inherited_different
206
238
  end
207
-
239
+
208
240
  it "should have different tag_counts_on for inherited models" do
209
241
  @inherited_same.tag_list = "bob, kelso"
210
242
  @inherited_same.save!
211
243
  @inherited_different.tag_list = "fork, spoon"
212
244
  @inherited_different.save!
213
-
245
+
214
246
  InheritingTaggableModel.tag_counts_on(:tags).map(&:name).should == %w(bob kelso)
215
247
  AlteredInheritingTaggableModel.tag_counts_on(:tags).map(&:name).should == %w(fork spoon)
216
248
  TaggableModel.tag_counts_on(:tags).map(&:name).should == %w(bob kelso fork spoon)
@@ -6,17 +6,32 @@ describe "Tagger" do
6
6
  @user = TaggableUser.new
7
7
  @taggable = TaggableModel.new(:name => "Bob Jones")
8
8
  end
9
-
9
+
10
10
  it "should have taggings" do
11
11
  @user.tag(@taggable, :with=>'ruby,scheme', :on=>:tags)
12
12
  @user.owned_taggings.size == 2
13
13
  end
14
-
14
+
15
15
  it "should have tags" do
16
16
  @user.tag(@taggable, :with=>'ruby,scheme', :on=>:tags)
17
17
  @user.owned_tags.size == 2
18
18
  end
19
19
 
20
+ it "should not overlap or lose tags from different users" do
21
+ @user2 = TaggableUser.new
22
+ lambda{
23
+ @user.tag(@taggable, :with => 'ruby, scheme', :on => :tags)
24
+ @user2.tag(@taggable, :with => 'java, python, lisp, ruby', :on => :tags)
25
+ }.should change(Tagging, :count).by(6)
26
+
27
+ @user.owned_tags.map(&:name).sort.should == %w(ruby scheme)
28
+ @user2.owned_tags.map(&:name).sort.should == %w(java python lisp ruby).sort
29
+ @taggable.tags_from(@user).sort.should == %w(ruby scheme)
30
+ @taggable.tags_from(@user2).sort.should == %w(java lisp python ruby)
31
+ @taggable.all_tags_list_on(:tags).sort.should == %w(ruby scheme java python lisp).sort
32
+ @taggable.all_tags_on(:tags).size.should == 6
33
+ end
34
+
20
35
  it "is tagger" do
21
36
  @user.is_tagger?.should(be_true)
22
37
  end
@@ -13,4 +13,13 @@ describe Tagging do
13
13
  @tagging.should_not be_valid
14
14
  @tagging.errors.on(:tag_id).should == "can't be blank"
15
15
  end
16
+
17
+ it "should not create duplicate taggings" do
18
+ @taggable = TaggableModel.create(:name => "Bob Jones")
19
+ @tag = Tag.create(:name => "awesome")
20
+
21
+ lambda {
22
+ 2.times { Tagging.create(:taggable => @taggable, :tag => @tag, :context => 'tags') }
23
+ }.should change(Tagging, :count).by(1)
24
+ end
16
25
  end
data/spec/spec_helper.rb CHANGED
@@ -1,12 +1,20 @@
1
1
  # require File.dirname(__FILE__) + '/../../../../spec/spec_helper'
2
2
  require 'rubygems'
3
- require 'activerecord'
3
+ require 'active_record'
4
4
  require 'spec'
5
5
 
6
6
  module Spec::Example::ExampleGroupMethods
7
7
  alias :context :describe
8
8
  end
9
9
 
10
+ class Array
11
+ def freq
12
+ k=Hash.new(0)
13
+ each {|e| k[e]+=1}
14
+ k
15
+ end
16
+ end
17
+
10
18
  TEST_DATABASE_FILE = File.join(File.dirname(__FILE__), '..', 'test.sqlite3')
11
19
 
12
20
  File.unlink(TEST_DATABASE_FILE) if File.exist?(TEST_DATABASE_FILE)
@@ -16,7 +24,10 @@ ActiveRecord::Base.establish_connection(
16
24
 
17
25
  RAILS_DEFAULT_LOGGER = Logger.new(File.join(File.dirname(__FILE__), "debug.log"))
18
26
 
19
- load(File.dirname(__FILE__) + '/schema.rb')
27
+ ActiveRecord::Base.silence do
28
+ ActiveRecord::Migration.verbose = false
29
+ load(File.dirname(__FILE__) + '/schema.rb')
30
+ end
20
31
 
21
32
  $: << File.join(File.dirname(__FILE__), '..', 'lib')
22
33
  require File.join(File.dirname(__FILE__), '..', 'init')
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: 1.0.13
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Bleigh
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-11 00:00:00 +01:00
12
+ date: 2010-02-06 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -27,6 +27,8 @@ files:
27
27
  - README.rdoc
28
28
  - Rakefile
29
29
  - VERSION
30
+ - generators/acts_as_taggable_on_migration/acts_as_taggable_on_migration_generator.rb
31
+ - generators/acts_as_taggable_on_migration/templates/migration.rb
30
32
  - lib/acts-as-taggable-on.rb
31
33
  - lib/acts_as_taggable_on/acts_as_taggable_on.rb
32
34
  - lib/acts_as_taggable_on/acts_as_tagger.rb