Add the has_many_polymorphs plugin
[cs356-p2-videostore.git] / vendor / plugins / has_many_polymorphs / README
1
2 Has_many_polymorphs
3
4 An ActiveRecord plugin for self-referential and double-sided polymorphic associations.
5
6 == License
7
8 Copyright 2007 Cloudburst, LLC. Licensed under the AFL 3. See the included LICENSE file. 
9
10 The public certificate for this gem is at http://rubyforge.org/frs/download.php/25331/evan_weaver-original-public_cert.pem.
11
12 == Description
13
14 This plugin lets you define self-referential and double-sided polymorphic associations in your models. It is an extension of <tt>has_many :through</tt>.
15
16 “Polymorphic” means an association can freely point to any of several unrelated model classes, instead of being tied to one particular class.
17
18 == Features
19
20 * self-references
21 * double-sided polymorphism
22 * efficient database usage
23 * STI support
24 * namespace support
25 * automatic individual and reverse associations
26
27 The plugin also includes a generator for a tagging system, a common use case (see below).
28
29 == Requirements
30
31 * Rails 1.2.3 or greater
32
33 = Usage
34
35 == Installation
36
37 To install the Rails plugin, run:
38   script/plugin install svn://rubyforge.org/var/svn/fauna/has_many_polymorphs/trunk
39
40 There's also a gem version. To install it instead, run: 
41   sudo gem install has_many_polymorphs
42   
43 If you are using the gem, make sure to add <tt>require 'has_many_polymorphs'</tt> to <tt>environment.rb</tt>, before Rails::Initializer block.
44
45 == Configuration
46
47 Setup the parent model as so:
48
49   class Kennel < ActiveRecord::Base
50     has_many_polymorphs :guests, :from => [:dogs, :cats, :birds]
51   end
52
53 The join model:
54
55   class GuestsKennel < ActiveRecord::Base
56     belongs_to :kennel
57     belongs_to :guest, :polymorphic => true
58   end
59
60 One of the child models:
61
62   class Dog < ActiveRecord::Base
63     # nothing
64   end
65
66 See ActiveRecord::Associations::PolymorphicClassMethods for more configuration options.
67
68 == Helper methods example
69
70   >> k = Kennel.find(1)
71   #<Kennel id: 1, name: "Happy Paws">
72   >> k.guests.map(&:class) 
73   [Dog, Cat, Cat, Bird]
74   
75   >> k.guests.push(Cat.create); k.cats.size
76   3
77   >> k.guests << Cat.create; k.cats.size
78   4
79   >> k.guests.size
80   6
81
82   >> d = k.dogs.first
83   #<Dog id: 3, name: "Rover">
84   >> d.kennels 
85   [#<Kennel id: 1, name: "Happy Paws">]
86   
87   >> k.guests.delete(d); k.dogs.size
88   0
89   >> k.guests.size
90   5  
91   
92 Note that the parent method is always plural, even if there is only one parent (<tt>Dog#kennels</tt>, not <tt>Dog#kennel</tt>).
93
94 See ActiveRecord::Associations::PolymorphicAssociation for more helper method details.
95
96 = Extras
97
98 == Double-sided polymorphism
99
100 Double-sided relationships are defined on the join model:
101
102   class Devouring < ActiveRecord::Base
103     belongs_to :guest, :polymorphic => true
104     belongs_to :eaten, :polymorphic => true
105   
106     acts_as_double_polymorphic_join(
107       :guests =>[:dogs, :cats], 
108       :eatens => [:cats, :birds]
109     )       
110   end
111   
112 Now, dogs and cats can eat birds and cats. Birds can't eat anything (they aren't <tt>guests</tt>) and dogs can't be eaten by anything (since they aren't <tt>eatens</tt>). The keys stand for what the models are, not what they do. 
113
114 In this case, each guest/eaten relationship is called a Devouring.
115
116 See ActiveRecord::Associations::PolymorphicClassMethods for more.
117
118 == Tagging generator
119
120 Has_many_polymorphs includes a tagging system generator. Run:
121   script/generate tagging Dog Cat [...MoreModels...]
122
123 This adds a migration and new Tag and Tagging models in <tt>app/models</tt>. It configures Tag with an appropriate <tt>has_many_polymorphs</tt> call against the models you list at the command line. It also adds the file <tt>lib/tagging_extensions.rb</tt> and <tt>requires</tt> it in <tt>environment.rb</tt>. 
124
125 Tests will also be generated. 
126
127 Once you've run the generator, you can tag records as follows:
128
129   >> d = Dog.create(:name => "Rover")
130   #<Dog id: 3, name: "Rover">
131   >> d.tag_list
132   ""
133   >> d.tag_with "fierce loud"
134   #<Dog id: 3, name: "Rover">
135   >> d.tag_list
136   "fierce loud"
137   >> c = Cat.create(:name => "Chloe")
138   #<Cat id: 1, name: "Chloe">
139   >> c.tag_with "fierce cute"
140   #<Cat id: 1, name: "Chloe">
141   >> c.tag_list
142   "cute fierce"
143   >> Tag.find_by_name("fierce").taggables 
144   [#<Cat id: 1, name: "Chloe">, #<Dog id: 3, name: "Rover">]
145
146 The generator accepts the optional flag <tt>--skip-migration</tt> to skip generating a migration (for example, if you are converting from <tt>acts_as_taggable</tt>). It also accepts the flag <tt>--self-referential</tt> if you want to be able to tag tags.
147
148 See ActiveRecord::Base::TaggingExtensions, Tag, and Tagging for more.
149
150 == Troubleshooting
151
152 Some debugging tools are available in <tt>lib/has_many_polymorphs/debugging_tools.rb</tt>.
153
154 If you are having trouble, think very carefully about how your model classes, key columns, and table names relate. You may have to explicitly specify options on your join model such as <tt>:class_name</tt>, <tt>:foreign_key</tt>, or <tt>:as</tt>. The included tests are a good place to look for examples.
155
156 Note that because of the way Rails reloads model classes, the plugin can sometimes bog down your development server. Set <tt>config.cache_classes = true</tt> in <tt>config/environments/development.rb</tt> to avoid this. 
157
158 == Reporting problems
159
160 * http://rubyforge.org/forum/forum.php?forum_id=16450
161
162 Patches and contributions are very welcome. Please note that contributors are required to assign copyright for their additions to Cloudburst, LLC.
163
164 == Further resources
165
166 * http://blog.evanweaver.com/articles/2007/08/15/polymorphs-tutorial
167 * http://blog.evanweaver.com/articles/2007/02/22/polymorphs-25-total-insanity-branch
168 * http://blog.evanweaver.com/articles/2007/02/09/how-to-find-the-most-popular-tags
169 * http://blog.evanweaver.com/articles/2007/01/13/growing-up-your-acts_as_taggable
170 * http://blog.evanweaver.com/articles/2006/12/02/polymorphs-19
171 * http://blog.evanweaver.com/articles/2006/11/05/directed-double-polymorphic-associations
172 * http://blog.evanweaver.com/articles/2006/11/04/namespaced-model-support-in-has_many_polymorphs
173 * http://blog.evanweaver.com/articles/2006/09/26/sti-support-in-has_many_polymorphs
174 * http://blog.evanweaver.com/articles/2006/09/11/make-polymorphic-children-belong-to-only-one-parent