Add the has_many_polymorphs plugin
[cs356-p2-videostore.git] / vendor / plugins / has_many_polymorphs / generators / tagging / templates / tagging_extensions.rb
1
2 class ActiveRecord::Base #:nodoc:
3
4   # These extensions make models taggable. This file is automatically generated and required by your app if you run the tagging generator included with has_many_polymorphs.
5   module TaggingExtensions
6     
7     # Add tags to <tt>self</tt>. Accepts a string of tagnames, an array of tagnames, an array of ids, or an array of Tags.
8     #
9     # We need to avoid name conflicts with the built-in ActiveRecord association methods, thus the underscores.
10     def _add_tags incoming
11       taggable?(true)
12       tag_cast_to_string(incoming).each do |tag_name|
13         begin
14           tag = Tag.find_or_create_by_name(tag_name)
15           raise Tag::Error, "tag could not be saved: #{tag_name}" if tag.new_record?
16           tag.taggables << self
17         rescue ActiveRecord::StatementInvalid => e
18           raise unless e.to_s =~ /duplicate/i
19         end
20       end
21     end
22   
23     # Removes tags from <tt>self</tt>. Accepts a string of tagnames, an array of tagnames, an array of ids, or an array of Tags.  
24     def _remove_tags outgoing
25       taggable?(true)
26       outgoing = tag_cast_to_string(outgoing)
27   <% if options[:self_referential] %>  
28       # because of http://dev.rubyonrails.org/ticket/6466
29       taggings.destroy(*(taggings.find(:all, :include => :<%= parent_association_name -%>).select do |tagging| 
30         outgoing.include? tagging.<%= parent_association_name -%>.name
31       end))
32   <% else -%>   
33       <%= parent_association_name -%>s.delete(*(<%= parent_association_name -%>s.select do |tag|
34         outgoing.include? tag.name    
35       end))
36   <% end -%>
37     end
38
39    # Returns the tags on <tt>self</tt> as a string.
40     def tag_list
41       # Redefined later to avoid an RDoc parse error.
42     end
43   
44     # Replace the existing tags on <tt>self</tt>. Accepts a string of tagnames, an array of tagnames, an array of ids, or an array of Tags.
45     def tag_with list    
46       #:stopdoc:
47       taggable?(true)
48       list = tag_cast_to_string(list)
49              
50       # Transactions may not be ideal for you here; be aware.
51       Tag.transaction do 
52         current = <%= parent_association_name -%>s.map(&:name)
53         _add_tags(list - current)
54         _remove_tags(current - list)
55       end
56       
57       self
58       #:startdoc:
59     end
60
61    # Returns the tags on <tt>self</tt> as a string.
62     def tag_list #:nodoc:
63       #:stopdoc:
64       taggable?(true)
65       <%= parent_association_name -%>s.reload
66       <%= parent_association_name -%>s.to_s
67       #:startdoc:
68     end
69     
70     private 
71     
72     def tag_cast_to_string obj #:nodoc:
73       case obj
74         when Array
75           obj.map! do |item|
76             case item
77               when /^\d+$/, Fixnum then Tag.find(item).name # This will be slow if you use ids a lot.
78               when Tag then item.name
79               when String then item
80               else
81                 raise "Invalid type"
82             end
83           end              
84         when String
85           obj = obj.split(Tag::DELIMITER).map do |tag_name| 
86             tag_name.strip.squeeze(" ")
87           end
88         else
89           raise "Invalid object of class #{obj.class} as tagging method parameter"
90       end.flatten.compact.map(&:downcase).uniq
91     end 
92   
93     # Check if a model is in the :taggables target list. The alternative to this check is to explicitly include a TaggingMethods module (which you would create) in each target model.  
94     def taggable?(should_raise = false) #:nodoc:
95       unless flag = respond_to?(:<%= parent_association_name -%>s)
96         raise "#{self.class} is not a taggable model" if should_raise
97       end
98       flag
99     end
100
101   end
102
103   include TaggingExtensions
104
105 end
106