johnsbrn-has_many_polymorphs 2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. data/CHANGELOG +84 -0
  2. data/LICENSE +184 -0
  3. data/Manifest +174 -0
  4. data/README +205 -0
  5. data/TODO +2 -0
  6. data/examples/hmph.rb +69 -0
  7. data/generators/tagging/tagging_generator.rb +97 -0
  8. data/generators/tagging/templates/migration.rb +28 -0
  9. data/generators/tagging/templates/tag.rb +39 -0
  10. data/generators/tagging/templates/tag_test.rb +15 -0
  11. data/generators/tagging/templates/tagging.rb +16 -0
  12. data/generators/tagging/templates/tagging_extensions.rb +159 -0
  13. data/generators/tagging/templates/tagging_test.rb +85 -0
  14. data/generators/tagging/templates/taggings.yml +23 -0
  15. data/generators/tagging/templates/tags.yml +7 -0
  16. data/has_many_polymorphs.gemspec +100 -0
  17. data/init.rb +2 -0
  18. data/lib/has_many_polymorphs.rb +27 -0
  19. data/lib/has_many_polymorphs/association.rb +159 -0
  20. data/lib/has_many_polymorphs/autoload.rb +70 -0
  21. data/lib/has_many_polymorphs/base.rb +60 -0
  22. data/lib/has_many_polymorphs/class_methods.rb +600 -0
  23. data/lib/has_many_polymorphs/configuration.rb +19 -0
  24. data/lib/has_many_polymorphs/debugging_tools.rb +103 -0
  25. data/lib/has_many_polymorphs/rake_task_redefine_task.rb +35 -0
  26. data/lib/has_many_polymorphs/reflection.rb +58 -0
  27. data/lib/has_many_polymorphs/support_methods.rb +84 -0
  28. data/test/fixtures/bow_wows.yml +10 -0
  29. data/test/fixtures/cats.yml +18 -0
  30. data/test/fixtures/eaters_foodstuffs.yml +0 -0
  31. data/test/fixtures/fish.yml +12 -0
  32. data/test/fixtures/frogs.yml +5 -0
  33. data/test/fixtures/keep_your_enemies_close.yml +0 -0
  34. data/test/fixtures/little_whale_pupils.yml +0 -0
  35. data/test/fixtures/people.yml +7 -0
  36. data/test/fixtures/petfoods.yml +11 -0
  37. data/test/fixtures/whales.yml +5 -0
  38. data/test/fixtures/wild_boars.yml +10 -0
  39. data/test/generator/tagging_generator_test.rb +42 -0
  40. data/test/integration/app/README +182 -0
  41. data/test/integration/app/Rakefile +19 -0
  42. data/test/integration/app/app/controllers/application.rb +7 -0
  43. data/test/integration/app/app/controllers/bones_controller.rb +5 -0
  44. data/test/integration/app/app/helpers/addresses_helper.rb +2 -0
  45. data/test/integration/app/app/helpers/application_helper.rb +3 -0
  46. data/test/integration/app/app/helpers/bones_helper.rb +2 -0
  47. data/test/integration/app/app/helpers/sellers_helper.rb +28 -0
  48. data/test/integration/app/app/helpers/states_helper.rb +2 -0
  49. data/test/integration/app/app/helpers/users_helper.rb +2 -0
  50. data/test/integration/app/app/models/bone.rb +2 -0
  51. data/test/integration/app/app/models/double_sti_parent.rb +2 -0
  52. data/test/integration/app/app/models/double_sti_parent_relationship.rb +2 -0
  53. data/test/integration/app/app/models/organic_substance.rb +2 -0
  54. data/test/integration/app/app/models/single_sti_parent.rb +4 -0
  55. data/test/integration/app/app/models/single_sti_parent_relationship.rb +4 -0
  56. data/test/integration/app/app/models/stick.rb +2 -0
  57. data/test/integration/app/app/models/stone.rb +2 -0
  58. data/test/integration/app/app/views/addresses/edit.html.erb +12 -0
  59. data/test/integration/app/app/views/addresses/index.html.erb +18 -0
  60. data/test/integration/app/app/views/addresses/new.html.erb +11 -0
  61. data/test/integration/app/app/views/addresses/show.html.erb +3 -0
  62. data/test/integration/app/app/views/bones/index.rhtml +5 -0
  63. data/test/integration/app/app/views/layouts/addresses.html.erb +17 -0
  64. data/test/integration/app/app/views/layouts/sellers.html.erb +17 -0
  65. data/test/integration/app/app/views/layouts/states.html.erb +17 -0
  66. data/test/integration/app/app/views/layouts/users.html.erb +17 -0
  67. data/test/integration/app/app/views/sellers/edit.html.erb +12 -0
  68. data/test/integration/app/app/views/sellers/index.html.erb +20 -0
  69. data/test/integration/app/app/views/sellers/new.html.erb +11 -0
  70. data/test/integration/app/app/views/sellers/show.html.erb +3 -0
  71. data/test/integration/app/app/views/states/edit.html.erb +12 -0
  72. data/test/integration/app/app/views/states/index.html.erb +19 -0
  73. data/test/integration/app/app/views/states/new.html.erb +11 -0
  74. data/test/integration/app/app/views/states/show.html.erb +3 -0
  75. data/test/integration/app/app/views/users/edit.html.erb +12 -0
  76. data/test/integration/app/app/views/users/index.html.erb +22 -0
  77. data/test/integration/app/app/views/users/new.html.erb +11 -0
  78. data/test/integration/app/app/views/users/show.html.erb +3 -0
  79. data/test/integration/app/config/boot.rb +110 -0
  80. data/test/integration/app/config/database.yml +17 -0
  81. data/test/integration/app/config/environment.rb +19 -0
  82. data/test/integration/app/config/environment.rb.canonical +19 -0
  83. data/test/integration/app/config/environments/development.rb +8 -0
  84. data/test/integration/app/config/environments/production.rb +18 -0
  85. data/test/integration/app/config/environments/test.rb +19 -0
  86. data/test/integration/app/config/locomotive.yml +6 -0
  87. data/test/integration/app/config/routes.rb +33 -0
  88. data/test/integration/app/config/ultrasphinx/default.base +56 -0
  89. data/test/integration/app/config/ultrasphinx/development.conf.canonical +155 -0
  90. data/test/integration/app/db/migrate/001_create_sticks.rb +11 -0
  91. data/test/integration/app/db/migrate/002_create_stones.rb +11 -0
  92. data/test/integration/app/db/migrate/003_create_organic_substances.rb +11 -0
  93. data/test/integration/app/db/migrate/004_create_bones.rb +8 -0
  94. data/test/integration/app/db/migrate/005_create_single_sti_parents.rb +11 -0
  95. data/test/integration/app/db/migrate/006_create_double_sti_parents.rb +11 -0
  96. data/test/integration/app/db/migrate/007_create_single_sti_parent_relationships.rb +13 -0
  97. data/test/integration/app/db/migrate/008_create_double_sti_parent_relationships.rb +14 -0
  98. data/test/integration/app/db/migrate/009_create_library_model.rb +11 -0
  99. data/test/integration/app/doc/README_FOR_APP +2 -0
  100. data/test/integration/app/generators/commenting_generator_test.rb +83 -0
  101. data/test/integration/app/lib/library_model.rb +2 -0
  102. data/test/integration/app/public/404.html +30 -0
  103. data/test/integration/app/public/500.html +30 -0
  104. data/test/integration/app/public/dispatch.cgi +10 -0
  105. data/test/integration/app/public/dispatch.fcgi +24 -0
  106. data/test/integration/app/public/dispatch.rb +10 -0
  107. data/test/integration/app/public/favicon.ico +0 -0
  108. data/test/integration/app/public/images/rails.png +0 -0
  109. data/test/integration/app/public/index.html +277 -0
  110. data/test/integration/app/public/javascripts/application.js +2 -0
  111. data/test/integration/app/public/javascripts/controls.js +833 -0
  112. data/test/integration/app/public/javascripts/dragdrop.js +942 -0
  113. data/test/integration/app/public/javascripts/effects.js +1088 -0
  114. data/test/integration/app/public/javascripts/prototype.js +2515 -0
  115. data/test/integration/app/public/robots.txt +1 -0
  116. data/test/integration/app/public/stylesheets/scaffold.css +74 -0
  117. data/test/integration/app/script/about +3 -0
  118. data/test/integration/app/script/breakpointer +3 -0
  119. data/test/integration/app/script/console +3 -0
  120. data/test/integration/app/script/destroy +3 -0
  121. data/test/integration/app/script/generate +3 -0
  122. data/test/integration/app/script/performance/benchmarker +3 -0
  123. data/test/integration/app/script/performance/profiler +3 -0
  124. data/test/integration/app/script/plugin +3 -0
  125. data/test/integration/app/script/process/inspector +3 -0
  126. data/test/integration/app/script/process/reaper +3 -0
  127. data/test/integration/app/script/process/spawner +3 -0
  128. data/test/integration/app/script/runner +3 -0
  129. data/test/integration/app/script/server +3 -0
  130. data/test/integration/app/test/fixtures/double_sti_parent_relationships.yml +7 -0
  131. data/test/integration/app/test/fixtures/double_sti_parents.yml +7 -0
  132. data/test/integration/app/test/fixtures/organic_substances.yml +5 -0
  133. data/test/integration/app/test/fixtures/single_sti_parent_relationships.yml +7 -0
  134. data/test/integration/app/test/fixtures/single_sti_parents.yml +7 -0
  135. data/test/integration/app/test/fixtures/sticks.yml +7 -0
  136. data/test/integration/app/test/fixtures/stones.yml +7 -0
  137. data/test/integration/app/test/functional/addresses_controller_test.rb +57 -0
  138. data/test/integration/app/test/functional/bones_controller_test.rb +8 -0
  139. data/test/integration/app/test/functional/sellers_controller_test.rb +57 -0
  140. data/test/integration/app/test/functional/states_controller_test.rb +57 -0
  141. data/test/integration/app/test/functional/users_controller_test.rb +57 -0
  142. data/test/integration/app/test/test_helper.rb +8 -0
  143. data/test/integration/app/test/unit/bone_test.rb +8 -0
  144. data/test/integration/app/test/unit/double_sti_parent_relationship_test.rb +8 -0
  145. data/test/integration/app/test/unit/double_sti_parent_test.rb +8 -0
  146. data/test/integration/app/test/unit/organic_substance_test.rb +8 -0
  147. data/test/integration/app/test/unit/single_sti_parent_relationship_test.rb +8 -0
  148. data/test/integration/app/test/unit/single_sti_parent_test.rb +8 -0
  149. data/test/integration/app/test/unit/stick_test.rb +8 -0
  150. data/test/integration/app/test/unit/stone_test.rb +8 -0
  151. data/test/integration/server_test.rb +43 -0
  152. data/test/models/aquatic/fish.rb +5 -0
  153. data/test/models/aquatic/pupils_whale.rb +7 -0
  154. data/test/models/aquatic/whale.rb +15 -0
  155. data/test/models/beautiful_fight_relationship.rb +26 -0
  156. data/test/models/canine.rb +9 -0
  157. data/test/models/cat.rb +5 -0
  158. data/test/models/dog.rb +18 -0
  159. data/test/models/eaters_foodstuff.rb +10 -0
  160. data/test/models/frog.rb +4 -0
  161. data/test/models/kitten.rb +3 -0
  162. data/test/models/parentship.rb +4 -0
  163. data/test/models/person.rb +9 -0
  164. data/test/models/petfood.rb +39 -0
  165. data/test/models/tabby.rb +2 -0
  166. data/test/models/wild_boar.rb +3 -0
  167. data/test/modules/extension_module.rb +9 -0
  168. data/test/modules/other_extension_module.rb +9 -0
  169. data/test/patches/symlinked_plugins_1.2.6.diff +46 -0
  170. data/test/schema.rb +87 -0
  171. data/test/setup.rb +14 -0
  172. data/test/test_helper.rb +51 -0
  173. data/test/unit/has_many_polymorphs_test.rb +714 -0
  174. metadata +237 -0
@@ -0,0 +1,23 @@
1
+ ---
2
+ <% if taggable_models.size > 1 -%>
3
+ taggings_003:
4
+ <%= parent_association_name -%>_id: "2"
5
+ id: "3"
6
+ taggable_type: <%= model_one %>
7
+ taggable_id: "1"
8
+ <% end -%>
9
+ taggings_004:
10
+ <%= parent_association_name -%>_id: "2"
11
+ id: "4"
12
+ taggable_type: <%= model_two %>
13
+ taggable_id: "2"
14
+ taggings_001:
15
+ <%= parent_association_name -%>_id: "1"
16
+ id: "1"
17
+ taggable_type: <%= model_two %>
18
+ taggable_id: "1"
19
+ taggings_002:
20
+ <%= parent_association_name -%>_id: "1"
21
+ id: "2"
22
+ taggable_type: <%= model_two %>
23
+ taggable_id: "2"
@@ -0,0 +1,7 @@
1
+ ---
2
+ tags_001:
3
+ name: pale
4
+ id: "1"
5
+ tags_002:
6
+ name: imperial
7
+ id: "2"
@@ -0,0 +1,100 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{has_many_polymorphs}
5
+ s.version = "2.13"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = [""]
9
+ #s.cert_chain = ["-----BEGIN CERTIFICATE-----\nMIIDLjCCAhagAwIBAgIBADANBgkqhkiG9w0BAQUFADA9MQ0wCwYDVQQDDARldmFu\nMRgwFgYKCZImiZPyLGQBGRYIY2xvdWRidXIxEjAQBgoJkiaJk/IsZAEZFgJzdDAe\nFw0wNzA5MTYxMDMzMDBaFw0wODA5MTUxMDMzMDBaMD0xDTALBgNVBAMMBGV2YW4x\nGDAWBgoJkiaJk/IsZAEZFghjbG91ZGJ1cjESMBAGCgmSJomT8ixkARkWAnN0MIIB\nIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5C0Io89nyApnr+PvbNFge9Vs\nyRWAlGBUEMahpXp28VrrfXZT0rAW7JBo4PlCE3jl4nE4dzE6gAdItSycjTosrw7A\nIr5+xoyl4Vb35adv56TIQQXvNz+BzlqnkAY5JN0CSBRTQb6mxS3hFyD/h4qgDosj\nR2RFVzHqSxCS8xq4Ny8uzOwOi+Xyu4w67fI5JvnPvMxqrlR1eaIQHmxnf76RzC46\nQO5QhufjAYGGXd960XzbQsQyTDUYJzrvT7AdOfiyZzKQykKt8dEpDn+QPjFTnGnT\nQmgJBX5WJN0lHF2l1sbv3gh4Kn1tZu+kTUqeXY6ShAoDTyvZRiFqQdwh8w2lTQID\nAQABozkwNzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU+WqJz3xQ\nXSea1hRvvHWcIMgeeC4wDQYJKoZIhvcNAQEFBQADggEBAGLZ75jfOEW8Nsl26CTt\nJFrWxQTcQT/UljeefVE3xYr7lc9oQjbqO3FOyued3qW7TaNEtZfSHoYeUSMYbpw1\nXAwocIPuSRFDGM4B+hgQGVDx8PMGiJKom4qLXjO40UZsR7QyN/u869Vj45LURm6h\nMBcPeqCASI+WNprj9+uZa2kmHiitrFqqfMBNlm5IFbn9XeYSta9AHVvs5QQqV2m5\nhIPfLqCyxsn/YgOGvo6iwyQTWyTswamaAC3HRWZxIS1sfn/Ssqa7E7oQMkv5FAXr\nx5rKePfXINf8XTJczkl9OBEYdE9aNdJsJpXD0asLgGVwBICS5Bjohp6mizJcDC1+\nyZ0=\n-----END CERTIFICATE-----\n"]
10
+ s.date = %q{2009-01-14}
11
+ s.description = %q{An ActiveRecord plugin for self-referential and double-sided polymorphic associations.}
12
+ s.email = %q{}
13
+ s.files = ["CHANGELOG",
14
+ "examples/hmph.rb",
15
+ "generators/tagging/tagging_generator.rb",
16
+ "generators/tagging/templates/migration.rb",
17
+ "generators/tagging/templates/tag.rb",
18
+ "generators/tagging/templates/tag_test.rb",
19
+ "generators/tagging/templates/tagging.rb",
20
+ "generators/tagging/templates/tagging_extensions.rb",
21
+ "generators/tagging/templates/tagging_test.rb",
22
+ "generators/tagging/templates/taggings.yml",
23
+ "generators/tagging/templates/tags.yml",
24
+ "init.rb",
25
+ "lib/has_many_polymorphs/association.rb",
26
+ "lib/has_many_polymorphs/autoload.rb",
27
+ "lib/has_many_polymorphs/base.rb",
28
+ "lib/has_many_polymorphs/class_methods.rb",
29
+ "lib/has_many_polymorphs/configuration.rb",
30
+ "lib/has_many_polymorphs/debugging_tools.rb",
31
+ "lib/has_many_polymorphs/rake_task_redefine_task.rb",
32
+ "lib/has_many_polymorphs/reflection.rb",
33
+ "lib/has_many_polymorphs/support_methods.rb",
34
+ "lib/has_many_polymorphs.rb",
35
+ "LICENSE", "Manifest", "README",
36
+ "test/fixtures/bow_wows.yml",
37
+ "test/fixtures/cats.yml",
38
+ "test/fixtures/eaters_foodstuffs.yml",
39
+ "test/fixtures/fish.yml",
40
+ "test/fixtures/frogs.yml",
41
+ "test/fixtures/keep_your_enemies_close.yml",
42
+ "test/fixtures/little_whale_pupils.yml",
43
+ "test/fixtures/people.yml",
44
+ "test/fixtures/petfoods.yml",
45
+ "test/fixtures/whales.yml",
46
+ "test/fixtures/wild_boars.yml",
47
+ "test/generator/tagging_generator_test.rb",
48
+ "test/integration/app/app/controllers/application.rb",
49
+ "test/integration/app/app/controllers/bones_controller.rb",
50
+ "test/integration/app/app/helpers/addresses_helper.rb",
51
+ "test/integration/app/app/helpers/application_helper.rb",
52
+ "test/integration/app/app/helpers/bones_helper.rb",
53
+ "test/integration/app/app/helpers/sellers_helper.rb",
54
+ "test/integration/app/app/helpers/states_helper.rb",
55
+ "test/integration/app/app/helpers/users_helper.rb",
56
+ "test/integration/app/app/models/bone.rb",
57
+ "test/integration/app/app/models/double_sti_parent.rb",
58
+ "test/integration/app/app/models/double_sti_parent_relationship.rb",
59
+ "test/integration/app/app/models/organic_substance.rb",
60
+ "test/integration/app/app/models/single_sti_parent.rb",
61
+ "test/integration/app/app/models/single_sti_parent_relationship.rb",
62
+ "test/integration/app/app/models/stick.rb",
63
+ "test/integration/app/app/models/stone.rb",
64
+ "test/integration/app/app/views/addresses/edit.html.erb",
65
+ "test/integration/app/app/views/addresses/index.html.erb",
66
+ "test/integration/app/app/views/addresses/new.html.erb",
67
+ "test/integration/app/app/views/addresses/show.html.erb",
68
+ "test/integration/app/app/views/bones/index.rhtml",
69
+ "test/integration/app/app/views/layouts/addresses.html.erb",
70
+ "test/integration/app/app/views/layouts/sellers.html.erb",
71
+ "test/integration/app/app/views/layouts/states.html.erb",
72
+ "test/integration/app/app/views/layouts/users.html.erb",
73
+ "test/integration/app/app/views/sellers/edit.html.erb",
74
+ "test/integration/app/app/views/sellers/index.html.erb",
75
+ "test/integration/app/app/views/sellers/new.html.erb",
76
+ "test/integration/app/app/views/sellers/show.html.erb",
77
+ "test/integration/app/app/views/states/edit.html.erb",
78
+ "test/integration/app/app/views/states/index.html.erb",
79
+ "test/integration/app/app/views/states/new.html.erb", "test/integration/app/app/views/states/show.html.erb", "test/integration/app/app/views/users/edit.html.erb", "test/integration/app/app/views/users/index.html.erb", "test/integration/app/app/views/users/new.html.erb", "test/integration/app/app/views/users/show.html.erb", "test/integration/app/config/boot.rb", "test/integration/app/config/database.yml", "test/integration/app/config/environment.rb", "test/integration/app/config/environment.rb.canonical", "test/integration/app/config/environments/development.rb", "test/integration/app/config/environments/production.rb", "test/integration/app/config/environments/test.rb", "test/integration/app/config/locomotive.yml", "test/integration/app/config/routes.rb", "test/integration/app/config/ultrasphinx/default.base", "test/integration/app/config/ultrasphinx/development.conf.canonical", "test/integration/app/db/migrate/001_create_sticks.rb", "test/integration/app/db/migrate/002_create_stones.rb", "test/integration/app/db/migrate/003_create_organic_substances.rb", "test/integration/app/db/migrate/004_create_bones.rb", "test/integration/app/db/migrate/005_create_single_sti_parents.rb", "test/integration/app/db/migrate/006_create_double_sti_parents.rb", "test/integration/app/db/migrate/007_create_single_sti_parent_relationships.rb", "test/integration/app/db/migrate/008_create_double_sti_parent_relationships.rb", "test/integration/app/db/migrate/009_create_library_model.rb", "test/integration/app/db/schema.rb", "test/integration/app/doc/README_FOR_APP", "test/integration/app/generators/commenting_generator_test.rb", "test/integration/app/hmp_development", "test/integration/app/lib/library_model.rb", "test/integration/app/public/404.html", "test/integration/app/public/500.html", "test/integration/app/public/dispatch.cgi", "test/integration/app/public/dispatch.fcgi", "test/integration/app/public/dispatch.rb", "test/integration/app/public/favicon.ico", "test/integration/app/public/images/rails.png", "test/integration/app/public/index.html", "test/integration/app/public/javascripts/application.js", "test/integration/app/public/javascripts/controls.js", "test/integration/app/public/javascripts/dragdrop.js", "test/integration/app/public/javascripts/effects.js", "test/integration/app/public/javascripts/prototype.js", "test/integration/app/public/robots.txt", "test/integration/app/public/stylesheets/scaffold.css", "test/integration/app/Rakefile", "test/integration/app/README", "test/integration/app/script/about", "test/integration/app/script/breakpointer", "test/integration/app/script/console", "test/integration/app/script/destroy", "test/integration/app/script/generate", "test/integration/app/script/performance/benchmarker", "test/integration/app/script/performance/profiler", "test/integration/app/script/plugin", "test/integration/app/script/process/inspector", "test/integration/app/script/process/reaper", "test/integration/app/script/process/spawner", "test/integration/app/script/runner", "test/integration/app/script/server", "test/integration/app/test/fixtures/double_sti_parent_relationships.yml", "test/integration/app/test/fixtures/double_sti_parents.yml", "test/integration/app/test/fixtures/organic_substances.yml", "test/integration/app/test/fixtures/single_sti_parent_relationships.yml", "test/integration/app/test/fixtures/single_sti_parents.yml", "test/integration/app/test/fixtures/sticks.yml", "test/integration/app/test/fixtures/stones.yml", "test/integration/app/test/functional/addresses_controller_test.rb", "test/integration/app/test/functional/bones_controller_test.rb", "test/integration/app/test/functional/sellers_controller_test.rb", "test/integration/app/test/functional/states_controller_test.rb", "test/integration/app/test/functional/users_controller_test.rb", "test/integration/app/test/test_helper.rb", "test/integration/app/test/unit/bone_test.rb", "test/integration/app/test/unit/double_sti_parent_relationship_test.rb", "test/integration/app/test/unit/double_sti_parent_test.rb", "test/integration/app/test/unit/organic_substance_test.rb", "test/integration/app/test/unit/single_sti_parent_relationship_test.rb", "test/integration/app/test/unit/single_sti_parent_test.rb", "test/integration/app/test/unit/stick_test.rb", "test/integration/app/test/unit/stone_test.rb", "test/integration/server_test.rb", "test/models/aquatic/fish.rb", "test/models/aquatic/pupils_whale.rb", "test/models/aquatic/whale.rb", "test/models/beautiful_fight_relationship.rb", "test/models/canine.rb", "test/models/cat.rb", "test/models/dog.rb", "test/models/eaters_foodstuff.rb", "test/models/frog.rb", "test/models/kitten.rb", "test/models/parentship.rb", "test/models/person.rb", "test/models/petfood.rb", "test/models/tabby.rb", "test/models/wild_boar.rb", "test/modules/extension_module.rb", "test/modules/other_extension_module.rb", "test/patches/symlinked_plugins_1.2.6.diff", "test/schema.rb", "test/setup.rb", "test/test_helper.rb", "test/unit/has_many_polymorphs_test.rb", "TODO", "has_many_polymorphs.gemspec"]
80
+ s.has_rdoc = true
81
+ s.homepage = %q{http://blog.evanweaver.com/files/doc/fauna/has_many_polymorphs/}
82
+ s.require_paths = ["lib"]
83
+ s.rubyforge_project = %q{fauna}
84
+ s.rubygems_version = %q{1.3.1}
85
+ s.summary = %q{An ActiveRecord plugin for self-referential and double-sided polymorphic associations.}
86
+ s.test_files = ["test/generator/tagging_generator_test.rb", "test/integration/server_test.rb", "test/unit/has_many_polymorphs_test.rb"]
87
+
88
+ if s.respond_to? :specification_version then
89
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
90
+ s.specification_version = 2
91
+
92
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
93
+ s.add_runtime_dependency(%q<activerecord>, [">= 0"])
94
+ else
95
+ s.add_dependency(%q<activerecord>, [">= 0"])
96
+ end
97
+ else
98
+ s.add_dependency(%q<activerecord>, [">= 0"])
99
+ end
100
+ end
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+
2
+ require 'has_many_polymorphs'
@@ -0,0 +1,27 @@
1
+
2
+ require 'active_record'
3
+
4
+ RAILS_DEFAULT_LOGGER = nil unless defined? RAILS_DEFAULT_LOGGER
5
+
6
+ require 'has_many_polymorphs/reflection'
7
+ require 'has_many_polymorphs/association'
8
+ require 'has_many_polymorphs/class_methods'
9
+
10
+ require 'has_many_polymorphs/support_methods'
11
+ require 'has_many_polymorphs/base'
12
+
13
+ class ActiveRecord::Base
14
+ extend ActiveRecord::Associations::PolymorphicClassMethods
15
+ end
16
+
17
+ if ENV['HMP_DEBUG'] or ENV['RAILS_ENV'] =~ /development|test/ and ENV['USER'] == 'eweaver'
18
+ require 'has_many_polymorphs/debugging_tools'
19
+ end
20
+
21
+ if defined? Rails and RAILS_ENV and RAILS_ROOT
22
+ _logger_warn "rails environment detected"
23
+ require 'has_many_polymorphs/configuration'
24
+ require 'has_many_polymorphs/autoload'
25
+ end
26
+
27
+ _logger_debug "loaded ok"
@@ -0,0 +1,159 @@
1
+ module ActiveRecord #:nodoc:
2
+ module Associations #:nodoc:
3
+
4
+ class PolymorphicError < ActiveRecordError #:nodoc:
5
+ end
6
+
7
+ class PolymorphicMethodNotSupportedError < ActiveRecordError #:nodoc:
8
+ end
9
+
10
+ # The association class for a <tt>has_many_polymorphs</tt> association.
11
+ class PolymorphicAssociation < HasManyThroughAssociation
12
+
13
+ # Push a record onto the association. Triggers a database load for a uniqueness check only if <tt>:skip_duplicates</tt> is <tt>true</tt>. Return value is undefined.
14
+ def <<(*records)
15
+ return if records.empty?
16
+
17
+ if @reflection.options[:skip_duplicates]
18
+ _logger_debug "Loading instances for polymorphic duplicate push check; use :skip_duplicates => false and perhaps a database constraint to avoid this possible performance issue"
19
+ load_target
20
+ end
21
+
22
+ @reflection.klass.transaction do
23
+ flatten_deeper(records).each do |record|
24
+ if @owner.new_record? or not record.respond_to?(:new_record?) or record.new_record?
25
+ raise PolymorphicError, "You can't associate unsaved records."
26
+ end
27
+ next if @reflection.options[:skip_duplicates] and @target.include? record
28
+ @owner.send(@reflection.through_reflection.name).proxy_target << @reflection.klass.create!(construct_join_attributes(record))
29
+ @target << record if loaded?
30
+ end
31
+ end
32
+
33
+ self
34
+ end
35
+
36
+ alias :push :<<
37
+ alias :concat :<<
38
+
39
+ # Runs a <tt>find</tt> against the association contents, returning the matched records. All regular <tt>find</tt> options except <tt>:include</tt> are supported.
40
+ def find(*args)
41
+ opts = args._extract_options!
42
+ opts.delete :include
43
+ super(*(args + [opts]))
44
+ end
45
+
46
+ def construct_scope
47
+ _logger_warn "Warning; not all usage scenarios for polymorphic scopes are supported yet."
48
+ super
49
+ end
50
+
51
+ # Deletes a record from the association. Return value is undefined.
52
+ def delete(*records)
53
+ records = flatten_deeper(records)
54
+ records.reject! {|record| @target.delete(record) if record.new_record?}
55
+ return if records.empty?
56
+
57
+ @reflection.klass.transaction do
58
+ records.each do |record|
59
+ joins = @reflection.through_reflection.name
60
+ @owner.send(joins).delete(@owner.send(joins).select do |join|
61
+ join.send(@reflection.options[:polymorphic_key]) == record.id and
62
+ join.send(@reflection.options[:polymorphic_type_key]) == "#{record.class.base_class}"
63
+ end)
64
+ @target.delete(record)
65
+ end
66
+ end
67
+ end
68
+
69
+ # Clears all records from the association. Returns an empty array.
70
+ def clear(klass = nil)
71
+ load_target
72
+ return if @target.empty?
73
+
74
+ if klass
75
+ delete(@target.select {|r| r.is_a? klass })
76
+ else
77
+ @owner.send(@reflection.through_reflection.name).clear
78
+ @target.clear
79
+ end
80
+ []
81
+ end
82
+
83
+ protected
84
+
85
+ # undef :sum
86
+ # undef :create!
87
+
88
+ def construct_quoted_owner_attributes(*args) #:nodoc:
89
+ # no access to returning() here? why not?
90
+ type_key = @reflection.options[:foreign_type_key]
91
+ {@reflection.primary_key_name => @owner.id,
92
+ type_key=> (@owner.class.base_class.name if type_key)}
93
+ end
94
+
95
+ def construct_from #:nodoc:
96
+ # build the FROM part of the query, in this case, the polymorphic join table
97
+ @reflection.klass.table_name
98
+ end
99
+
100
+ def construct_owner #:nodoc:
101
+ # the table name for the owner object's class
102
+ @owner.class.table_name
103
+ end
104
+
105
+ def construct_owner_key #:nodoc:
106
+ # the primary key field for the owner object
107
+ @owner.class.primary_key
108
+ end
109
+
110
+ def construct_select(custom_select = nil) #:nodoc:
111
+ # build the select query
112
+ selected = custom_select || @reflection.options[:select]
113
+ end
114
+
115
+ def construct_joins(custom_joins = nil) #:nodoc:
116
+ # build the string of default joins
117
+ "JOIN #{construct_owner} polymorphic_parent ON #{construct_from}.#{@reflection.options[:foreign_key]} = polymorphic_parent.#{construct_owner_key} " +
118
+ @reflection.options[:from].map do |plural|
119
+ klass = plural._as_class
120
+ "LEFT JOIN #{klass.table_name} ON #{construct_from}.#{@reflection.options[:polymorphic_key]} = #{klass.table_name}.#{klass.primary_key} AND #{construct_from}.#{@reflection.options[:polymorphic_type_key]} = #{@reflection.klass.quote_value(klass.base_class.name)}"
121
+ end.uniq.join(" ") + " #{custom_joins}"
122
+ end
123
+
124
+ def construct_conditions #:nodoc:
125
+ # build the fully realized condition string
126
+ conditions = construct_quoted_owner_attributes.map do |field, value|
127
+ "#{construct_from}.#{field} = #{@reflection.klass.quote_value(value)}" if value
128
+ end
129
+ conditions << custom_conditions if custom_conditions
130
+ "(" + conditions.compact.join(') AND (') + ")"
131
+ end
132
+
133
+ def custom_conditions #:nodoc:
134
+ # custom conditions... not as messy as has_many :through because our joins are a little smarter
135
+ if @reflection.options[:conditions]
136
+ "(" + interpolate_sql(@reflection.klass.send(:sanitize_sql, @reflection.options[:conditions])) + ")"
137
+ end
138
+ end
139
+
140
+ alias :construct_owner_attributes :construct_quoted_owner_attributes
141
+ alias :conditions :custom_conditions # XXX possibly not necessary
142
+ alias :sql_conditions :custom_conditions # XXX ditto
143
+
144
+ # construct attributes for join for a particular record
145
+ def construct_join_attributes(record) #:nodoc:
146
+ {@reflection.options[:polymorphic_key] => record.id,
147
+ @reflection.options[:polymorphic_type_key] => "#{record.class.base_class}",
148
+ @reflection.options[:foreign_key] => @owner.id}.merge(@reflection.options[:foreign_type_key] ?
149
+ {@reflection.options[:foreign_type_key] => "#{@owner.class.base_class}"} : {}) # for double-sided relationships
150
+ end
151
+
152
+ def build(attrs = nil) #:nodoc:
153
+ raise PolymorphicMethodNotSupportedError, "You can't associate new records."
154
+ end
155
+
156
+ end
157
+
158
+ end
159
+ end
@@ -0,0 +1,70 @@
1
+
2
+ require 'initializer' unless defined? ::Rails::Initializer
3
+ require 'dispatcher' unless defined? ::ActionController::Dispatcher
4
+
5
+ module HasManyPolymorphs
6
+
7
+ =begin rdoc
8
+ Searches for models that use <tt>has_many_polymorphs</tt> or <tt>acts_as_double_polymorphic_join</tt> and makes sure that they get loaded during app initialization. This ensures that helper methods are injected into the target classes.
9
+
10
+ Note that you can override DEFAULT_OPTIONS via Rails::Configuration#has_many_polymorphs_options. For example, if you need an application extension to be required before has_many_polymorphs loads your models, add an <tt>after_initialize</tt> block in <tt>config/environment.rb</tt> that appends to the <tt>'requirements'</tt> key:
11
+ Rails::Initializer.run do |config|
12
+ # your other configuration here
13
+
14
+ config.after_initialize do
15
+ config.has_many_polymorphs_options['requirements'] << 'lib/my_extension'
16
+ end
17
+ end
18
+
19
+ =end
20
+
21
+ DEFAULT_OPTIONS = {
22
+ :file_pattern => "#{RAILS_ROOT}/app/models/**/*.rb",
23
+ :file_exclusions => ['svn', 'CVS', 'bzr'],
24
+ :methods => ['has_many_polymorphs', 'acts_as_double_polymorphic_join'],
25
+ :requirements => []}
26
+
27
+ mattr_accessor :options
28
+ @@options = HashWithIndifferentAccess.new(DEFAULT_OPTIONS)
29
+
30
+ # Dispatcher callback to load polymorphic relationships from the top down.
31
+ def self.autoload
32
+
33
+ _logger_debug "autoload hook invoked"
34
+
35
+ options[:requirements].each do |requirement|
36
+ _logger_warn "forcing requirement load of #{requirement}"
37
+ require requirement
38
+ end
39
+
40
+ Dir[options[:file_pattern]].each do |filename|
41
+ next if filename =~ /#{options[:file_exclusions].join("|")}/
42
+ open filename do |file|
43
+ if file.grep(/#{options[:methods].join("|")}/).any?
44
+ begin
45
+ model = File.basename(filename)[0..-4].camelize
46
+ _logger_warn "preloading parent model #{model}"
47
+ model.constantize
48
+ rescue Object => e
49
+ _logger_warn "#{model} could not be preloaded: #{e.inspect}"
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ end
57
+
58
+ class Rails::Initializer #:nodoc:
59
+ # Make sure it gets loaded in the console, tests, and migrations
60
+ def after_initialize_with_autoload
61
+ after_initialize_without_autoload
62
+ HasManyPolymorphs.autoload
63
+ end
64
+ alias_method_chain :after_initialize, :autoload
65
+ end
66
+
67
+ Dispatcher.to_prepare(:has_many_polymorphs_autoload) do
68
+ # Make sure it gets loaded in the app
69
+ HasManyPolymorphs.autoload
70
+ end
@@ -0,0 +1,60 @@
1
+
2
+ module ActiveRecord
3
+ class Base
4
+
5
+ class << self
6
+
7
+ # Interprets a polymorphic row from a unified SELECT, returning the appropriate ActiveRecord instance. Overrides ActiveRecord::Base.instantiate_without_callbacks.
8
+ def instantiate_with_polymorphic_checks(record)
9
+ if record['polymorphic_parent_class']
10
+ reflection = record['polymorphic_parent_class'].constantize.reflect_on_association(record['polymorphic_association_id'].to_sym)
11
+ # _logger_debug "Instantiating a polymorphic row for #{record['polymorphic_parent_class']}.reflect_on_association(:#{record['polymorphic_association_id']})"
12
+
13
+ # rewrite the record with the right column names
14
+ table_aliases = reflection.options[:table_aliases].dup
15
+ record = Hash[*table_aliases.keys.map {|key| [key, record[table_aliases[key]]] }.flatten]
16
+
17
+ # find the real child class
18
+ klass = record["#{self.table_name}.#{reflection.options[:polymorphic_type_key]}"].constantize
19
+ if sti_klass = record["#{klass.table_name}.#{klass.inheritance_column}"]
20
+ klass = klass.class_eval do compute_type(sti_klass) end # in case of namespaced STI models
21
+ end
22
+
23
+ # check that the join actually joined to something
24
+ unless (child_id = record["#{self.table_name}.#{reflection.options[:polymorphic_key]}"]) == record["#{klass.table_name}.#{klass.primary_key}"]
25
+ raise ActiveRecord::Associations::PolymorphicError,
26
+ "Referential integrity violation; child <#{klass.name}:#{child_id}> was not found for #{reflection.name.inspect}"
27
+ end
28
+
29
+ # eject the join keys
30
+ # XXX not very readable
31
+ record = Hash[*record._select do |column, value|
32
+ column[/^#{klass.table_name}/]
33
+ end.map do |column, value|
34
+ [column[/\.(.*)/, 1], value]
35
+ end.flatten]
36
+
37
+ # allocate and assign values
38
+ returning(klass.allocate) do |obj|
39
+ obj.instance_variable_set("@attributes", record)
40
+ obj.instance_variable_set("@attributes_cache", Hash.new)
41
+
42
+ if obj.respond_to_without_attributes?(:after_find)
43
+ obj.send(:callback, :after_find)
44
+ end
45
+
46
+ if obj.respond_to_without_attributes?(:after_initialize)
47
+ obj.send(:callback, :after_initialize)
48
+ end
49
+
50
+ end
51
+ else
52
+ instantiate_without_polymorphic_checks(record)
53
+ end
54
+ end
55
+
56
+ alias_method_chain :instantiate, :polymorphic_checks
57
+ end
58
+
59
+ end
60
+ end