activerecord 2.3.18 → 3.2.22

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (454) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1014 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +222 -0
  5. data/examples/performance.rb +100 -126
  6. data/examples/simple.rb +14 -0
  7. data/lib/active_record/aggregations.rb +93 -99
  8. data/lib/active_record/associations/alias_tracker.rb +76 -0
  9. data/lib/active_record/associations/association.rb +247 -0
  10. data/lib/active_record/associations/association_scope.rb +134 -0
  11. data/lib/active_record/associations/belongs_to_association.rb +54 -61
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +17 -59
  13. data/lib/active_record/associations/builder/association.rb +55 -0
  14. data/lib/active_record/associations/builder/belongs_to.rb +88 -0
  15. data/lib/active_record/associations/builder/collection_association.rb +75 -0
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +57 -0
  17. data/lib/active_record/associations/builder/has_many.rb +71 -0
  18. data/lib/active_record/associations/builder/has_one.rb +62 -0
  19. data/lib/active_record/associations/builder/singular_association.rb +32 -0
  20. data/lib/active_record/associations/collection_association.rb +580 -0
  21. data/lib/active_record/associations/collection_proxy.rb +133 -0
  22. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +39 -119
  23. data/lib/active_record/associations/has_many_association.rb +60 -79
  24. data/lib/active_record/associations/has_many_through_association.rb +127 -206
  25. data/lib/active_record/associations/has_one_association.rb +55 -114
  26. data/lib/active_record/associations/has_one_through_association.rb +25 -26
  27. data/lib/active_record/associations/join_dependency/join_association.rb +159 -0
  28. data/lib/active_record/associations/join_dependency/join_base.rb +24 -0
  29. data/lib/active_record/associations/join_dependency/join_part.rb +78 -0
  30. data/lib/active_record/associations/join_dependency.rb +214 -0
  31. data/lib/active_record/associations/join_helper.rb +55 -0
  32. data/lib/active_record/associations/preloader/association.rb +125 -0
  33. data/lib/active_record/associations/preloader/belongs_to.rb +17 -0
  34. data/lib/active_record/associations/preloader/collection_association.rb +24 -0
  35. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +60 -0
  36. data/lib/active_record/associations/preloader/has_many.rb +17 -0
  37. data/lib/active_record/associations/preloader/has_many_through.rb +15 -0
  38. data/lib/active_record/associations/preloader/has_one.rb +23 -0
  39. data/lib/active_record/associations/preloader/has_one_through.rb +9 -0
  40. data/lib/active_record/associations/preloader/singular_association.rb +21 -0
  41. data/lib/active_record/associations/preloader/through_association.rb +67 -0
  42. data/lib/active_record/associations/preloader.rb +181 -0
  43. data/lib/active_record/associations/singular_association.rb +64 -0
  44. data/lib/active_record/associations/through_association.rb +87 -0
  45. data/lib/active_record/associations.rb +693 -1337
  46. data/lib/active_record/attribute_assignment.rb +221 -0
  47. data/lib/active_record/attribute_methods/before_type_cast.rb +31 -0
  48. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +32 -0
  49. data/lib/active_record/attribute_methods/dirty.rb +111 -0
  50. data/lib/active_record/attribute_methods/primary_key.rb +114 -0
  51. data/lib/active_record/attribute_methods/query.rb +39 -0
  52. data/lib/active_record/attribute_methods/read.rb +136 -0
  53. data/lib/active_record/attribute_methods/serialization.rb +120 -0
  54. data/lib/active_record/attribute_methods/time_zone_conversion.rb +65 -0
  55. data/lib/active_record/attribute_methods/write.rb +70 -0
  56. data/lib/active_record/attribute_methods.rb +211 -339
  57. data/lib/active_record/autosave_association.rb +179 -149
  58. data/lib/active_record/base.rb +401 -2907
  59. data/lib/active_record/callbacks.rb +91 -176
  60. data/lib/active_record/coders/yaml_column.rb +41 -0
  61. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +236 -119
  62. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +110 -58
  63. data/lib/active_record/connection_adapters/abstract/database_limits.rb +12 -11
  64. data/lib/active_record/connection_adapters/abstract/database_statements.rb +175 -74
  65. data/lib/active_record/connection_adapters/abstract/query_cache.rb +31 -35
  66. data/lib/active_record/connection_adapters/abstract/quoting.rb +71 -21
  67. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +81 -311
  68. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +194 -78
  69. data/lib/active_record/connection_adapters/abstract_adapter.rb +130 -83
  70. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +676 -0
  71. data/lib/active_record/connection_adapters/column.rb +296 -0
  72. data/lib/active_record/connection_adapters/mysql2_adapter.rb +280 -0
  73. data/lib/active_record/connection_adapters/mysql_adapter.rb +272 -493
  74. data/lib/active_record/connection_adapters/postgresql_adapter.rb +650 -405
  75. data/lib/active_record/connection_adapters/schema_cache.rb +69 -0
  76. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +30 -9
  77. data/lib/active_record/connection_adapters/sqlite_adapter.rb +276 -147
  78. data/lib/active_record/connection_adapters/statement_pool.rb +40 -0
  79. data/lib/active_record/counter_cache.rb +123 -0
  80. data/lib/active_record/dynamic_finder_match.rb +41 -14
  81. data/lib/active_record/dynamic_matchers.rb +84 -0
  82. data/lib/active_record/dynamic_scope_match.rb +13 -15
  83. data/lib/active_record/errors.rb +195 -0
  84. data/lib/active_record/explain.rb +86 -0
  85. data/lib/active_record/explain_subscriber.rb +25 -0
  86. data/lib/active_record/fixtures/file.rb +65 -0
  87. data/lib/active_record/fixtures.rb +695 -770
  88. data/lib/active_record/identity_map.rb +162 -0
  89. data/lib/active_record/inheritance.rb +174 -0
  90. data/lib/active_record/integration.rb +60 -0
  91. data/lib/active_record/locale/en.yml +9 -27
  92. data/lib/active_record/locking/optimistic.rb +76 -73
  93. data/lib/active_record/locking/pessimistic.rb +32 -10
  94. data/lib/active_record/log_subscriber.rb +72 -0
  95. data/lib/active_record/migration/command_recorder.rb +105 -0
  96. data/lib/active_record/migration.rb +415 -205
  97. data/lib/active_record/model_schema.rb +368 -0
  98. data/lib/active_record/nested_attributes.rb +153 -63
  99. data/lib/active_record/observer.rb +27 -103
  100. data/lib/active_record/persistence.rb +376 -0
  101. data/lib/active_record/query_cache.rb +49 -8
  102. data/lib/active_record/querying.rb +58 -0
  103. data/lib/active_record/railtie.rb +131 -0
  104. data/lib/active_record/railties/console_sandbox.rb +6 -0
  105. data/lib/active_record/railties/controller_runtime.rb +49 -0
  106. data/lib/active_record/railties/databases.rake +659 -0
  107. data/lib/active_record/railties/jdbcmysql_error.rb +16 -0
  108. data/lib/active_record/readonly_attributes.rb +26 -0
  109. data/lib/active_record/reflection.rb +269 -120
  110. data/lib/active_record/relation/batches.rb +90 -0
  111. data/lib/active_record/relation/calculations.rb +372 -0
  112. data/lib/active_record/relation/delegation.rb +49 -0
  113. data/lib/active_record/relation/finder_methods.rb +402 -0
  114. data/lib/active_record/relation/predicate_builder.rb +63 -0
  115. data/lib/active_record/relation/query_methods.rb +417 -0
  116. data/lib/active_record/relation/spawn_methods.rb +180 -0
  117. data/lib/active_record/relation.rb +537 -0
  118. data/lib/active_record/result.rb +40 -0
  119. data/lib/active_record/sanitization.rb +194 -0
  120. data/lib/active_record/schema.rb +9 -6
  121. data/lib/active_record/schema_dumper.rb +55 -32
  122. data/lib/active_record/scoping/default.rb +142 -0
  123. data/lib/active_record/scoping/named.rb +200 -0
  124. data/lib/active_record/scoping.rb +152 -0
  125. data/lib/active_record/serialization.rb +8 -91
  126. data/lib/active_record/serializers/xml_serializer.rb +43 -197
  127. data/lib/active_record/session_store.rb +129 -103
  128. data/lib/active_record/store.rb +52 -0
  129. data/lib/active_record/test_case.rb +30 -23
  130. data/lib/active_record/timestamp.rb +95 -52
  131. data/lib/active_record/transactions.rb +212 -66
  132. data/lib/active_record/translation.rb +22 -0
  133. data/lib/active_record/validations/associated.rb +43 -0
  134. data/lib/active_record/validations/uniqueness.rb +180 -0
  135. data/lib/active_record/validations.rb +43 -1106
  136. data/lib/active_record/version.rb +5 -4
  137. data/lib/active_record.rb +121 -48
  138. data/lib/rails/generators/active_record/migration/migration_generator.rb +25 -0
  139. data/lib/rails/generators/active_record/migration/templates/migration.rb +34 -0
  140. data/lib/rails/generators/active_record/migration.rb +15 -0
  141. data/lib/rails/generators/active_record/model/model_generator.rb +47 -0
  142. data/lib/rails/generators/active_record/model/templates/migration.rb +15 -0
  143. data/lib/rails/generators/active_record/model/templates/model.rb +12 -0
  144. data/lib/rails/generators/active_record/model/templates/module.rb +7 -0
  145. data/lib/rails/generators/active_record/observer/observer_generator.rb +15 -0
  146. data/lib/rails/generators/active_record/observer/templates/observer.rb +4 -0
  147. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +25 -0
  148. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +12 -0
  149. data/lib/rails/generators/active_record.rb +25 -0
  150. metadata +187 -363
  151. data/CHANGELOG +0 -5904
  152. data/README +0 -351
  153. data/RUNNING_UNIT_TESTS +0 -36
  154. data/Rakefile +0 -268
  155. data/install.rb +0 -30
  156. data/lib/active_record/association_preload.rb +0 -406
  157. data/lib/active_record/associations/association_collection.rb +0 -533
  158. data/lib/active_record/associations/association_proxy.rb +0 -288
  159. data/lib/active_record/batches.rb +0 -85
  160. data/lib/active_record/calculations.rb +0 -321
  161. data/lib/active_record/dirty.rb +0 -183
  162. data/lib/active_record/named_scope.rb +0 -197
  163. data/lib/active_record/serializers/json_serializer.rb +0 -91
  164. data/lib/activerecord.rb +0 -2
  165. data/test/assets/example.log +0 -1
  166. data/test/assets/flowers.jpg +0 -0
  167. data/test/cases/aaa_create_tables_test.rb +0 -24
  168. data/test/cases/active_schema_test_mysql.rb +0 -122
  169. data/test/cases/active_schema_test_postgresql.rb +0 -24
  170. data/test/cases/adapter_test.rb +0 -144
  171. data/test/cases/aggregations_test.rb +0 -167
  172. data/test/cases/ar_schema_test.rb +0 -32
  173. data/test/cases/associations/belongs_to_associations_test.rb +0 -438
  174. data/test/cases/associations/callbacks_test.rb +0 -161
  175. data/test/cases/associations/cascaded_eager_loading_test.rb +0 -131
  176. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +0 -36
  177. data/test/cases/associations/eager_load_nested_include_test.rb +0 -131
  178. data/test/cases/associations/eager_load_nested_polymorphic_include.rb +0 -19
  179. data/test/cases/associations/eager_singularization_test.rb +0 -145
  180. data/test/cases/associations/eager_test.rb +0 -852
  181. data/test/cases/associations/extension_test.rb +0 -62
  182. data/test/cases/associations/habtm_join_table_test.rb +0 -56
  183. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +0 -827
  184. data/test/cases/associations/has_many_associations_test.rb +0 -1273
  185. data/test/cases/associations/has_many_through_associations_test.rb +0 -360
  186. data/test/cases/associations/has_one_associations_test.rb +0 -330
  187. data/test/cases/associations/has_one_through_associations_test.rb +0 -209
  188. data/test/cases/associations/inner_join_association_test.rb +0 -93
  189. data/test/cases/associations/inverse_associations_test.rb +0 -566
  190. data/test/cases/associations/join_model_test.rb +0 -712
  191. data/test/cases/associations_test.rb +0 -282
  192. data/test/cases/attribute_methods_test.rb +0 -305
  193. data/test/cases/autosave_association_test.rb +0 -1218
  194. data/test/cases/base_test.rb +0 -2166
  195. data/test/cases/batches_test.rb +0 -81
  196. data/test/cases/binary_test.rb +0 -30
  197. data/test/cases/calculations_test.rb +0 -360
  198. data/test/cases/callbacks_observers_test.rb +0 -38
  199. data/test/cases/callbacks_test.rb +0 -438
  200. data/test/cases/class_inheritable_attributes_test.rb +0 -32
  201. data/test/cases/column_alias_test.rb +0 -17
  202. data/test/cases/column_definition_test.rb +0 -70
  203. data/test/cases/connection_pool_test.rb +0 -25
  204. data/test/cases/connection_test_firebird.rb +0 -8
  205. data/test/cases/connection_test_mysql.rb +0 -65
  206. data/test/cases/copy_table_test_sqlite.rb +0 -80
  207. data/test/cases/counter_cache_test.rb +0 -84
  208. data/test/cases/database_statements_test.rb +0 -12
  209. data/test/cases/datatype_test_postgresql.rb +0 -204
  210. data/test/cases/date_time_test.rb +0 -37
  211. data/test/cases/default_test_firebird.rb +0 -16
  212. data/test/cases/defaults_test.rb +0 -111
  213. data/test/cases/deprecated_finder_test.rb +0 -30
  214. data/test/cases/dirty_test.rb +0 -316
  215. data/test/cases/finder_respond_to_test.rb +0 -76
  216. data/test/cases/finder_test.rb +0 -1098
  217. data/test/cases/fixtures_test.rb +0 -661
  218. data/test/cases/helper.rb +0 -68
  219. data/test/cases/i18n_test.rb +0 -46
  220. data/test/cases/inheritance_test.rb +0 -262
  221. data/test/cases/invalid_date_test.rb +0 -24
  222. data/test/cases/json_serialization_test.rb +0 -219
  223. data/test/cases/lifecycle_test.rb +0 -193
  224. data/test/cases/locking_test.rb +0 -350
  225. data/test/cases/method_scoping_test.rb +0 -704
  226. data/test/cases/migration_test.rb +0 -1649
  227. data/test/cases/migration_test_firebird.rb +0 -124
  228. data/test/cases/mixin_test.rb +0 -96
  229. data/test/cases/modules_test.rb +0 -109
  230. data/test/cases/multiple_db_test.rb +0 -85
  231. data/test/cases/named_scope_test.rb +0 -372
  232. data/test/cases/nested_attributes_test.rb +0 -840
  233. data/test/cases/pk_test.rb +0 -119
  234. data/test/cases/pooled_connections_test.rb +0 -103
  235. data/test/cases/query_cache_test.rb +0 -129
  236. data/test/cases/readonly_test.rb +0 -107
  237. data/test/cases/reflection_test.rb +0 -234
  238. data/test/cases/reload_models_test.rb +0 -22
  239. data/test/cases/repair_helper.rb +0 -50
  240. data/test/cases/reserved_word_test_mysql.rb +0 -176
  241. data/test/cases/sanitize_test.rb +0 -25
  242. data/test/cases/schema_authorization_test_postgresql.rb +0 -75
  243. data/test/cases/schema_dumper_test.rb +0 -211
  244. data/test/cases/schema_test_postgresql.rb +0 -178
  245. data/test/cases/serialization_test.rb +0 -47
  246. data/test/cases/sp_test_mysql.rb +0 -16
  247. data/test/cases/synonym_test_oracle.rb +0 -17
  248. data/test/cases/timestamp_test.rb +0 -75
  249. data/test/cases/transactions_test.rb +0 -543
  250. data/test/cases/unconnected_test.rb +0 -32
  251. data/test/cases/validations_i18n_test.rb +0 -925
  252. data/test/cases/validations_test.rb +0 -1684
  253. data/test/cases/xml_serialization_test.rb +0 -240
  254. data/test/cases/yaml_serialization_test.rb +0 -11
  255. data/test/config.rb +0 -5
  256. data/test/connections/jdbc_jdbcderby/connection.rb +0 -18
  257. data/test/connections/jdbc_jdbch2/connection.rb +0 -18
  258. data/test/connections/jdbc_jdbchsqldb/connection.rb +0 -18
  259. data/test/connections/jdbc_jdbcmysql/connection.rb +0 -26
  260. data/test/connections/jdbc_jdbcpostgresql/connection.rb +0 -26
  261. data/test/connections/jdbc_jdbcsqlite3/connection.rb +0 -25
  262. data/test/connections/native_db2/connection.rb +0 -25
  263. data/test/connections/native_firebird/connection.rb +0 -26
  264. data/test/connections/native_frontbase/connection.rb +0 -27
  265. data/test/connections/native_mysql/connection.rb +0 -25
  266. data/test/connections/native_openbase/connection.rb +0 -21
  267. data/test/connections/native_oracle/connection.rb +0 -27
  268. data/test/connections/native_postgresql/connection.rb +0 -21
  269. data/test/connections/native_sqlite/connection.rb +0 -25
  270. data/test/connections/native_sqlite3/connection.rb +0 -25
  271. data/test/connections/native_sqlite3/in_memory_connection.rb +0 -18
  272. data/test/connections/native_sybase/connection.rb +0 -23
  273. data/test/fixtures/accounts.yml +0 -29
  274. data/test/fixtures/all/developers.yml +0 -0
  275. data/test/fixtures/all/people.csv +0 -0
  276. data/test/fixtures/all/tasks.yml +0 -0
  277. data/test/fixtures/author_addresses.yml +0 -5
  278. data/test/fixtures/author_favorites.yml +0 -4
  279. data/test/fixtures/authors.yml +0 -9
  280. data/test/fixtures/binaries.yml +0 -132
  281. data/test/fixtures/books.yml +0 -7
  282. data/test/fixtures/categories/special_categories.yml +0 -9
  283. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +0 -4
  284. data/test/fixtures/categories.yml +0 -14
  285. data/test/fixtures/categories_ordered.yml +0 -7
  286. data/test/fixtures/categories_posts.yml +0 -23
  287. data/test/fixtures/categorizations.yml +0 -17
  288. data/test/fixtures/clubs.yml +0 -6
  289. data/test/fixtures/comments.yml +0 -59
  290. data/test/fixtures/companies.yml +0 -56
  291. data/test/fixtures/computers.yml +0 -4
  292. data/test/fixtures/courses.yml +0 -7
  293. data/test/fixtures/customers.yml +0 -26
  294. data/test/fixtures/developers.yml +0 -21
  295. data/test/fixtures/developers_projects.yml +0 -17
  296. data/test/fixtures/edges.yml +0 -6
  297. data/test/fixtures/entrants.yml +0 -14
  298. data/test/fixtures/faces.yml +0 -11
  299. data/test/fixtures/fk_test_has_fk.yml +0 -3
  300. data/test/fixtures/fk_test_has_pk.yml +0 -2
  301. data/test/fixtures/funny_jokes.yml +0 -10
  302. data/test/fixtures/interests.yml +0 -33
  303. data/test/fixtures/items.yml +0 -4
  304. data/test/fixtures/jobs.yml +0 -7
  305. data/test/fixtures/legacy_things.yml +0 -3
  306. data/test/fixtures/mateys.yml +0 -4
  307. data/test/fixtures/member_types.yml +0 -6
  308. data/test/fixtures/members.yml +0 -6
  309. data/test/fixtures/memberships.yml +0 -20
  310. data/test/fixtures/men.yml +0 -5
  311. data/test/fixtures/minimalistics.yml +0 -2
  312. data/test/fixtures/mixed_case_monkeys.yml +0 -6
  313. data/test/fixtures/mixins.yml +0 -29
  314. data/test/fixtures/movies.yml +0 -7
  315. data/test/fixtures/naked/csv/accounts.csv +0 -1
  316. data/test/fixtures/naked/yml/accounts.yml +0 -1
  317. data/test/fixtures/naked/yml/companies.yml +0 -1
  318. data/test/fixtures/naked/yml/courses.yml +0 -1
  319. data/test/fixtures/organizations.yml +0 -5
  320. data/test/fixtures/owners.yml +0 -7
  321. data/test/fixtures/parrots.yml +0 -27
  322. data/test/fixtures/parrots_pirates.yml +0 -7
  323. data/test/fixtures/people.yml +0 -15
  324. data/test/fixtures/pets.yml +0 -14
  325. data/test/fixtures/pirates.yml +0 -9
  326. data/test/fixtures/polymorphic_designs.yml +0 -19
  327. data/test/fixtures/polymorphic_prices.yml +0 -19
  328. data/test/fixtures/posts.yml +0 -52
  329. data/test/fixtures/price_estimates.yml +0 -7
  330. data/test/fixtures/projects.yml +0 -7
  331. data/test/fixtures/readers.yml +0 -9
  332. data/test/fixtures/references.yml +0 -17
  333. data/test/fixtures/reserved_words/distinct.yml +0 -5
  334. data/test/fixtures/reserved_words/distincts_selects.yml +0 -11
  335. data/test/fixtures/reserved_words/group.yml +0 -14
  336. data/test/fixtures/reserved_words/select.yml +0 -8
  337. data/test/fixtures/reserved_words/values.yml +0 -7
  338. data/test/fixtures/ships.yml +0 -5
  339. data/test/fixtures/sponsors.yml +0 -9
  340. data/test/fixtures/subscribers.yml +0 -7
  341. data/test/fixtures/subscriptions.yml +0 -12
  342. data/test/fixtures/taggings.yml +0 -28
  343. data/test/fixtures/tags.yml +0 -7
  344. data/test/fixtures/tasks.yml +0 -7
  345. data/test/fixtures/tees.yml +0 -4
  346. data/test/fixtures/ties.yml +0 -4
  347. data/test/fixtures/topics.yml +0 -42
  348. data/test/fixtures/toys.yml +0 -4
  349. data/test/fixtures/treasures.yml +0 -10
  350. data/test/fixtures/vertices.yml +0 -4
  351. data/test/fixtures/warehouse-things.yml +0 -3
  352. data/test/fixtures/zines.yml +0 -5
  353. data/test/migrations/broken/100_migration_that_raises_exception.rb +0 -10
  354. data/test/migrations/decimal/1_give_me_big_numbers.rb +0 -15
  355. data/test/migrations/duplicate/1_people_have_last_names.rb +0 -9
  356. data/test/migrations/duplicate/2_we_need_reminders.rb +0 -12
  357. data/test/migrations/duplicate/3_foo.rb +0 -7
  358. data/test/migrations/duplicate/3_innocent_jointable.rb +0 -12
  359. data/test/migrations/duplicate_names/20080507052938_chunky.rb +0 -7
  360. data/test/migrations/duplicate_names/20080507053028_chunky.rb +0 -7
  361. data/test/migrations/interleaved/pass_1/3_innocent_jointable.rb +0 -12
  362. data/test/migrations/interleaved/pass_2/1_people_have_last_names.rb +0 -9
  363. data/test/migrations/interleaved/pass_2/3_innocent_jointable.rb +0 -12
  364. data/test/migrations/interleaved/pass_3/1_people_have_last_names.rb +0 -9
  365. data/test/migrations/interleaved/pass_3/2_i_raise_on_down.rb +0 -8
  366. data/test/migrations/interleaved/pass_3/3_innocent_jointable.rb +0 -12
  367. data/test/migrations/missing/1000_people_have_middle_names.rb +0 -9
  368. data/test/migrations/missing/1_people_have_last_names.rb +0 -9
  369. data/test/migrations/missing/3_we_need_reminders.rb +0 -12
  370. data/test/migrations/missing/4_innocent_jointable.rb +0 -12
  371. data/test/migrations/valid/1_people_have_last_names.rb +0 -9
  372. data/test/migrations/valid/2_we_need_reminders.rb +0 -12
  373. data/test/migrations/valid/3_innocent_jointable.rb +0 -12
  374. data/test/models/author.rb +0 -151
  375. data/test/models/auto_id.rb +0 -4
  376. data/test/models/binary.rb +0 -2
  377. data/test/models/bird.rb +0 -9
  378. data/test/models/book.rb +0 -4
  379. data/test/models/categorization.rb +0 -5
  380. data/test/models/category.rb +0 -34
  381. data/test/models/citation.rb +0 -6
  382. data/test/models/club.rb +0 -13
  383. data/test/models/column_name.rb +0 -3
  384. data/test/models/comment.rb +0 -29
  385. data/test/models/company.rb +0 -173
  386. data/test/models/company_in_module.rb +0 -78
  387. data/test/models/computer.rb +0 -3
  388. data/test/models/contact.rb +0 -16
  389. data/test/models/contract.rb +0 -5
  390. data/test/models/course.rb +0 -3
  391. data/test/models/customer.rb +0 -73
  392. data/test/models/default.rb +0 -2
  393. data/test/models/developer.rb +0 -101
  394. data/test/models/edge.rb +0 -5
  395. data/test/models/entrant.rb +0 -3
  396. data/test/models/essay.rb +0 -3
  397. data/test/models/event.rb +0 -3
  398. data/test/models/event_author.rb +0 -8
  399. data/test/models/face.rb +0 -7
  400. data/test/models/guid.rb +0 -2
  401. data/test/models/interest.rb +0 -5
  402. data/test/models/invoice.rb +0 -4
  403. data/test/models/item.rb +0 -7
  404. data/test/models/job.rb +0 -5
  405. data/test/models/joke.rb +0 -3
  406. data/test/models/keyboard.rb +0 -3
  407. data/test/models/legacy_thing.rb +0 -3
  408. data/test/models/line_item.rb +0 -3
  409. data/test/models/man.rb +0 -9
  410. data/test/models/matey.rb +0 -4
  411. data/test/models/member.rb +0 -12
  412. data/test/models/member_detail.rb +0 -5
  413. data/test/models/member_type.rb +0 -3
  414. data/test/models/membership.rb +0 -9
  415. data/test/models/minimalistic.rb +0 -2
  416. data/test/models/mixed_case_monkey.rb +0 -3
  417. data/test/models/movie.rb +0 -5
  418. data/test/models/order.rb +0 -4
  419. data/test/models/organization.rb +0 -6
  420. data/test/models/owner.rb +0 -5
  421. data/test/models/parrot.rb +0 -22
  422. data/test/models/person.rb +0 -16
  423. data/test/models/pet.rb +0 -5
  424. data/test/models/pirate.rb +0 -80
  425. data/test/models/polymorphic_design.rb +0 -3
  426. data/test/models/polymorphic_price.rb +0 -3
  427. data/test/models/post.rb +0 -102
  428. data/test/models/price_estimate.rb +0 -3
  429. data/test/models/project.rb +0 -30
  430. data/test/models/reader.rb +0 -4
  431. data/test/models/reference.rb +0 -4
  432. data/test/models/reply.rb +0 -46
  433. data/test/models/ship.rb +0 -19
  434. data/test/models/ship_part.rb +0 -7
  435. data/test/models/sponsor.rb +0 -4
  436. data/test/models/subject.rb +0 -4
  437. data/test/models/subscriber.rb +0 -8
  438. data/test/models/subscription.rb +0 -4
  439. data/test/models/tag.rb +0 -7
  440. data/test/models/tagging.rb +0 -10
  441. data/test/models/task.rb +0 -3
  442. data/test/models/tee.rb +0 -4
  443. data/test/models/tie.rb +0 -4
  444. data/test/models/topic.rb +0 -80
  445. data/test/models/toy.rb +0 -6
  446. data/test/models/treasure.rb +0 -8
  447. data/test/models/vertex.rb +0 -9
  448. data/test/models/warehouse_thing.rb +0 -5
  449. data/test/models/zine.rb +0 -3
  450. data/test/schema/mysql_specific_schema.rb +0 -31
  451. data/test/schema/postgresql_specific_schema.rb +0 -114
  452. data/test/schema/schema.rb +0 -550
  453. data/test/schema/schema2.rb +0 -6
  454. data/test/schema/sqlite_specific_schema.rb +0 -25
@@ -1,406 +0,0 @@
1
- module ActiveRecord
2
- # See ActiveRecord::AssociationPreload::ClassMethods for documentation.
3
- module AssociationPreload #:nodoc:
4
- def self.included(base)
5
- base.extend(ClassMethods)
6
- end
7
-
8
- # Implements the details of eager loading of ActiveRecord associations.
9
- # Application developers should not use this module directly.
10
- #
11
- # ActiveRecord::Base is extended with this module. The source code in
12
- # ActiveRecord::Base references methods defined in this module.
13
- #
14
- # Note that 'eager loading' and 'preloading' are actually the same thing.
15
- # However, there are two different eager loading strategies.
16
- #
17
- # The first one is by using table joins. This was only strategy available
18
- # prior to Rails 2.1. Suppose that you have an Author model with columns
19
- # 'name' and 'age', and a Book model with columns 'name' and 'sales'. Using
20
- # this strategy, ActiveRecord would try to retrieve all data for an author
21
- # and all of its books via a single query:
22
- #
23
- # SELECT * FROM authors
24
- # LEFT OUTER JOIN books ON authors.id = books.id
25
- # WHERE authors.name = 'Ken Akamatsu'
26
- #
27
- # However, this could result in many rows that contain redundant data. After
28
- # having received the first row, we already have enough data to instantiate
29
- # the Author object. In all subsequent rows, only the data for the joined
30
- # 'books' table is useful; the joined 'authors' data is just redundant, and
31
- # processing this redundant data takes memory and CPU time. The problem
32
- # quickly becomes worse and worse as the level of eager loading increases
33
- # (i.e. if ActiveRecord is to eager load the associations' assocations as
34
- # well).
35
- #
36
- # The second strategy is to use multiple database queries, one for each
37
- # level of association. Since Rails 2.1, this is the default strategy. In
38
- # situations where a table join is necessary (e.g. when the +:conditions+
39
- # option references an association's column), it will fallback to the table
40
- # join strategy.
41
- #
42
- # See also ActiveRecord::Associations::ClassMethods, which explains eager
43
- # loading in a more high-level (application developer-friendly) manner.
44
- module ClassMethods
45
- protected
46
-
47
- # Eager loads the named associations for the given ActiveRecord record(s).
48
- #
49
- # In this description, 'association name' shall refer to the name passed
50
- # to an association creation method. For example, a model that specifies
51
- # <tt>belongs_to :author</tt>, <tt>has_many :buyers</tt> has association
52
- # names +:author+ and +:buyers+.
53
- #
54
- # == Parameters
55
- # +records+ is an array of ActiveRecord::Base. This array needs not be flat,
56
- # i.e. +records+ itself may also contain arrays of records. In any case,
57
- # +preload_associations+ will preload the associations all records by
58
- # flattening +records+.
59
- #
60
- # +associations+ specifies one or more associations that you want to
61
- # preload. It may be:
62
- # - a Symbol or a String which specifies a single association name. For
63
- # example, specifiying +:books+ allows this method to preload all books
64
- # for an Author.
65
- # - an Array which specifies multiple association names. This array
66
- # is processed recursively. For example, specifying <tt>[:avatar, :books]</tt>
67
- # allows this method to preload an author's avatar as well as all of his
68
- # books.
69
- # - a Hash which specifies multiple association names, as well as
70
- # association names for the to-be-preloaded association objects. For
71
- # example, specifying <tt>{ :author => :avatar }</tt> will preload a
72
- # book's author, as well as that author's avatar.
73
- #
74
- # +:associations+ has the same format as the +:include+ option for
75
- # <tt>ActiveRecord::Base.find</tt>. So +associations+ could look like this:
76
- #
77
- # :books
78
- # [ :books, :author ]
79
- # { :author => :avatar }
80
- # [ :books, { :author => :avatar } ]
81
- #
82
- # +preload_options+ contains options that will be passed to ActiveRecord#find
83
- # (which is called under the hood for preloading records). But it is passed
84
- # only one level deep in the +associations+ argument, i.e. it's not passed
85
- # to the child associations when +associations+ is a Hash.
86
- def preload_associations(records, associations, preload_options={})
87
- records = [records].flatten.compact.uniq
88
- return if records.empty?
89
- case associations
90
- when Array then associations.each {|association| preload_associations(records, association, preload_options)}
91
- when Symbol, String then preload_one_association(records, associations.to_sym, preload_options)
92
- when Hash then
93
- associations.each do |parent, child|
94
- raise "parent must be an association name" unless parent.is_a?(String) || parent.is_a?(Symbol)
95
- preload_associations(records, parent, preload_options)
96
- reflection = reflections[parent]
97
- parents = records.map {|record| record.send(reflection.name)}.flatten.compact
98
- unless parents.empty?
99
- parents.first.class.preload_associations(parents, child)
100
- end
101
- end
102
- end
103
- end
104
-
105
- private
106
-
107
- # Preloads a specific named association for the given records. This is
108
- # called by +preload_associations+ as its base case.
109
- def preload_one_association(records, association, preload_options={})
110
- class_to_reflection = {}
111
- # Not all records have the same class, so group then preload
112
- # group on the reflection itself so that if various subclass share the same association then we do not split them
113
- # unnecessarily
114
- records.group_by {|record| class_to_reflection[record.class] ||= record.class.reflections[association]}.each do |reflection, records|
115
- raise ConfigurationError, "Association named '#{ association }' was not found; perhaps you misspelled it?" unless reflection
116
-
117
- # 'reflection.macro' can return 'belongs_to', 'has_many', etc. Thus,
118
- # the following could call 'preload_belongs_to_association',
119
- # 'preload_has_many_association', etc.
120
- send("preload_#{reflection.macro}_association", records, reflection, preload_options)
121
- end
122
- end
123
-
124
- def add_preloaded_records_to_collection(parent_records, reflection_name, associated_record)
125
- parent_records.each do |parent_record|
126
- association_proxy = parent_record.send(reflection_name)
127
- association_proxy.loaded
128
- association_proxy.target.push(*[associated_record].flatten)
129
- association_proxy.__send__(:set_inverse_instance, associated_record, parent_record)
130
- end
131
- end
132
-
133
- def add_preloaded_record_to_collection(parent_records, reflection_name, associated_record)
134
- parent_records.each do |parent_record|
135
- parent_record.send("set_#{reflection_name}_target", associated_record)
136
- end
137
- end
138
-
139
- def set_association_collection_records(id_to_record_map, reflection_name, associated_records, key)
140
- associated_records.each do |associated_record|
141
- mapped_records = id_to_record_map[associated_record[key].to_s]
142
- add_preloaded_records_to_collection(mapped_records, reflection_name, associated_record)
143
- end
144
- end
145
-
146
- def set_association_single_records(id_to_record_map, reflection_name, associated_records, key)
147
- seen_keys = {}
148
- associated_records.each do |associated_record|
149
- #this is a has_one or belongs_to: there should only be one record.
150
- #Unfortunately we can't (in portable way) ask the database for 'all records where foo_id in (x,y,z), but please
151
- # only one row per distinct foo_id' so this where we enforce that
152
- next if seen_keys[associated_record[key].to_s]
153
- seen_keys[associated_record[key].to_s] = true
154
- mapped_records = id_to_record_map[associated_record[key].to_s]
155
- mapped_records.each do |mapped_record|
156
- association_proxy = mapped_record.send("set_#{reflection_name}_target", associated_record)
157
- association_proxy.__send__(:set_inverse_instance, associated_record, mapped_record)
158
- end
159
- end
160
-
161
- id_to_record_map.each do |id, records|
162
- next if seen_keys.include?(id.to_s)
163
- records.each {|record| record.send("set_#{reflection_name}_target", nil) }
164
- end
165
- end
166
-
167
- # Given a collection of ActiveRecord objects, constructs a Hash which maps
168
- # the objects' IDs to the relevant objects. Returns a 2-tuple
169
- # <tt>(id_to_record_map, ids)</tt> where +id_to_record_map+ is the Hash,
170
- # and +ids+ is an Array of record IDs.
171
- def construct_id_map(records, primary_key=nil)
172
- id_to_record_map = {}
173
- ids = []
174
- records.each do |record|
175
- primary_key ||= record.class.primary_key
176
- ids << record[primary_key]
177
- mapped_records = (id_to_record_map[ids.last.to_s] ||= [])
178
- mapped_records << record
179
- end
180
- ids.uniq!
181
- return id_to_record_map, ids
182
- end
183
-
184
- def preload_has_and_belongs_to_many_association(records, reflection, preload_options={})
185
- table_name = reflection.klass.quoted_table_name
186
- id_to_record_map, ids = construct_id_map(records)
187
- records.each {|record| record.send(reflection.name).loaded}
188
- options = reflection.options
189
-
190
- conditions = "t0.#{reflection.primary_key_name} #{in_or_equals_for_ids(ids)}"
191
- conditions << append_conditions(reflection, preload_options)
192
-
193
- associated_records = reflection.klass.with_exclusive_scope do
194
- reflection.klass.find(:all, :conditions => [conditions, ids],
195
- :include => options[:include],
196
- :joins => "INNER JOIN #{connection.quote_table_name options[:join_table]} t0 ON #{reflection.klass.quoted_table_name}.#{reflection.klass.primary_key} = t0.#{reflection.association_foreign_key}",
197
- :select => "#{options[:select] || table_name+'.*'}, t0.#{reflection.primary_key_name} as the_parent_record_id",
198
- :order => options[:order])
199
- end
200
- set_association_collection_records(id_to_record_map, reflection.name, associated_records, 'the_parent_record_id')
201
- end
202
-
203
- def preload_has_one_association(records, reflection, preload_options={})
204
- return if records.first.send("loaded_#{reflection.name}?")
205
- id_to_record_map, ids = construct_id_map(records, reflection.options[:primary_key])
206
- options = reflection.options
207
- records.each {|record| record.send("set_#{reflection.name}_target", nil)}
208
- if options[:through]
209
- through_records = preload_through_records(records, reflection, options[:through])
210
- through_reflection = reflections[options[:through]]
211
- through_primary_key = through_reflection.primary_key_name
212
- unless through_records.empty?
213
- source = reflection.source_reflection.name
214
- through_records.first.class.preload_associations(through_records, source)
215
- if through_reflection.macro == :belongs_to
216
- rev_id_to_record_map, rev_ids = construct_id_map(records, through_primary_key)
217
- rev_primary_key = through_reflection.klass.primary_key
218
- through_records.each do |through_record|
219
- add_preloaded_record_to_collection(rev_id_to_record_map[through_record[rev_primary_key].to_s],
220
- reflection.name, through_record.send(source))
221
- end
222
- else
223
- through_records.each do |through_record|
224
- add_preloaded_record_to_collection(id_to_record_map[through_record[through_primary_key].to_s],
225
- reflection.name, through_record.send(source))
226
- end
227
- end
228
- end
229
- else
230
- set_association_single_records(id_to_record_map, reflection.name, find_associated_records(ids, reflection, preload_options), reflection.primary_key_name)
231
- end
232
- end
233
-
234
- def preload_has_many_association(records, reflection, preload_options={})
235
- return if records.first.send(reflection.name).loaded?
236
- options = reflection.options
237
-
238
- primary_key_name = reflection.through_reflection_primary_key_name
239
- id_to_record_map, ids = construct_id_map(records, primary_key_name || reflection.options[:primary_key])
240
- records.each {|record| record.send(reflection.name).loaded}
241
-
242
- if options[:through]
243
- through_records = preload_through_records(records, reflection, options[:through])
244
- through_reflection = reflections[options[:through]]
245
- unless through_records.empty?
246
- source = reflection.source_reflection.name
247
- through_records.first.class.preload_associations(through_records, source, options)
248
- through_records.each do |through_record|
249
- through_record_id = through_record[reflection.through_reflection_primary_key].to_s
250
- add_preloaded_records_to_collection(id_to_record_map[through_record_id], reflection.name, through_record.send(source))
251
- end
252
- end
253
-
254
- else
255
- set_association_collection_records(id_to_record_map, reflection.name, find_associated_records(ids, reflection, preload_options),
256
- reflection.primary_key_name)
257
- end
258
- end
259
-
260
- def preload_through_records(records, reflection, through_association)
261
- through_reflection = reflections[through_association]
262
- through_primary_key = through_reflection.primary_key_name
263
-
264
- if reflection.options[:source_type]
265
- interface = reflection.source_reflection.options[:foreign_type]
266
- preload_options = {:conditions => ["#{connection.quote_column_name interface} = ?", reflection.options[:source_type]]}
267
-
268
- records.compact!
269
- records.first.class.preload_associations(records, through_association, preload_options)
270
-
271
- # Dont cache the association - we would only be caching a subset
272
- through_records = []
273
- records.each do |record|
274
- proxy = record.send(through_association)
275
-
276
- if proxy.respond_to?(:target)
277
- through_records << proxy.target
278
- proxy.reset
279
- else # this is a has_one :through reflection
280
- through_records << proxy if proxy
281
- end
282
- end
283
- through_records.flatten!
284
- else
285
- options = {}
286
- options[:include] = reflection.options[:include] || reflection.options[:source] if reflection.options[:conditions] || reflection.options[:order]
287
- options[:order] = reflection.options[:order]
288
- options[:conditions] = reflection.options[:conditions]
289
- records.first.class.preload_associations(records, through_association, options)
290
- through_records = records.map {|record| record.send(through_association)}.flatten
291
- end
292
- through_records.compact!
293
- through_records
294
- end
295
-
296
- def preload_belongs_to_association(records, reflection, preload_options={})
297
- return if records.first.send("loaded_#{reflection.name}?")
298
- options = reflection.options
299
- primary_key_name = reflection.primary_key_name
300
-
301
- if options[:polymorphic]
302
- polymorph_type = options[:foreign_type]
303
- klasses_and_ids = {}
304
-
305
- # Construct a mapping from klass to a list of ids to load and a mapping of those ids back to their parent_records
306
- records.each do |record|
307
- if klass = record.send(polymorph_type)
308
- klass_id = record.send(primary_key_name)
309
- if klass_id
310
- id_map = klasses_and_ids[klass] ||= {}
311
- id_list_for_klass_id = (id_map[klass_id.to_s] ||= [])
312
- id_list_for_klass_id << record
313
- end
314
- end
315
- end
316
- klasses_and_ids = klasses_and_ids.to_a
317
- else
318
- id_map = {}
319
- records.each do |record|
320
- key = record.send(primary_key_name)
321
- if key
322
- mapped_records = (id_map[key.to_s] ||= [])
323
- mapped_records << record
324
- end
325
- end
326
- klasses_and_ids = [[reflection.klass.name, id_map]]
327
- end
328
-
329
- klasses_and_ids.each do |klass_and_id|
330
- klass_name, id_map = *klass_and_id
331
- next if id_map.empty?
332
- klass = klass_name.constantize
333
-
334
- table_name = klass.quoted_table_name
335
- primary_key = reflection.options[:primary_key] || klass.primary_key
336
- column_type = klass.columns.detect{|c| c.name == primary_key}.type
337
- ids = id_map.keys.map do |id|
338
- if column_type == :integer
339
- id.to_i
340
- elsif column_type == :float
341
- id.to_f
342
- else
343
- id
344
- end
345
- end
346
- conditions = "#{table_name}.#{connection.quote_column_name(primary_key)} #{in_or_equals_for_ids(ids)}"
347
- conditions << append_conditions(reflection, preload_options)
348
- associated_records = klass.with_exclusive_scope do
349
- klass.find(:all, :conditions => [conditions, ids],
350
- :include => options[:include],
351
- :select => options[:select],
352
- :joins => options[:joins],
353
- :order => options[:order])
354
- end
355
- set_association_single_records(id_map, reflection.name, associated_records, primary_key)
356
- end
357
- end
358
-
359
- def find_associated_records(ids, reflection, preload_options)
360
- options = reflection.options
361
- table_name = reflection.klass.quoted_table_name
362
-
363
- if interface = reflection.options[:as]
364
- parent_type = if reflection.active_record.abstract_class?
365
- self.base_class.sti_name
366
- else
367
- reflection.active_record.sti_name
368
- end
369
-
370
- conditions = "#{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_id"} #{in_or_equals_for_ids(ids)} and #{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_type"} = '#{parent_type}'"
371
- else
372
- foreign_key = reflection.primary_key_name
373
- conditions = "#{reflection.klass.quoted_table_name}.#{foreign_key} #{in_or_equals_for_ids(ids)}"
374
- end
375
-
376
- conditions << append_conditions(reflection, preload_options)
377
-
378
- reflection.klass.with_exclusive_scope do
379
- reflection.klass.find(:all,
380
- :select => (preload_options[:select] || options[:select] || "#{table_name}.*"),
381
- :include => preload_options[:include] || options[:include],
382
- :conditions => [conditions, ids],
383
- :joins => options[:joins],
384
- :group => preload_options[:group] || options[:group],
385
- :order => preload_options[:order] || options[:order])
386
- end
387
- end
388
-
389
-
390
- def interpolate_sql_for_preload(sql)
391
- instance_eval("%@#{sql.gsub('@', '\@')}@")
392
- end
393
-
394
- def append_conditions(reflection, preload_options)
395
- sql = ""
396
- sql << " AND (#{interpolate_sql_for_preload(reflection.sanitized_conditions)})" if reflection.sanitized_conditions
397
- sql << " AND (#{sanitize_sql preload_options[:conditions]})" if preload_options[:conditions]
398
- sql
399
- end
400
-
401
- def in_or_equals_for_ids(ids)
402
- ids.size > 1 ? "IN (?)" : "= ?"
403
- end
404
- end
405
- end
406
- end