public
Rubygem
Description: A tagging plugin for Rails applications that allows for custom tagging along dynamic contexts.
Homepage: http://mbleigh.lighthouseapp.com/projects/10116-acts-as-taggable-on
Clone URL: git://github.com/mbleigh/acts-as-taggable-on.git
Click here to lend your support to: acts-as-taggable-on and make a donation at www.pledgie.com !
Added support and specs for Single Table Inheritance. Thanks to slainer68 for 
the patch! [#5 status:resolved]
mbleigh (author)
Mon Jun 09 12:04:15 -0700 2008
commit  1bedda907e62d6574a7c2bc6ee73558b7ac078f6
tree    309aa2ff9a467db1e17cfae267a3ed49c1a4f833
parent  e488a0040ec1def0b6406ae2afb11f18e14ab6b6
...
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
29
30
31
...
34
35
36
37
38
39
40
41
...
64
65
66
 
67
68
69
70
 
71
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
74
75
...
11
12
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
15
16
17
...
20
21
22
 
 
23
24
25
...
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
0
@@ -11,21 +11,7 @@ module ActiveRecord
0
         end
0
         
0
         def acts_as_taggable_on(*args)
0
-          self.class_eval do
0
-            @tag_types = args
0
-            def self.tag_types
0
-              @tag_types
0
-            end
0
-            
0
-            has_many :taggings, :as => :taggable, :dependent => :destroy, :include => :tag
0
-            has_many :base_tags, :class_name => "Tag", :through => :taggings, :source => :tag
0
-            
0
-            attr_writer :custom_contexts
0
-            
0
-            before_save :save_cached_tag_list
0
-            after_save :save_tags
0
-          end
0
-          
0
+          puts "Registering #{args.inspect} with #{self.inspect}"
0
           for tag_type in args
0
             tag_type = tag_type.to_s
0
             self.class_eval do
0
@@ -34,8 +20,6 @@ module ActiveRecord
0
               has_many "#{tag_type}".to_sym, :through => "#{tag_type.singularize}_taggings".to_sym, :source => :tag
0
             end
0
             
0
-            include ActiveRecord::Acts::TaggableOn::InstanceMethods
0
-            
0
             self.class_eval <<-RUBY
0
               def self.caching_#{tag_type.singularize}_list?
0
                 caching_tag_list_on?("#{tag_type}")
0
@@ -64,12 +48,31 @@ module ActiveRecord
0
               def find_related_#{tag_type}(options = {})
0
                 related_tags_on('#{tag_type}',options)
0
               end
0
+              alias_method :find_related_on_#{tag_type}, :find_related_#{tag_type}
0
             RUBY
0
-          end
0
-          
0
-          extend ActiveRecord::Acts::TaggableOn::SingletonMethods          
0
+          end      
0
           
0
-          alias_method_chain :reload, :tag_list
0
+          if respond_to?(:tag_types)
0
+            puts "Appending #{args.inspect} onto #{tag_types.inspect}"
0
+            write_inheritable_attribute(:tag_types, tag_types + args)
0
+          else
0
+            self.class_eval do
0
+              write_inheritable_attribute(:tag_types, args)
0
+              class_inheritable_reader :tag_types
0
+            
0
+              has_many :taggings, :as => :taggable, :dependent => :destroy, :include => :tag
0
+              has_many :base_tags, :class_name => "Tag", :through => :taggings, :source => :tag
0
+            
0
+              attr_writer :custom_contexts
0
+            
0
+              before_save :save_cached_tag_list
0
+              after_save :save_tags
0
+            end
0
+            
0
+            include ActiveRecord::Acts::TaggableOn::InstanceMethods
0
+            extend ActiveRecord::Acts::TaggableOn::SingletonMethods                
0
+            alias_method_chain :reload, :tag_list
0
+          end
0
         end
0
         
0
         def is_taggable?
...
33
34
35
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
37
38
...
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
0
@@ -33,6 +33,23 @@ describe "acts_as_taggable_on" do
0
     end
0
   end
0
   
0
+  context "inheritance" do
0
+    before do
0
+      @taggable = TaggableModel.new(:name => "taggable")
0
+      @inherited_same = InheritingTaggableModel.new(:name => "inherited same")
0
+      @inherited_different = AlteredInheritingTaggableModel.new(:name => "inherited different")
0
+    end
0
+    
0
+    it "should pass on tag contexts to STI-inherited models" do
0
+      @inherited_same.should respond_to(:tag_list, :skill_list, :language_list)
0
+      @inherited_different.should respond_to(:tag_list, :skill_list, :language_list)
0
+    end
0
+    
0
+    it "should have tag contexts added in altered STI models" do
0
+      @inherited_different.should respond_to(:part_list)
0
+    end
0
+  end
0
+  
0
   context "reloading" do
0
     it "should save a model instantiated by Model.find" do
0
       taggable = TaggableModel.create!(:name => "Taggable")
...
88
89
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
92
...
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
0
@@ -88,4 +88,31 @@ describe "Taggable" do
0
     bob.save
0
     TaggableModel.find_tagged_with("spinning", :on => :rotors).should_not be_empty
0
   end
0
+  
0
+  context "inheritance" do
0
+    before do
0
+      @taggable = TaggableModel.new(:name => "taggable")
0
+      @inherited_same = InheritingTaggableModel.new(:name => "inherited same")
0
+      @inherited_different = AlteredInheritingTaggableModel.new(:name => "inherited different")
0
+    end
0
+    
0
+    it "should be able to save tags for inherited models" do
0
+      @inherited_same.tag_list = "bob, kelso"
0
+      @inherited_same.save
0
+      InheritingTaggableModel.find_tagged_with("bob").first.should == @inherited_same
0
+    end
0
+    
0
+    it "should find STI tagged models on the superclass" do
0
+      @inherited_same.tag_list = "bob, kelso"
0
+      @inherited_same.save
0
+      TaggableModel.find_tagged_with("bob").first.should == @inherited_same
0
+    end
0
+    
0
+    it "should be able to add on contexts only to some subclasses" do
0
+      @inherited_different.part_list = "fork, spoon"
0
+      @inherited_different.save
0
+      InheritingTaggableModel.find_tagged_with("fork", :on => :parts).should be_empty
0
+      AlteredInheritingTaggableModel.find_tagged_with("fork", :on => :parts).first.should == @inherited_different
0
+    end
0
+  end
0
 end
0
\ No newline at end of file
...
2
3
4
5
 
6
7
8
...
2
3
4
 
5
6
7
8
0
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../spec_helper'
0
 
0
 describe "Tagger" do
0
   before(:each) do
0
-    @user = User.new
0
+    @user = TaggableUser.new
0
     @taggable = TaggableModel.new(:name => "Bob Jones")
0
   end
0
   
...
15
16
17
 
18
19
20
 
21
22
23
...
15
16
17
18
19
20
 
21
22
23
24
0
@@ -15,9 +15,10 @@ ActiveRecord::Schema.define :version => 0 do
0
   
0
   create_table :taggable_models, :force => true do |t|
0
     t.column :name, :string
0
+    t.column :type, :string
0
     #t.column :cached_tag_list, :string
0
   end
0
-  create_table :users, :force => true do |t|
0
+  create_table :taggable_users, :force => true do |t|
0
     t.column :name, :string
0
   end
0
 end
...
6
7
8
9
 
 
10
11
12
 
 
 
 
 
 
 
 
13
14
15
...
6
7
8
 
9
10
11
12
 
13
14
15
16
17
18
19
20
21
22
23
0
@@ -6,9 +6,17 @@ ActiveRecord::Base.logger = Logger.new(plugin_spec_dir + "/debug.log")
0
 load(File.dirname(__FILE__) + '/schema.rb')
0
 
0
 class TaggableModel < ActiveRecord::Base
0
-  acts_as_taggable_on :tags, :languages, :skills
0
+  acts_as_taggable_on :tags, :languages
0
+  acts_as_taggable_on :skills
0
 end
0
 
0
-class User < ActiveRecord::Base
0
+class InheritingTaggableModel < TaggableModel
0
+end
0
+
0
+class AlteredInheritingTaggableModel < TaggableModel
0
+  acts_as_taggable_on :parts
0
+end
0
+
0
+class TaggableUser < ActiveRecord::Base
0
   acts_as_tagger
0
 end
0
\ No newline at end of file

Comments