public
Fork of halorgium/mephisto
Description: A mirror of the mephisto code-base
Homepage: http://mephistoblog.com/
Clone URL: git://github.com/technoweenie/mephisto.git
Click here to lend your support to: mephisto and make a donation at www.pledgie.com !
mephisto / app / models / tag.rb
100644 84 lines (71 sloc) 1.926 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
class Tag < ActiveRecord::Base
  has_many :taggings
 
  class << self
    def [](tag)
      find_by_name(tag.to_s)
    end
 
    # parses a list of tags into tag names
    #
    # Tag.parse('a, b, c')
    # # => ['a', 'b', 'c']
    #
    # Tag.parse("a b c")
    # # => ['a', 'b', 'c']
    #
    # Tag.parse(%(a "b c"))
    # # => ['a', 'b c']
    def parse(list)
      return list if list.is_a?(Array)
      list.include?(',') ? parse_with_commas(list) : parse_with_spaces(list)
    end
 
    # Parses comma separated tag list and returns tags for them.
    #
    # Tag.parse_to_tags('a, b, c')
    # # => [Tag, Tag, Tag]
    def parse_to_tags(list)
      find_or_create(parse(list))
    end
 
    # Returns Tags from an array of tag names
    #
    # Tag.find_or_create(['a', 'b', 'c'])
    # # => [Tag, Tag, Tag]
    def find_or_create(tag_names)
      transaction do
        found_tags = find :all, :conditions => ['name IN (?)', tag_names]
        found_tags + (tag_names - found_tags.collect(&:name)).collect { |s| create!(:name => s) }
      end
    end
  
    private
      def parse_with_commas(list)
        cleanup_tags(list.split(','))
      end
      
      def parse_with_spaces(list)
        tags = []
 
        # first, pull out the quoted tags
        list.gsub!(/\"(.*?)\"\s*/ ) { tags << $1; "" }
        
        # then, get whatever's left
        tags.concat list.split(/\s/)
 
        cleanup_tags(tags)
      end
    
      def cleanup_tags(tags)
        tags.tap do |t|
          t.collect! do |tag|
            unless tag.blank?
              tag.downcase!
              tag.gsub!(/:/, '')
              tag.strip!
              tag
            end
          end
          t.compact!
          t.uniq!
        end
      end
  end
 
  def ==(comparison_object)
    super || name == comparison_object.to_s
  end
 
  def to_s() name end
  alias to_param to_s
  alias to_liquid to_s
end