Module: ActiveRecord::Acts::Taxonomy::InstanceMethods

Includes:
GroupHelper
Defined in:
lib/taxonomy/has_taxonomy.rb

Instance Method Summary collapse

Methods included from GroupHelper

#grouped_column_names_for

Instance Method Details

#add_custom_context(value) ⇒ Object



335
336
337
# File 'lib/taxonomy/has_taxonomy.rb', line 335

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

#all_tags_list_on(context) ⇒ Object



352
353
354
355
356
357
# File 'lib/taxonomy/has_taxonomy.rb', line 352

def all_tags_list_on(context)
  context = context.to_s.singularize
  variable_name = "@all_#{context}_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



359
360
361
362
363
# File 'lib/taxonomy/has_taxonomy.rb', line 359

def all_tags_on(context)
  context = context.to_s.singularize
  opts = {:conditions => ["#{Tag.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



375
376
377
# File 'lib/taxonomy/has_taxonomy.rb', line 375

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

#custom_contextsObject



327
328
329
# File 'lib/taxonomy/has_taxonomy.rb', line 327

def custom_contexts
  @custom_contexts ||= []
end

#is_taggable?Boolean

Returns:

  • (Boolean)


331
332
333
# File 'lib/taxonomy/has_taxonomy.rb', line 331

def is_taggable?
  self.class.is_taggable?
end

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



421
422
423
424
425
426
427
428
429
430
431
432
433
434
# File 'lib/taxonomy/has_taxonomy.rb', line 421

def matching_context_search_options(search_context, result_context, klass, options = {})
  search_context = search_context.to_s.singularize
  result_context = result_context.to_s.singularize
  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 #{Tag.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



415
416
417
418
419
# File 'lib/taxonomy/has_taxonomy.rb', line 415

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


402
403
404
405
406
407
408
409
410
411
412
413
# File 'lib/taxonomy/has_taxonomy.rb', line 402

def related_search_options(context, klass, options = {})
  tags_to_find = tags_on(context.to_s.singularize).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


396
397
398
399
400
# File 'lib/taxonomy/has_taxonomy.rb', line 396

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

  klass.find(:all, search_conditions)
end

#reload_with_tag_list(*args) ⇒ Object



492
493
494
495
496
497
498
# File 'lib/taxonomy/has_taxonomy.rb', line 492

def reload_with_tag_list(*args)
  self.class.tag_types.each do |tag_type|
    instance_variable_set("@#{tag_type.to_s.singularize}_list", nil)
  end

  reload_without_tag_list(*args)
end

#save_cached_tag_listObject



436
437
438
439
440
441
442
# File 'lib/taxonomy/has_taxonomy.rb', line 436

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?")              
      self["cached_#{tag_type.singularize}_list"] = tag_list_cache_on(tag_type.singularize).to_a.flatten.compact.join(', ')
    end
  end
end

#save_tagsObject



444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
# File 'lib/taxonomy/has_taxonomy.rb', line 444

def save_tags
  contexts = custom_contexts + self.class.tag_types.map(&:to_s)
  transaction do
    contexts.each do |context|
      context = context.to_s.singularize
      
      cache = tag_list_cache_on(context)
      
      cache.each do |owner, list|
        new_tags = Tag.find_or_create_all_with_like_by_name(context, list.uniq)
        taggings = Tagging.joins(:tag).where(:taggable_id => self.id, :taggable_type => self.class.base_class.to_s, "tags.context" => context ).all

        # Destroy old taggings:
        if owner
          old_tags = tags_on(context, owner) - new_tags
          
          old_taggings = Tagging.joins(:tag).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, 
                                                   "tags.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.tag.context == context
          }
        }
        
        # create new taggings:
        new_tags.each do |tag|
          Tagging.create!(:tag_id => tag.id, :tagger => owner, :taggable => self)
        end
      end
    end
  end          

  true
end

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



386
387
388
389
390
# File 'lib/taxonomy/has_taxonomy.rb', line 386

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

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



392
393
394
# File 'lib/taxonomy/has_taxonomy.rb', line 392

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

#tag_list_cache_on(context) ⇒ Object



379
380
381
382
383
384
# File 'lib/taxonomy/has_taxonomy.rb', line 379

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



339
340
341
342
343
344
345
346
347
348
349
350
# File 'lib/taxonomy/has_taxonomy.rb', line 339

def tag_list_on(context, owner = nil)
  context = context.to_s.singularize
  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



365
366
367
368
369
370
371
372
373
# File 'lib/taxonomy/has_taxonomy.rb', line 365

def tags_on(context, owner = nil)
  context = context.to_s.singularize
  if owner
    base_tags.where("#{Tag.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
    base_tags.where("#{Tag.table_name}.context = ? AND #{Tagging.table_name}.tagger_id IS NULL", context.to_s)
  end
end