Module: ActiveRecord::Acts::TaggableOn::InstanceMethods

Includes:
GroupHelper
Defined in:
lib/acts_as_taggable_on/acts_as_taggable_on.rb

Instance Method Summary collapse

Methods included from GroupHelper

#grouped_column_names_for

Instance Method Details

#add_custom_context(value) ⇒ Object



292
293
294
# File 'lib/acts_as_taggable_on/acts_as_taggable_on.rb', line 292

def add_custom_context(value)
  custom_contexts << value.to_s unless custom_contexts.include?(value.to_s) or self.class.tag_types.map(&:to_s).include?(value.to_s)
end

#all_tags_list_on(context) ⇒ Object



308
309
310
311
312
# File 'lib/acts_as_taggable_on/acts_as_taggable_on.rb', line 308

def all_tags_list_on(context)
  variable_name = "@all_#{context.to_s.singularize}_list"
  return instance_variable_get(variable_name) if instance_variable_get(variable_name)
  instance_variable_set(variable_name, TagList.new(all_tags_on(context).map(&:name)).freeze)
end

#all_tags_on(context) ⇒ Object



314
315
316
317
# File 'lib/acts_as_taggable_on/acts_as_taggable_on.rb', line 314

def all_tags_on(context)
  opts = {:conditions => ["#{Tagging.table_name}.context = ?", context.to_s]}
  base_tags.find(:all, opts.merge(:order => "#{Tagging.table_name}.created_at"))
end

#cached_tag_list_on(context) ⇒ Object



329
330
331
# File 'lib/acts_as_taggable_on/acts_as_taggable_on.rb', line 329

def cached_tag_list_on(context)
  self["cached_#{context.to_s.singularize}_list"]
end

#custom_contextsObject



284
285
286
# File 'lib/acts_as_taggable_on/acts_as_taggable_on.rb', line 284

def custom_contexts
  @custom_contexts ||= []
end

#is_taggable?Boolean

Returns:

  • (Boolean)


288
289
290
# File 'lib/acts_as_taggable_on/acts_as_taggable_on.rb', line 288

def is_taggable?
  self.class.is_taggable?
end

#matching_context_search_options(search_context, result_context, klass, options = {}) ⇒ Object



374
375
376
377
378
379
380
381
382
383
384
385
# File 'lib/acts_as_taggable_on/acts_as_taggable_on.rb', line 374

def matching_context_search_options(search_context, result_context, klass, options = {})
  tags_to_find = tags_on(search_context).collect { |t| t.name }

  exclude_self = "#{klass.table_name}.id != #{id} AND" if self.class == klass

  { :select     => "#{klass.table_name}.*, COUNT(#{Tag.table_name}.id) AS count",
    :from       => "#{klass.table_name}, #{Tag.table_name}, #{Tagging.table_name}",
    :conditions => ["#{exclude_self} #{klass.table_name}.id = #{Tagging.table_name}.taggable_id AND #{Tagging.table_name}.taggable_type = '#{klass.to_s}' AND #{Tagging.table_name}.tag_id = #{Tag.table_name}.id AND #{Tag.table_name}.name IN (?) AND #{Tagging.table_name}.context = ?", tags_to_find, result_context],
    :group      => grouped_column_names_for(klass),
    :order      => "count DESC"
  }.update(options)
end

#matching_contexts_for(search_context, result_context, klass, options = {}) ⇒ Object



368
369
370
371
372
# File 'lib/acts_as_taggable_on/acts_as_taggable_on.rb', line 368

def matching_contexts_for(search_context, result_context, klass, options = {})
  search_conditions = matching_context_search_options(search_context, result_context, klass, options)

  klass.find(:all, search_conditions)
end


355
356
357
358
359
360
361
362
363
364
365
366
# File 'lib/acts_as_taggable_on/acts_as_taggable_on.rb', line 355

def related_search_options(context, klass, options = {})
  tags_to_find = tags_on(context).collect { |t| t.name }

  exclude_self = "#{klass.table_name}.id != #{id} AND" if self.class == klass

  { :select     => "#{klass.table_name}.*, COUNT(#{Tag.table_name}.id) AS count",
    :from       => "#{klass.table_name}, #{Tag.table_name}, #{Tagging.table_name}",
    :conditions => ["#{exclude_self} #{klass.table_name}.id = #{Tagging.table_name}.taggable_id AND #{Tagging.table_name}.taggable_type = '#{klass.to_s}' AND #{Tagging.table_name}.tag_id = #{Tag.table_name}.id AND #{Tag.table_name}.name IN (?)", tags_to_find],
    :group      => grouped_column_names_for(klass),
    :order      => "count DESC"
  }.update(options)
end


349
350
351
352
353
# File 'lib/acts_as_taggable_on/acts_as_taggable_on.rb', line 349

def related_tags_for(context, klass, options = {})
  search_conditions = related_search_options(context, klass, options)

  klass.find(:all, search_conditions)
end

#save_cached_tag_listObject



387
388
389
390
391
392
393
# File 'lib/acts_as_taggable_on/acts_as_taggable_on.rb', line 387

def save_cached_tag_list
  self.class.tag_types.map(&:to_s).each do |tag_type|
    if self.class.send("caching_#{tag_type.singularize}_list?")
      send(:"cached_#{tag_type.singularize}_list=", tag_list_cache_on(tag_type.singularize).to_a.flatten.compact.join(', '))
    end
  end
end

#save_tagsObject



395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
# File 'lib/acts_as_taggable_on/acts_as_taggable_on.rb', line 395

def save_tags
  contexts = custom_contexts + self.class.tag_types.map(&:to_s)

  transaction do
    contexts.each do |context|
      cache = tag_list_cache_on(context)
      
      cache.each do |owner, list|
        new_tags = Tag.find_or_create_all_with_like_by_name(list.uniq)
        taggings = Tagging.find(:all, :conditions => { :taggable_id => self.id, :taggable_type => self.class.base_class.to_s })

        # Destroy old taggings:
        if owner
          old_tags = tags_on(context, owner) - new_tags
          old_taggings = Tagging.find(:all, :conditions => { :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 })

          Tagging.destroy_all :id => old_taggings.map(&:id)
        else
          old_tags = tags_on(context) - new_tags
          base_tags.delete(*old_tags)                
        end
 
        new_tags.reject! { |tag| taggings.any? { |tagging|
            tagging.tag_id      == tag.id &&
            tagging.tagger_id   == (owner ? owner.id : nil) &&
            tagging.tagger_type == (owner ? owner.class.to_s : nil) &&
            tagging.context     == context
          }
        }
        
        # create new taggings:
        new_tags.each do |tag|
          Tagging.create!(:tag_id => tag.id, :context => context, :tagger => owner, :taggable => self)
        end
      end
    end
  end          

  true
end

#set_tag_list_on(context, new_list, tagger = nil) ⇒ Object



340
341
342
343
# File 'lib/acts_as_taggable_on/acts_as_taggable_on.rb', line 340

def set_tag_list_on(context, new_list, tagger = nil)
  tag_list_cache_on(context)[tagger] = TagList.from(new_list)
  add_custom_context(context)
end

#tag_counts_on(context, options = {}) ⇒ Object



345
346
347
# File 'lib/acts_as_taggable_on/acts_as_taggable_on.rb', line 345

def tag_counts_on(context, options={})
  self.class.tag_counts_on(context, options.merge(:id => id))
end

#tag_list_cache_on(context) ⇒ Object



333
334
335
336
337
338
# File 'lib/acts_as_taggable_on/acts_as_taggable_on.rb', line 333

def tag_list_cache_on(context)
  variable_name = "@#{context.to_s.singularize}_list"
  cache = instance_variable_get(variable_name)
  instance_variable_set(variable_name, cache = {}) unless cache
  cache
end

#tag_list_on(context, owner = nil) ⇒ Object



296
297
298
299
300
301
302
303
304
305
306
# File 'lib/acts_as_taggable_on/acts_as_taggable_on.rb', line 296

def tag_list_on(context, owner = nil)
  add_custom_context(context)
  cache = tag_list_cache_on(context)
  return owner ? cache[owner] : cache[owner] if cache[owner]
  
  if !owner && self.class.caching_tag_list_on?(context) and !(cached_value = cached_tag_list_on(context)).nil?
    cache[owner] = TagList.from(cached_tag_list_on(context))
  else
    cache[owner] = TagList.new(*tags_on(context, owner).map(&:name))
  end
end

#tags_on(context, owner = nil) ⇒ Object



319
320
321
322
323
324
325
326
327
# File 'lib/acts_as_taggable_on/acts_as_taggable_on.rb', line 319

def tags_on(context, owner = nil)
  if owner
    opts = {:conditions => ["#{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]}
  else
    opts = {:conditions => ["#{Tagging.table_name}.context = ? AND #{Tagging.table_name}.tagger_id IS NULL", context.to_s]}
  end
  base_tags.find(:all, opts)
end