Module: LeanTag::Taggable

Defined in:
lib/lean_tag/taggable.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



4
5
6
7
8
9
10
11
# File 'lib/lean_tag/taggable.rb', line 4

def self.included(base)
  base.class_eval do
    has_many :taggings, class_name: "LeanTag::Tagging", as: :record, inverse_of: :record, dependent: :destroy
    has_many :tags, through: :taggings

    scope :with_tags, -> { includes(:tags) }
  end
end

Instance Method Details

#add_tag(tag) ⇒ Object

Adds a single tag on parent save



15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/lean_tag/taggable.rb', line 15

def add_tag(tag)
  if tag.is_a?(String)
    tag_name = tag
    tag = Tag.find_by_name(tag_name)

    if tag.nil?
      self.tags.build(name: tag_name)
    elsif !self.taggings.exists?(tag_id: tag.id)
      self.taggings.build(tag_id: tag.id)
    end
  else
    self.taggings.build(tag_id: tag.id)
  end
end

#add_tag!(tag) ⇒ Object

Adds a single tag immediately



32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/lean_tag/taggable.rb', line 32

def add_tag!(tag)
   if tag.is_a?(String)
    tag_name = tag
    tag = Tag.find_by_name(tag_name)

    if tag.nil?
      self.tags.create(name: tag_name)
    elsif !self.taggings.exists?(tag_id: tag.id)
      self.taggings.create(tag_id: tag.id)
    end
  else
    self.taggings.create(tag_id: tag.id)
  end
end

#destroy_if_unused(tag) ⇒ Object

Destroy a tag if it’s no longer in use



49
50
51
52
53
# File 'lib/lean_tag/taggable.rb', line 49

def destroy_if_unused(tag)
  if tag.taggings_count && LeanTag.config.remove_unused
    tag.destroy
  end
end

#excluded_tags(tag_names) ⇒ Object

Finds current tags on this record which aren’t in the passed list



57
58
59
# File 'lib/lean_tag/taggable.rb', line 57

def excluded_tags(tag_names)
  self.tags.reject { |t| t.name.in?(tag_names) }
end

#find_tag(tag_name) ⇒ Object

Finds a tag on this record by name



63
64
65
# File 'lib/lean_tag/taggable.rb', line 63

def find_tag(tag_name)
  self.tags.find_by_name(tag_name)
end

#included_tags(tag_names) ⇒ Object

Finds current tags on this record which are in the passed list



69
70
71
# File 'lib/lean_tag/taggable.rb', line 69

def included_tags(tag_names)
  self.tags.select { |t| t.name.in?(tag_names) }
end

#remove_tag(tag, method = 'mark_for_destruction') ⇒ Object

Removes a single tag on parent save



75
76
77
78
79
80
81
82
# File 'lib/lean_tag/taggable.rb', line 75

def remove_tag(tag, method='mark_for_destruction')
  tag = self.find_tag(tag) if tag.is_a?(String)

  tagging = tagging.find_by_tag_id(tag.id)
  tagging.send(method) unless tagging.nil?

  destroy_if_unused(tag)
end

#remove_tag!(tag) ⇒ Object

Removes a single tag immediately



86
87
88
89
90
91
92
93
# File 'lib/lean_tag/taggable.rb', line 86

def remove_tag!(tag)
  tag = self.find_tag(tag) if tag.is_a?(String)

  tagging = tagging.find_by_tag_id(tag.id)
  tagging.destroy unless tagging.nil?

  destroy_if_unused(tag)
end

#tag_listObject

Returns a delimited list of tag names



109
110
111
# File 'lib/lean_tag/taggable.rb', line 109

def tag_list
  self.tags.map(&:name).join(LeanTag.config.delimiter)
end

#tag_list=(value) ⇒ Object

Set a list of tags



97
98
99
100
101
102
103
104
105
# File 'lib/lean_tag/taggable.rb', line 97

def tag_list=(value)
  tag_names = value.blank? ? [] : value.split(LeanTag.config.delimiter)

  # Get rid of existing tags that aren't in the list
  self.excluded_tags(tag_names).each { |t| self.remove_tag(t) }

  # Add any new tags
  tag_names.each { |t| self.add_tag(t) }
end