activerecord 2.3.18 → 3.0.0.beta

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 (378) hide show
  1. data/CHANGELOG +105 -34
  2. data/examples/performance.rb +3 -39
  3. data/examples/simple.rb +14 -0
  4. data/lib/active_record.rb +81 -47
  5. data/lib/active_record/aggregations.rb +1 -3
  6. data/lib/active_record/association_preload.rb +39 -54
  7. data/lib/active_record/associations.rb +262 -419
  8. data/lib/active_record/associations/association_collection.rb +85 -100
  9. data/lib/active_record/associations/association_proxy.rb +20 -18
  10. data/lib/active_record/associations/belongs_to_association.rb +8 -8
  11. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +13 -35
  12. data/lib/active_record/associations/has_many_association.rb +11 -19
  13. data/lib/active_record/associations/has_many_through_association.rb +30 -183
  14. data/lib/active_record/associations/has_one_association.rb +10 -10
  15. data/lib/active_record/associations/has_one_through_association.rb +13 -11
  16. data/lib/active_record/associations/through_association_scope.rb +153 -0
  17. data/lib/active_record/attribute_methods.rb +17 -370
  18. data/lib/active_record/attribute_methods/before_type_cast.rb +33 -0
  19. data/lib/active_record/attribute_methods/dirty.rb +87 -0
  20. data/lib/active_record/attribute_methods/primary_key.rb +44 -0
  21. data/lib/active_record/attribute_methods/query.rb +37 -0
  22. data/lib/active_record/attribute_methods/read.rb +116 -0
  23. data/lib/active_record/attribute_methods/time_zone_conversion.rb +60 -0
  24. data/lib/active_record/attribute_methods/write.rb +37 -0
  25. data/lib/active_record/autosave_association.rb +20 -41
  26. data/lib/active_record/base.rb +357 -1180
  27. data/lib/active_record/batches.rb +10 -16
  28. data/lib/active_record/callbacks.rb +66 -126
  29. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +17 -13
  30. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +5 -25
  31. data/lib/active_record/connection_adapters/abstract/database_statements.rb +4 -43
  32. data/lib/active_record/connection_adapters/abstract/query_cache.rb +3 -2
  33. data/lib/active_record/connection_adapters/abstract/quoting.rb +15 -4
  34. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +1 -1
  35. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +18 -72
  36. data/lib/active_record/connection_adapters/abstract_adapter.rb +16 -49
  37. data/lib/active_record/connection_adapters/mysql_adapter.rb +15 -27
  38. data/lib/active_record/connection_adapters/postgresql_adapter.rb +84 -46
  39. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +9 -3
  40. data/lib/active_record/connection_adapters/sqlite_adapter.rb +34 -65
  41. data/lib/active_record/fixtures.rb +21 -25
  42. data/lib/active_record/locale/en.yml +9 -27
  43. data/lib/active_record/locking/optimistic.rb +16 -48
  44. data/lib/active_record/migration.rb +59 -46
  45. data/lib/active_record/named_scope.rb +85 -92
  46. data/lib/active_record/nested_attributes.rb +18 -24
  47. data/lib/active_record/observer.rb +18 -94
  48. data/lib/active_record/railtie.rb +83 -0
  49. data/lib/active_record/railties/controller_runtime.rb +38 -0
  50. data/lib/active_record/railties/databases.rake +477 -0
  51. data/lib/active_record/railties/subscriber.rb +27 -0
  52. data/lib/active_record/reflection.rb +2 -15
  53. data/lib/active_record/relation.rb +339 -0
  54. data/lib/active_record/relation/calculations.rb +259 -0
  55. data/lib/active_record/relation/finder_methods.rb +315 -0
  56. data/lib/active_record/relation/predicate_builder.rb +46 -0
  57. data/lib/active_record/relation/query_methods.rb +218 -0
  58. data/lib/active_record/relation/spawn_methods.rb +102 -0
  59. data/lib/active_record/schema_dumper.rb +10 -6
  60. data/lib/active_record/serialization.rb +31 -74
  61. data/lib/active_record/serializers/xml_serializer.rb +33 -121
  62. data/lib/active_record/session_store.rb +1 -9
  63. data/lib/active_record/test_case.rb +1 -3
  64. data/lib/active_record/timestamp.rb +7 -5
  65. data/lib/active_record/transactions.rb +9 -9
  66. data/lib/active_record/validations.rb +51 -1100
  67. data/lib/active_record/validations/associated.rb +47 -0
  68. data/lib/active_record/validations/uniqueness.rb +181 -0
  69. data/lib/active_record/version.rb +3 -3
  70. data/lib/generators/active_record.rb +30 -0
  71. data/lib/generators/active_record/migration/migration_generator.rb +25 -0
  72. data/lib/generators/active_record/migration/templates/migration.rb +11 -0
  73. data/lib/generators/active_record/model/model_generator.rb +33 -0
  74. data/lib/generators/active_record/model/templates/migration.rb +16 -0
  75. data/lib/generators/active_record/model/templates/model.rb +5 -0
  76. data/lib/generators/active_record/observer/observer_generator.rb +15 -0
  77. data/lib/generators/active_record/observer/templates/observer.rb +2 -0
  78. data/lib/generators/active_record/session_migration/session_migration_generator.rb +24 -0
  79. data/lib/generators/active_record/session_migration/templates/migration.rb +16 -0
  80. metadata +67 -325
  81. data/RUNNING_UNIT_TESTS +0 -36
  82. data/Rakefile +0 -268
  83. data/install.rb +0 -30
  84. data/lib/active_record/calculations.rb +0 -321
  85. data/lib/active_record/connection_adapters/abstract/database_limits.rb +0 -57
  86. data/lib/active_record/dirty.rb +0 -183
  87. data/lib/active_record/serializers/json_serializer.rb +0 -91
  88. data/lib/activerecord.rb +0 -2
  89. data/test/assets/example.log +0 -1
  90. data/test/assets/flowers.jpg +0 -0
  91. data/test/cases/aaa_create_tables_test.rb +0 -24
  92. data/test/cases/active_schema_test_mysql.rb +0 -122
  93. data/test/cases/active_schema_test_postgresql.rb +0 -24
  94. data/test/cases/adapter_test.rb +0 -144
  95. data/test/cases/aggregations_test.rb +0 -167
  96. data/test/cases/ar_schema_test.rb +0 -32
  97. data/test/cases/associations/belongs_to_associations_test.rb +0 -438
  98. data/test/cases/associations/callbacks_test.rb +0 -161
  99. data/test/cases/associations/cascaded_eager_loading_test.rb +0 -131
  100. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +0 -36
  101. data/test/cases/associations/eager_load_nested_include_test.rb +0 -131
  102. data/test/cases/associations/eager_load_nested_polymorphic_include.rb +0 -19
  103. data/test/cases/associations/eager_singularization_test.rb +0 -145
  104. data/test/cases/associations/eager_test.rb +0 -852
  105. data/test/cases/associations/extension_test.rb +0 -62
  106. data/test/cases/associations/habtm_join_table_test.rb +0 -56
  107. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +0 -827
  108. data/test/cases/associations/has_many_associations_test.rb +0 -1273
  109. data/test/cases/associations/has_many_through_associations_test.rb +0 -360
  110. data/test/cases/associations/has_one_associations_test.rb +0 -330
  111. data/test/cases/associations/has_one_through_associations_test.rb +0 -209
  112. data/test/cases/associations/inner_join_association_test.rb +0 -93
  113. data/test/cases/associations/inverse_associations_test.rb +0 -566
  114. data/test/cases/associations/join_model_test.rb +0 -712
  115. data/test/cases/associations_test.rb +0 -282
  116. data/test/cases/attribute_methods_test.rb +0 -305
  117. data/test/cases/autosave_association_test.rb +0 -1218
  118. data/test/cases/base_test.rb +0 -2166
  119. data/test/cases/batches_test.rb +0 -81
  120. data/test/cases/binary_test.rb +0 -30
  121. data/test/cases/calculations_test.rb +0 -360
  122. data/test/cases/callbacks_observers_test.rb +0 -38
  123. data/test/cases/callbacks_test.rb +0 -438
  124. data/test/cases/class_inheritable_attributes_test.rb +0 -32
  125. data/test/cases/column_alias_test.rb +0 -17
  126. data/test/cases/column_definition_test.rb +0 -70
  127. data/test/cases/connection_pool_test.rb +0 -25
  128. data/test/cases/connection_test_firebird.rb +0 -8
  129. data/test/cases/connection_test_mysql.rb +0 -65
  130. data/test/cases/copy_table_test_sqlite.rb +0 -80
  131. data/test/cases/counter_cache_test.rb +0 -84
  132. data/test/cases/database_statements_test.rb +0 -12
  133. data/test/cases/datatype_test_postgresql.rb +0 -204
  134. data/test/cases/date_time_test.rb +0 -37
  135. data/test/cases/default_test_firebird.rb +0 -16
  136. data/test/cases/defaults_test.rb +0 -111
  137. data/test/cases/deprecated_finder_test.rb +0 -30
  138. data/test/cases/dirty_test.rb +0 -316
  139. data/test/cases/finder_respond_to_test.rb +0 -76
  140. data/test/cases/finder_test.rb +0 -1098
  141. data/test/cases/fixtures_test.rb +0 -661
  142. data/test/cases/helper.rb +0 -68
  143. data/test/cases/i18n_test.rb +0 -46
  144. data/test/cases/inheritance_test.rb +0 -262
  145. data/test/cases/invalid_date_test.rb +0 -24
  146. data/test/cases/json_serialization_test.rb +0 -219
  147. data/test/cases/lifecycle_test.rb +0 -193
  148. data/test/cases/locking_test.rb +0 -350
  149. data/test/cases/method_scoping_test.rb +0 -704
  150. data/test/cases/migration_test.rb +0 -1649
  151. data/test/cases/migration_test_firebird.rb +0 -124
  152. data/test/cases/mixin_test.rb +0 -96
  153. data/test/cases/modules_test.rb +0 -109
  154. data/test/cases/multiple_db_test.rb +0 -85
  155. data/test/cases/named_scope_test.rb +0 -372
  156. data/test/cases/nested_attributes_test.rb +0 -840
  157. data/test/cases/pk_test.rb +0 -119
  158. data/test/cases/pooled_connections_test.rb +0 -103
  159. data/test/cases/query_cache_test.rb +0 -129
  160. data/test/cases/readonly_test.rb +0 -107
  161. data/test/cases/reflection_test.rb +0 -234
  162. data/test/cases/reload_models_test.rb +0 -22
  163. data/test/cases/repair_helper.rb +0 -50
  164. data/test/cases/reserved_word_test_mysql.rb +0 -176
  165. data/test/cases/sanitize_test.rb +0 -25
  166. data/test/cases/schema_authorization_test_postgresql.rb +0 -75
  167. data/test/cases/schema_dumper_test.rb +0 -211
  168. data/test/cases/schema_test_postgresql.rb +0 -178
  169. data/test/cases/serialization_test.rb +0 -47
  170. data/test/cases/sp_test_mysql.rb +0 -16
  171. data/test/cases/synonym_test_oracle.rb +0 -17
  172. data/test/cases/timestamp_test.rb +0 -75
  173. data/test/cases/transactions_test.rb +0 -543
  174. data/test/cases/unconnected_test.rb +0 -32
  175. data/test/cases/validations_i18n_test.rb +0 -925
  176. data/test/cases/validations_test.rb +0 -1684
  177. data/test/cases/xml_serialization_test.rb +0 -240
  178. data/test/cases/yaml_serialization_test.rb +0 -11
  179. data/test/config.rb +0 -5
  180. data/test/connections/jdbc_jdbcderby/connection.rb +0 -18
  181. data/test/connections/jdbc_jdbch2/connection.rb +0 -18
  182. data/test/connections/jdbc_jdbchsqldb/connection.rb +0 -18
  183. data/test/connections/jdbc_jdbcmysql/connection.rb +0 -26
  184. data/test/connections/jdbc_jdbcpostgresql/connection.rb +0 -26
  185. data/test/connections/jdbc_jdbcsqlite3/connection.rb +0 -25
  186. data/test/connections/native_db2/connection.rb +0 -25
  187. data/test/connections/native_firebird/connection.rb +0 -26
  188. data/test/connections/native_frontbase/connection.rb +0 -27
  189. data/test/connections/native_mysql/connection.rb +0 -25
  190. data/test/connections/native_openbase/connection.rb +0 -21
  191. data/test/connections/native_oracle/connection.rb +0 -27
  192. data/test/connections/native_postgresql/connection.rb +0 -21
  193. data/test/connections/native_sqlite/connection.rb +0 -25
  194. data/test/connections/native_sqlite3/connection.rb +0 -25
  195. data/test/connections/native_sqlite3/in_memory_connection.rb +0 -18
  196. data/test/connections/native_sybase/connection.rb +0 -23
  197. data/test/fixtures/accounts.yml +0 -29
  198. data/test/fixtures/all/developers.yml +0 -0
  199. data/test/fixtures/all/people.csv +0 -0
  200. data/test/fixtures/all/tasks.yml +0 -0
  201. data/test/fixtures/author_addresses.yml +0 -5
  202. data/test/fixtures/author_favorites.yml +0 -4
  203. data/test/fixtures/authors.yml +0 -9
  204. data/test/fixtures/binaries.yml +0 -132
  205. data/test/fixtures/books.yml +0 -7
  206. data/test/fixtures/categories.yml +0 -14
  207. data/test/fixtures/categories/special_categories.yml +0 -9
  208. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +0 -4
  209. data/test/fixtures/categories_ordered.yml +0 -7
  210. data/test/fixtures/categories_posts.yml +0 -23
  211. data/test/fixtures/categorizations.yml +0 -17
  212. data/test/fixtures/clubs.yml +0 -6
  213. data/test/fixtures/comments.yml +0 -59
  214. data/test/fixtures/companies.yml +0 -56
  215. data/test/fixtures/computers.yml +0 -4
  216. data/test/fixtures/courses.yml +0 -7
  217. data/test/fixtures/customers.yml +0 -26
  218. data/test/fixtures/developers.yml +0 -21
  219. data/test/fixtures/developers_projects.yml +0 -17
  220. data/test/fixtures/edges.yml +0 -6
  221. data/test/fixtures/entrants.yml +0 -14
  222. data/test/fixtures/faces.yml +0 -11
  223. data/test/fixtures/fk_test_has_fk.yml +0 -3
  224. data/test/fixtures/fk_test_has_pk.yml +0 -2
  225. data/test/fixtures/funny_jokes.yml +0 -10
  226. data/test/fixtures/interests.yml +0 -33
  227. data/test/fixtures/items.yml +0 -4
  228. data/test/fixtures/jobs.yml +0 -7
  229. data/test/fixtures/legacy_things.yml +0 -3
  230. data/test/fixtures/mateys.yml +0 -4
  231. data/test/fixtures/member_types.yml +0 -6
  232. data/test/fixtures/members.yml +0 -6
  233. data/test/fixtures/memberships.yml +0 -20
  234. data/test/fixtures/men.yml +0 -5
  235. data/test/fixtures/minimalistics.yml +0 -2
  236. data/test/fixtures/mixed_case_monkeys.yml +0 -6
  237. data/test/fixtures/mixins.yml +0 -29
  238. data/test/fixtures/movies.yml +0 -7
  239. data/test/fixtures/naked/csv/accounts.csv +0 -1
  240. data/test/fixtures/naked/yml/accounts.yml +0 -1
  241. data/test/fixtures/naked/yml/companies.yml +0 -1
  242. data/test/fixtures/naked/yml/courses.yml +0 -1
  243. data/test/fixtures/organizations.yml +0 -5
  244. data/test/fixtures/owners.yml +0 -7
  245. data/test/fixtures/parrots.yml +0 -27
  246. data/test/fixtures/parrots_pirates.yml +0 -7
  247. data/test/fixtures/people.yml +0 -15
  248. data/test/fixtures/pets.yml +0 -14
  249. data/test/fixtures/pirates.yml +0 -9
  250. data/test/fixtures/polymorphic_designs.yml +0 -19
  251. data/test/fixtures/polymorphic_prices.yml +0 -19
  252. data/test/fixtures/posts.yml +0 -52
  253. data/test/fixtures/price_estimates.yml +0 -7
  254. data/test/fixtures/projects.yml +0 -7
  255. data/test/fixtures/readers.yml +0 -9
  256. data/test/fixtures/references.yml +0 -17
  257. data/test/fixtures/reserved_words/distinct.yml +0 -5
  258. data/test/fixtures/reserved_words/distincts_selects.yml +0 -11
  259. data/test/fixtures/reserved_words/group.yml +0 -14
  260. data/test/fixtures/reserved_words/select.yml +0 -8
  261. data/test/fixtures/reserved_words/values.yml +0 -7
  262. data/test/fixtures/ships.yml +0 -5
  263. data/test/fixtures/sponsors.yml +0 -9
  264. data/test/fixtures/subscribers.yml +0 -7
  265. data/test/fixtures/subscriptions.yml +0 -12
  266. data/test/fixtures/taggings.yml +0 -28
  267. data/test/fixtures/tags.yml +0 -7
  268. data/test/fixtures/tasks.yml +0 -7
  269. data/test/fixtures/tees.yml +0 -4
  270. data/test/fixtures/ties.yml +0 -4
  271. data/test/fixtures/topics.yml +0 -42
  272. data/test/fixtures/toys.yml +0 -4
  273. data/test/fixtures/treasures.yml +0 -10
  274. data/test/fixtures/vertices.yml +0 -4
  275. data/test/fixtures/warehouse-things.yml +0 -3
  276. data/test/fixtures/zines.yml +0 -5
  277. data/test/migrations/broken/100_migration_that_raises_exception.rb +0 -10
  278. data/test/migrations/decimal/1_give_me_big_numbers.rb +0 -15
  279. data/test/migrations/duplicate/1_people_have_last_names.rb +0 -9
  280. data/test/migrations/duplicate/2_we_need_reminders.rb +0 -12
  281. data/test/migrations/duplicate/3_foo.rb +0 -7
  282. data/test/migrations/duplicate/3_innocent_jointable.rb +0 -12
  283. data/test/migrations/duplicate_names/20080507052938_chunky.rb +0 -7
  284. data/test/migrations/duplicate_names/20080507053028_chunky.rb +0 -7
  285. data/test/migrations/interleaved/pass_1/3_innocent_jointable.rb +0 -12
  286. data/test/migrations/interleaved/pass_2/1_people_have_last_names.rb +0 -9
  287. data/test/migrations/interleaved/pass_2/3_innocent_jointable.rb +0 -12
  288. data/test/migrations/interleaved/pass_3/1_people_have_last_names.rb +0 -9
  289. data/test/migrations/interleaved/pass_3/2_i_raise_on_down.rb +0 -8
  290. data/test/migrations/interleaved/pass_3/3_innocent_jointable.rb +0 -12
  291. data/test/migrations/missing/1000_people_have_middle_names.rb +0 -9
  292. data/test/migrations/missing/1_people_have_last_names.rb +0 -9
  293. data/test/migrations/missing/3_we_need_reminders.rb +0 -12
  294. data/test/migrations/missing/4_innocent_jointable.rb +0 -12
  295. data/test/migrations/valid/1_people_have_last_names.rb +0 -9
  296. data/test/migrations/valid/2_we_need_reminders.rb +0 -12
  297. data/test/migrations/valid/3_innocent_jointable.rb +0 -12
  298. data/test/models/author.rb +0 -151
  299. data/test/models/auto_id.rb +0 -4
  300. data/test/models/binary.rb +0 -2
  301. data/test/models/bird.rb +0 -9
  302. data/test/models/book.rb +0 -4
  303. data/test/models/categorization.rb +0 -5
  304. data/test/models/category.rb +0 -34
  305. data/test/models/citation.rb +0 -6
  306. data/test/models/club.rb +0 -13
  307. data/test/models/column_name.rb +0 -3
  308. data/test/models/comment.rb +0 -29
  309. data/test/models/company.rb +0 -173
  310. data/test/models/company_in_module.rb +0 -78
  311. data/test/models/computer.rb +0 -3
  312. data/test/models/contact.rb +0 -16
  313. data/test/models/contract.rb +0 -5
  314. data/test/models/course.rb +0 -3
  315. data/test/models/customer.rb +0 -73
  316. data/test/models/default.rb +0 -2
  317. data/test/models/developer.rb +0 -101
  318. data/test/models/edge.rb +0 -5
  319. data/test/models/entrant.rb +0 -3
  320. data/test/models/essay.rb +0 -3
  321. data/test/models/event.rb +0 -3
  322. data/test/models/event_author.rb +0 -8
  323. data/test/models/face.rb +0 -7
  324. data/test/models/guid.rb +0 -2
  325. data/test/models/interest.rb +0 -5
  326. data/test/models/invoice.rb +0 -4
  327. data/test/models/item.rb +0 -7
  328. data/test/models/job.rb +0 -5
  329. data/test/models/joke.rb +0 -3
  330. data/test/models/keyboard.rb +0 -3
  331. data/test/models/legacy_thing.rb +0 -3
  332. data/test/models/line_item.rb +0 -3
  333. data/test/models/man.rb +0 -9
  334. data/test/models/matey.rb +0 -4
  335. data/test/models/member.rb +0 -12
  336. data/test/models/member_detail.rb +0 -5
  337. data/test/models/member_type.rb +0 -3
  338. data/test/models/membership.rb +0 -9
  339. data/test/models/minimalistic.rb +0 -2
  340. data/test/models/mixed_case_monkey.rb +0 -3
  341. data/test/models/movie.rb +0 -5
  342. data/test/models/order.rb +0 -4
  343. data/test/models/organization.rb +0 -6
  344. data/test/models/owner.rb +0 -5
  345. data/test/models/parrot.rb +0 -22
  346. data/test/models/person.rb +0 -16
  347. data/test/models/pet.rb +0 -5
  348. data/test/models/pirate.rb +0 -80
  349. data/test/models/polymorphic_design.rb +0 -3
  350. data/test/models/polymorphic_price.rb +0 -3
  351. data/test/models/post.rb +0 -102
  352. data/test/models/price_estimate.rb +0 -3
  353. data/test/models/project.rb +0 -30
  354. data/test/models/reader.rb +0 -4
  355. data/test/models/reference.rb +0 -4
  356. data/test/models/reply.rb +0 -46
  357. data/test/models/ship.rb +0 -19
  358. data/test/models/ship_part.rb +0 -7
  359. data/test/models/sponsor.rb +0 -4
  360. data/test/models/subject.rb +0 -4
  361. data/test/models/subscriber.rb +0 -8
  362. data/test/models/subscription.rb +0 -4
  363. data/test/models/tag.rb +0 -7
  364. data/test/models/tagging.rb +0 -10
  365. data/test/models/task.rb +0 -3
  366. data/test/models/tee.rb +0 -4
  367. data/test/models/tie.rb +0 -4
  368. data/test/models/topic.rb +0 -80
  369. data/test/models/toy.rb +0 -6
  370. data/test/models/treasure.rb +0 -8
  371. data/test/models/vertex.rb +0 -9
  372. data/test/models/warehouse_thing.rb +0 -5
  373. data/test/models/zine.rb +0 -3
  374. data/test/schema/mysql_specific_schema.rb +0 -31
  375. data/test/schema/postgresql_specific_schema.rb +0 -114
  376. data/test/schema/schema.rb +0 -550
  377. data/test/schema/schema2.rb +0 -6
  378. data/test/schema/sqlite_specific_schema.rb +0 -25
@@ -1,19 +0,0 @@
1
- require 'cases/helper'
2
- require 'models/tee'
3
- require 'models/tie'
4
- require 'models/polymorphic_design'
5
- require 'models/polymorphic_price'
6
-
7
- class EagerLoadNestedPolymorphicIncludeTest < ActiveRecord::TestCase
8
- fixtures :tees, :ties, :polymorphic_designs, :polymorphic_prices
9
-
10
- def test_eager_load_polymorphic_has_one_nested_under_polymorphic_belongs_to
11
- designs = PolymorphicDesign.scoped(:include => {:designable => :polymorphic_price})
12
-
13
- associated_price_ids = designs.map{|design| design.designable.polymorphic_price.id}
14
- expected_price_ids = [1, 2, 3, 4]
15
-
16
- assert expected_price_ids.all?{|expected_id| associated_price_ids.include?(expected_id)},
17
- "Expected associated prices to be #{expected_price_ids.inspect} but they were #{associated_price_ids.sort.inspect}"
18
- end
19
- end
@@ -1,145 +0,0 @@
1
- require "cases/helper"
2
-
3
- class Virus < ActiveRecord::Base
4
- belongs_to :octopus
5
- end
6
- class Octopus < ActiveRecord::Base
7
- has_one :virus
8
- end
9
- class Pass < ActiveRecord::Base
10
- belongs_to :bus
11
- end
12
- class Bus < ActiveRecord::Base
13
- has_many :passes
14
- end
15
- class Mess < ActiveRecord::Base
16
- has_and_belongs_to_many :crises
17
- end
18
- class Crisis < ActiveRecord::Base
19
- has_and_belongs_to_many :messes
20
- has_many :analyses, :dependent => :destroy
21
- has_many :successes, :through => :analyses
22
- has_many :dresses, :dependent => :destroy
23
- has_many :compresses, :through => :dresses
24
- end
25
- class Analysis < ActiveRecord::Base
26
- belongs_to :crisis
27
- belongs_to :success
28
- end
29
- class Success < ActiveRecord::Base
30
- has_many :analyses, :dependent => :destroy
31
- has_many :crises, :through => :analyses
32
- end
33
- class Dress < ActiveRecord::Base
34
- belongs_to :crisis
35
- has_many :compresses
36
- end
37
- class Compress < ActiveRecord::Base
38
- belongs_to :dress
39
- end
40
-
41
-
42
- class EagerSingularizationTest < ActiveRecord::TestCase
43
-
44
- def setup
45
- if ActiveRecord::Base.connection.supports_migrations?
46
- ActiveRecord::Base.connection.create_table :viri do |t|
47
- t.column :octopus_id, :integer
48
- t.column :species, :string
49
- end
50
- ActiveRecord::Base.connection.create_table :octopi do |t|
51
- t.column :species, :string
52
- end
53
- ActiveRecord::Base.connection.create_table :passes do |t|
54
- t.column :bus_id, :integer
55
- t.column :rides, :integer
56
- end
57
- ActiveRecord::Base.connection.create_table :buses do |t|
58
- t.column :name, :string
59
- end
60
- ActiveRecord::Base.connection.create_table :crises_messes, :id => false do |t|
61
- t.column :crisis_id, :integer
62
- t.column :mess_id, :integer
63
- end
64
- ActiveRecord::Base.connection.create_table :messes do |t|
65
- t.column :name, :string
66
- end
67
- ActiveRecord::Base.connection.create_table :crises do |t|
68
- t.column :name, :string
69
- end
70
- ActiveRecord::Base.connection.create_table :successes do |t|
71
- t.column :name, :string
72
- end
73
- ActiveRecord::Base.connection.create_table :analyses do |t|
74
- t.column :crisis_id, :integer
75
- t.column :success_id, :integer
76
- end
77
- ActiveRecord::Base.connection.create_table :dresses do |t|
78
- t.column :crisis_id, :integer
79
- end
80
- ActiveRecord::Base.connection.create_table :compresses do |t|
81
- t.column :dress_id, :integer
82
- end
83
- @have_tables = true
84
- else
85
- @have_tables = false
86
- end
87
- end
88
-
89
- def teardown
90
- ActiveRecord::Base.connection.drop_table :viri
91
- ActiveRecord::Base.connection.drop_table :octopi
92
- ActiveRecord::Base.connection.drop_table :passes
93
- ActiveRecord::Base.connection.drop_table :buses
94
- ActiveRecord::Base.connection.drop_table :crises_messes
95
- ActiveRecord::Base.connection.drop_table :messes
96
- ActiveRecord::Base.connection.drop_table :crises
97
- ActiveRecord::Base.connection.drop_table :successes
98
- ActiveRecord::Base.connection.drop_table :analyses
99
- ActiveRecord::Base.connection.drop_table :dresses
100
- ActiveRecord::Base.connection.drop_table :compresses
101
- end
102
-
103
- def test_eager_no_extra_singularization_belongs_to
104
- return unless @have_tables
105
- assert_nothing_raised do
106
- Virus.find(:all, :include => :octopus)
107
- end
108
- end
109
-
110
- def test_eager_no_extra_singularization_has_one
111
- return unless @have_tables
112
- assert_nothing_raised do
113
- Octopus.find(:all, :include => :virus)
114
- end
115
- end
116
-
117
- def test_eager_no_extra_singularization_has_many
118
- return unless @have_tables
119
- assert_nothing_raised do
120
- Bus.find(:all, :include => :passes)
121
- end
122
- end
123
-
124
- def test_eager_no_extra_singularization_has_and_belongs_to_many
125
- return unless @have_tables
126
- assert_nothing_raised do
127
- Crisis.find(:all, :include => :messes)
128
- Mess.find(:all, :include => :crises)
129
- end
130
- end
131
-
132
- def test_eager_no_extra_singularization_has_many_through_belongs_to
133
- return unless @have_tables
134
- assert_nothing_raised do
135
- Crisis.find(:all, :include => :successes)
136
- end
137
- end
138
-
139
- def test_eager_no_extra_singularization_has_many_through_has_many
140
- return unless @have_tables
141
- assert_nothing_raised do
142
- Crisis.find(:all, :include => :compresses)
143
- end
144
- end
145
- end
@@ -1,852 +0,0 @@
1
- require "cases/helper"
2
- require 'models/post'
3
- require 'models/tagging'
4
- require 'models/tag'
5
- require 'models/comment'
6
- require 'models/author'
7
- require 'models/category'
8
- require 'models/company'
9
- require 'models/person'
10
- require 'models/reader'
11
- require 'models/owner'
12
- require 'models/pet'
13
- require 'models/reference'
14
- require 'models/job'
15
- require 'models/subscriber'
16
- require 'models/subscription'
17
- require 'models/book'
18
- require 'models/developer'
19
- require 'models/project'
20
-
21
- class EagerAssociationTest < ActiveRecord::TestCase
22
- fixtures :posts, :comments, :authors, :author_addresses, :categories, :categories_posts,
23
- :companies, :accounts, :tags, :taggings, :people, :readers,
24
- :owners, :pets, :author_favorites, :jobs, :references, :subscribers, :subscriptions, :books,
25
- :developers, :projects, :developers_projects
26
-
27
- def test_loading_with_one_association
28
- posts = Post.find(:all, :include => :comments)
29
- post = posts.find { |p| p.id == 1 }
30
- assert_equal 2, post.comments.size
31
- assert post.comments.include?(comments(:greetings))
32
-
33
- post = Post.find(:first, :include => :comments, :conditions => "posts.title = 'Welcome to the weblog'")
34
- assert_equal 2, post.comments.size
35
- assert post.comments.include?(comments(:greetings))
36
-
37
- posts = Post.find(:all, :include => :last_comment)
38
- post = posts.find { |p| p.id == 1 }
39
- assert_equal Post.find(1).last_comment, post.last_comment
40
- end
41
-
42
- def test_loading_with_one_association_with_non_preload
43
- posts = Post.find(:all, :include => :last_comment, :order => 'comments.id DESC')
44
- post = posts.find { |p| p.id == 1 }
45
- assert_equal Post.find(1).last_comment, post.last_comment
46
- end
47
-
48
- def test_loading_conditions_with_or
49
- posts = authors(:david).posts.find(:all, :include => :comments, :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE} = 'SpecialComment'")
50
- assert_nil posts.detect { |p| p.author_id != authors(:david).id },
51
- "expected to find only david's posts"
52
- end
53
-
54
- def test_with_ordering
55
- list = Post.find(:all, :include => :comments, :order => "posts.id DESC")
56
- [:eager_other, :sti_habtm, :sti_post_and_comments, :sti_comments,
57
- :authorless, :thinking, :welcome
58
- ].each_with_index do |post, index|
59
- assert_equal posts(post), list[index]
60
- end
61
- end
62
-
63
- def test_with_two_tables_in_from_without_getting_double_quoted
64
- posts = Post.find(:all,
65
- :select => "posts.*",
66
- :from => "authors, posts",
67
- :include => :comments,
68
- :conditions => "posts.author_id = authors.id",
69
- :order => "posts.id"
70
- )
71
-
72
- assert_equal 2, posts.first.comments.size
73
- end
74
-
75
- def test_loading_with_multiple_associations
76
- posts = Post.find(:all, :include => [ :comments, :author, :categories ], :order => "posts.id")
77
- assert_equal 2, posts.first.comments.size
78
- assert_equal 2, posts.first.categories.size
79
- assert posts.first.comments.include?(comments(:greetings))
80
- end
81
-
82
- def test_duplicate_middle_objects
83
- comments = Comment.find :all, :conditions => 'post_id = 1', :include => [:post => :author]
84
- assert_no_queries do
85
- comments.each {|comment| comment.post.author.name}
86
- end
87
- end
88
-
89
- def test_including_duplicate_objects_from_belongs_to
90
- popular_post = Post.create!(:title => 'foo', :body => "I like cars!")
91
- comment = popular_post.comments.create!(:body => "lol")
92
- popular_post.readers.create!(:person => people(:michael))
93
- popular_post.readers.create!(:person => people(:david))
94
-
95
- readers = Reader.find(:all, :conditions => ["post_id = ?", popular_post.id],
96
- :include => {:post => :comments})
97
- readers.each do |reader|
98
- assert_equal [comment], reader.post.comments
99
- end
100
- end
101
-
102
- def test_including_duplicate_objects_from_has_many
103
- car_post = Post.create!(:title => 'foo', :body => "I like cars!")
104
- car_post.categories << categories(:general)
105
- car_post.categories << categories(:technology)
106
-
107
- comment = car_post.comments.create!(:body => "hmm")
108
- categories = Category.find(:all, :conditions => ["posts.id=?", car_post.id],
109
- :include => {:posts => :comments})
110
- categories.each do |category|
111
- assert_equal [comment], category.posts[0].comments
112
- end
113
- end
114
-
115
- def test_finding_with_includes_on_has_many_association_with_same_include_includes_only_once
116
- author_id = authors(:david).id
117
- author = assert_queries(3) { Author.find(author_id, :include => {:posts_with_comments => :comments}) } # find the author, then find the posts, then find the comments
118
- author.posts_with_comments.each do |post_with_comments|
119
- assert_equal post_with_comments.comments.length, post_with_comments.comments.count
120
- assert_equal nil, post_with_comments.comments.uniq!
121
- end
122
- end
123
-
124
- def test_finding_with_includes_on_has_one_assocation_with_same_include_includes_only_once
125
- author = authors(:david)
126
- post = author.post_about_thinking_with_last_comment
127
- last_comment = post.last_comment
128
- author = assert_queries(3) { Author.find(author.id, :include => {:post_about_thinking_with_last_comment => :last_comment})} # find the author, then find the posts, then find the comments
129
- assert_no_queries do
130
- assert_equal post, author.post_about_thinking_with_last_comment
131
- assert_equal last_comment, author.post_about_thinking_with_last_comment.last_comment
132
- end
133
- end
134
-
135
- def test_finding_with_includes_on_belongs_to_association_with_same_include_includes_only_once
136
- post = posts(:welcome)
137
- author = post.author
138
- author_address = author.author_address
139
- post = assert_queries(3) { Post.find(post.id, :include => {:author_with_address => :author_address}) } # find the post, then find the author, then find the address
140
- assert_no_queries do
141
- assert_equal author, post.author_with_address
142
- assert_equal author_address, post.author_with_address.author_address
143
- end
144
- end
145
-
146
- def test_finding_with_includes_on_null_belongs_to_association_with_same_include_includes_only_once
147
- post = posts(:welcome)
148
- post.update_attributes!(:author => nil)
149
- post = assert_queries(1) { Post.find(post.id, :include => {:author_with_address => :author_address}) } # find the post, then find the author which is null so no query for the author or address
150
- assert_no_queries do
151
- assert_equal nil, post.author_with_address
152
- end
153
- end
154
-
155
- def test_loading_from_an_association
156
- posts = authors(:david).posts.find(:all, :include => :comments, :order => "posts.id")
157
- assert_equal 2, posts.first.comments.size
158
- end
159
-
160
- def test_loading_from_an_association_that_has_a_hash_of_conditions
161
- assert_nothing_raised do
162
- Author.find(:all, :include => :hello_posts_with_hash_conditions)
163
- end
164
- assert !Author.find(authors(:david).id, :include => :hello_posts_with_hash_conditions).hello_posts.empty?
165
- end
166
-
167
- def test_loading_with_no_associations
168
- assert_nil Post.find(posts(:authorless).id, :include => :author).author
169
- end
170
-
171
- def test_nested_loading_with_no_associations
172
- assert_nothing_raised do
173
- Post.find(posts(:authorless).id, :include => {:author => :author_addresss})
174
- end
175
- end
176
-
177
- def test_eager_association_loading_with_belongs_to_and_foreign_keys
178
- pets = Pet.find(:all, :include => :owner)
179
- assert_equal 3, pets.length
180
- end
181
-
182
- def test_eager_association_loading_with_belongs_to
183
- comments = Comment.find(:all, :include => :post)
184
- assert_equal 10, comments.length
185
- titles = comments.map { |c| c.post.title }
186
- assert titles.include?(posts(:welcome).title)
187
- assert titles.include?(posts(:sti_post_and_comments).title)
188
- end
189
-
190
- def test_eager_association_loading_with_belongs_to_and_limit
191
- comments = Comment.find(:all, :include => :post, :limit => 5, :order => 'comments.id')
192
- assert_equal 5, comments.length
193
- assert_equal [1,2,3,5,6], comments.collect { |c| c.id }
194
- end
195
-
196
- def test_eager_association_loading_with_belongs_to_and_limit_and_conditions
197
- comments = Comment.find(:all, :include => :post, :conditions => 'post_id = 4', :limit => 3, :order => 'comments.id')
198
- assert_equal 3, comments.length
199
- assert_equal [5,6,7], comments.collect { |c| c.id }
200
- end
201
-
202
- def test_eager_association_loading_with_belongs_to_and_limit_and_offset
203
- comments = Comment.find(:all, :include => :post, :limit => 3, :offset => 2, :order => 'comments.id')
204
- assert_equal 3, comments.length
205
- assert_equal [3,5,6], comments.collect { |c| c.id }
206
- end
207
-
208
- def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_conditions
209
- comments = Comment.find(:all, :include => :post, :conditions => 'post_id = 4', :limit => 3, :offset => 1, :order => 'comments.id')
210
- assert_equal 3, comments.length
211
- assert_equal [6,7,8], comments.collect { |c| c.id }
212
- end
213
-
214
- def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_conditions_array
215
- comments = Comment.find(:all, :include => :post, :conditions => ['post_id = ?',4], :limit => 3, :offset => 1, :order => 'comments.id')
216
- assert_equal 3, comments.length
217
- assert_equal [6,7,8], comments.collect { |c| c.id }
218
- end
219
-
220
- def test_eager_association_loading_with_belongs_to_and_conditions_string_with_unquoted_table_name
221
- assert_nothing_raised do
222
- Comment.find(:all, :include => :post, :conditions => ['posts.id = ?',4])
223
- end
224
- end
225
-
226
- def test_eager_association_loading_with_belongs_to_and_conditions_hash
227
- comments = []
228
- assert_nothing_raised do
229
- comments = Comment.find(:all, :include => :post, :conditions => {:posts => {:id => 4}}, :limit => 3, :order => 'comments.id')
230
- end
231
- assert_equal 3, comments.length
232
- assert_equal [5,6,7], comments.collect { |c| c.id }
233
- assert_no_queries do
234
- comments.first.post
235
- end
236
- end
237
-
238
- def test_eager_association_loading_with_belongs_to_and_conditions_string_with_quoted_table_name
239
- quoted_posts_id= Comment.connection.quote_table_name('posts') + '.' + Comment.connection.quote_column_name('id')
240
- assert_nothing_raised do
241
- Comment.find(:all, :include => :post, :conditions => ["#{quoted_posts_id} = ?",4])
242
- end
243
- end
244
-
245
- def test_eager_association_loading_with_belongs_to_and_order_string_with_unquoted_table_name
246
- assert_nothing_raised do
247
- Comment.find(:all, :include => :post, :order => 'posts.id')
248
- end
249
- end
250
-
251
- def test_eager_association_loading_with_belongs_to_and_order_string_with_quoted_table_name
252
- quoted_posts_id= Comment.connection.quote_table_name('posts') + '.' + Comment.connection.quote_column_name('id')
253
- assert_nothing_raised do
254
- Comment.find(:all, :include => :post, :order => quoted_posts_id)
255
- end
256
- end
257
-
258
- def test_eager_association_loading_with_belongs_to_and_limit_and_multiple_associations
259
- posts = Post.find(:all, :include => [:author, :very_special_comment], :limit => 1, :order => 'posts.id')
260
- assert_equal 1, posts.length
261
- assert_equal [1], posts.collect { |p| p.id }
262
- end
263
-
264
- def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_multiple_associations
265
- posts = Post.find(:all, :include => [:author, :very_special_comment], :limit => 1, :offset => 1, :order => 'posts.id')
266
- assert_equal 1, posts.length
267
- assert_equal [2], posts.collect { |p| p.id }
268
- end
269
-
270
- def test_eager_association_loading_with_belongs_to_inferred_foreign_key_from_association_name
271
- author_favorite = AuthorFavorite.find(:first, :include => :favorite_author)
272
- assert_equal authors(:mary), assert_no_queries { author_favorite.favorite_author }
273
- end
274
-
275
- def test_eager_load_belongs_to_quotes_table_and_column_names
276
- job = Job.find jobs(:unicyclist).id, :include => :ideal_reference
277
- references(:michael_unicyclist)
278
- assert_no_queries{ assert_equal references(:michael_unicyclist), job.ideal_reference}
279
- end
280
-
281
- def test_eager_load_has_one_quotes_table_and_column_names
282
- michael = Person.find(people(:michael), :include => :favourite_reference)
283
- references(:michael_unicyclist)
284
- assert_no_queries{ assert_equal references(:michael_unicyclist), michael.favourite_reference}
285
- end
286
-
287
- def test_eager_load_has_many_quotes_table_and_column_names
288
- michael = Person.find(people(:michael), :include => :references)
289
- references(:michael_magician,:michael_unicyclist)
290
- assert_no_queries{ assert_equal references(:michael_magician,:michael_unicyclist), michael.references.sort_by(&:id) }
291
- end
292
-
293
- def test_eager_load_has_many_through_quotes_table_and_column_names
294
- michael = Person.find(people(:michael), :include => :jobs)
295
- jobs(:magician, :unicyclist)
296
- assert_no_queries{ assert_equal jobs(:unicyclist, :magician), michael.jobs.sort_by(&:id) }
297
- end
298
-
299
- def test_eager_load_has_many_with_string_keys
300
- subscriptions = subscriptions(:webster_awdr, :webster_rfr)
301
- subscriber =Subscriber.find(subscribers(:second).id, :include => :subscriptions)
302
- assert_equal subscriptions, subscriber.subscriptions.sort_by(&:id)
303
- end
304
-
305
- def test_eager_load_has_many_through_with_string_keys
306
- books = books(:awdr, :rfr)
307
- subscriber = Subscriber.find(subscribers(:second).id, :include => :books)
308
- assert_equal books, subscriber.books.sort_by(&:id)
309
- end
310
-
311
- def test_eager_load_belongs_to_with_string_keys
312
- subscriber = subscribers(:second)
313
- subscription = Subscription.find(subscriptions(:webster_awdr).id, :include => :subscriber)
314
- assert_equal subscriber, subscription.subscriber
315
- end
316
-
317
- def test_eager_association_loading_with_explicit_join
318
- posts = Post.find(:all, :include => :comments, :joins => "INNER JOIN authors ON posts.author_id = authors.id AND authors.name = 'Mary'", :limit => 1, :order => 'author_id')
319
- assert_equal 1, posts.length
320
- end
321
-
322
- def test_eager_with_has_many_through
323
- posts_with_comments = people(:michael).posts.find(:all, :include => :comments, :order => 'posts.id')
324
- posts_with_author = people(:michael).posts.find(:all, :include => :author, :order => 'posts.id')
325
- posts_with_comments_and_author = people(:michael).posts.find(:all, :include => [ :comments, :author ], :order => 'posts.id')
326
- assert_equal 2, posts_with_comments.inject(0) { |sum, post| sum += post.comments.size }
327
- assert_equal authors(:david), assert_no_queries { posts_with_author.first.author }
328
- assert_equal authors(:david), assert_no_queries { posts_with_comments_and_author.first.author }
329
- end
330
-
331
- def test_eager_with_has_many_through_a_belongs_to_association
332
- author = authors(:mary)
333
- post = Post.create!(:author => author, :title => "TITLE", :body => "BODY")
334
- author.author_favorites.create(:favorite_author_id => 1)
335
- author.author_favorites.create(:favorite_author_id => 2)
336
- posts_with_author_favorites = author.posts.find(:all, :include => :author_favorites)
337
- assert_no_queries { posts_with_author_favorites.first.author_favorites.first.author_id }
338
- end
339
-
340
- def test_eager_with_has_many_through_an_sti_join_model
341
- author = Author.find(:first, :include => :special_post_comments, :order => 'authors.id')
342
- assert_equal [comments(:does_it_hurt)], assert_no_queries { author.special_post_comments }
343
- end
344
-
345
- def test_eager_with_has_many_through_an_sti_join_model_with_conditions_on_both
346
- author = Author.find(:first, :include => :special_nonexistant_post_comments, :order => 'authors.id')
347
- assert_equal [], author.special_nonexistant_post_comments
348
- end
349
-
350
- def test_eager_with_has_many_through_join_model_with_conditions
351
- assert_equal Author.find(:first, :include => :hello_post_comments,
352
- :order => 'authors.id').hello_post_comments.sort_by(&:id),
353
- Author.find(:first, :order => 'authors.id').hello_post_comments.sort_by(&:id)
354
- end
355
-
356
- def test_eager_with_has_many_through_join_model_with_conditions_on_top_level
357
- assert_equal comments(:more_greetings), Author.find(authors(:david).id, :include => :comments_with_order_and_conditions).comments_with_order_and_conditions.first
358
- end
359
-
360
- def test_eager_with_has_many_through_with_conditions_join_model_with_include
361
- post_tags = Post.find(posts(:welcome).id).misc_tags
362
- eager_post_tags = Post.find(1, :include => :misc_tags).misc_tags
363
- assert_equal post_tags, eager_post_tags
364
- end
365
-
366
- def test_eager_with_has_many_through_association_with_order
367
- author_comments = Author.find(authors(:david).id).comments_desc
368
- eager_author_comments = Author.find(authors(:david).id, :include => :comments_desc).comments_desc
369
- assert_equal eager_author_comments, author_comments
370
- end
371
-
372
- def test_eager_with_has_many_through_join_model_with_include
373
- author_comments = Author.find(authors(:david).id, :include => :comments_with_include).comments_with_include.to_a
374
- assert_no_queries do
375
- author_comments.first.post.title
376
- end
377
- end
378
-
379
- def test_eager_with_has_many_and_limit
380
- posts = Post.find(:all, :order => 'posts.id asc', :include => [ :author, :comments ], :limit => 2)
381
- assert_equal 2, posts.size
382
- assert_equal 3, posts.inject(0) { |sum, post| sum += post.comments.size }
383
- end
384
-
385
- def test_eager_with_has_many_and_limit_and_conditions
386
- if current_adapter?(:OpenBaseAdapter)
387
- posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "FETCHBLOB(posts.body) = 'hello'", :order => "posts.id")
388
- else
389
- posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "posts.body = 'hello'", :order => "posts.id")
390
- end
391
- assert_equal 2, posts.size
392
- assert_equal [4,5], posts.collect { |p| p.id }
393
- end
394
-
395
- def test_eager_with_has_many_and_limit_and_conditions_array
396
- if current_adapter?(:OpenBaseAdapter)
397
- posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => [ "FETCHBLOB(posts.body) = ?", 'hello' ], :order => "posts.id")
398
- else
399
- posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => [ "posts.body = ?", 'hello' ], :order => "posts.id")
400
- end
401
- assert_equal 2, posts.size
402
- assert_equal [4,5], posts.collect { |p| p.id }
403
- end
404
-
405
- def test_eager_with_has_many_and_limit_and_conditions_array_on_the_eagers
406
- posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => [ "authors.name = ?", 'David' ])
407
- assert_equal 2, posts.size
408
-
409
- count = Post.count(:include => [ :author, :comments ], :limit => 2, :conditions => [ "authors.name = ?", 'David' ])
410
- assert_equal count, posts.size
411
- end
412
-
413
- def test_eager_with_has_many_and_limit_and_high_offset
414
- posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10, :conditions => [ "authors.name = ?", 'David' ])
415
- assert_equal 0, posts.size
416
- end
417
-
418
- def test_eager_with_has_many_and_limit_and_high_offset_and_multiple_array_conditions
419
- assert_queries(1) do
420
- posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10,
421
- :conditions => [ "authors.name = ? and comments.body = ?", 'David', 'go crazy' ])
422
- assert_equal 0, posts.size
423
- end
424
- end
425
-
426
- def test_eager_with_has_many_and_limit_and_high_offset_and_multiple_hash_conditions
427
- assert_queries(1) do
428
- posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10,
429
- :conditions => { 'authors.name' => 'David', 'comments.body' => 'go crazy' })
430
- assert_equal 0, posts.size
431
- end
432
- end
433
-
434
- def test_count_eager_with_has_many_and_limit_and_high_offset
435
- posts = Post.count(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10, :conditions => [ "authors.name = ?", 'David' ])
436
- assert_equal 0, posts
437
- end
438
-
439
- def test_eager_with_has_many_and_limit_with_no_results
440
- posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "posts.title = 'magic forest'")
441
- assert_equal 0, posts.size
442
- end
443
-
444
- def test_eager_count_performed_on_a_has_many_association_with_multi_table_conditional
445
- author = authors(:david)
446
- author_posts_without_comments = author.posts.select { |post| post.comments.blank? }
447
- assert_equal author_posts_without_comments.size, author.posts.count(:all, :include => :comments, :conditions => 'comments.id is null')
448
- end
449
-
450
- def test_eager_count_performed_on_a_has_many_through_association_with_multi_table_conditional
451
- person = people(:michael)
452
- person_posts_without_comments = person.posts.select { |post| post.comments.blank? }
453
- assert_equal person_posts_without_comments.size, person.posts_with_no_comments.count
454
- end
455
-
456
- def test_eager_with_has_and_belongs_to_many_and_limit
457
- posts = Post.find(:all, :include => :categories, :order => "posts.id", :limit => 3)
458
- assert_equal 3, posts.size
459
- assert_equal 2, posts[0].categories.size
460
- assert_equal 1, posts[1].categories.size
461
- assert_equal 0, posts[2].categories.size
462
- assert posts[0].categories.include?(categories(:technology))
463
- assert posts[1].categories.include?(categories(:general))
464
- end
465
-
466
- def test_eager_with_has_many_and_limit_and_conditions_on_the_eagers
467
- posts = authors(:david).posts.find(:all,
468
- :include => :comments,
469
- :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'",
470
- :limit => 2
471
- )
472
- assert_equal 2, posts.size
473
-
474
- count = Post.count(
475
- :include => [ :comments, :author ],
476
- :conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')",
477
- :limit => 2
478
- )
479
- assert_equal count, posts.size
480
- end
481
-
482
- def test_eager_with_has_many_and_limit_and_scoped_conditions_on_the_eagers
483
- posts = nil
484
- Post.with_scope(:find => {
485
- :include => :comments,
486
- :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'"
487
- }) do
488
- posts = authors(:david).posts.find(:all, :limit => 2)
489
- assert_equal 2, posts.size
490
- end
491
-
492
- Post.with_scope(:find => {
493
- :include => [ :comments, :author ],
494
- :conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')"
495
- }) do
496
- count = Post.count(:limit => 2)
497
- assert_equal count, posts.size
498
- end
499
- end
500
-
501
- def test_eager_with_has_many_and_limit_and_scoped_and_explicit_conditions_on_the_eagers
502
- Post.with_scope(:find => { :conditions => "1=1" }) do
503
- posts = authors(:david).posts.find(:all,
504
- :include => :comments,
505
- :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'",
506
- :limit => 2
507
- )
508
- assert_equal 2, posts.size
509
-
510
- count = Post.count(
511
- :include => [ :comments, :author ],
512
- :conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')",
513
- :limit => 2
514
- )
515
- assert_equal count, posts.size
516
- end
517
- end
518
-
519
- def test_eager_with_scoped_order_using_association_limiting_without_explicit_scope
520
- posts_with_explicit_order = Post.find(:all, :conditions => 'comments.id is not null', :include => :comments, :order => 'posts.id DESC', :limit => 2)
521
- posts_with_scoped_order = Post.with_scope(:find => {:order => 'posts.id DESC'}) do
522
- Post.find(:all, :conditions => 'comments.id is not null', :include => :comments, :limit => 2)
523
- end
524
- assert_equal posts_with_explicit_order, posts_with_scoped_order
525
- end
526
-
527
- def test_eager_association_loading_with_habtm
528
- posts = Post.find(:all, :include => :categories, :order => "posts.id")
529
- assert_equal 2, posts[0].categories.size
530
- assert_equal 1, posts[1].categories.size
531
- assert_equal 0, posts[2].categories.size
532
- assert posts[0].categories.include?(categories(:technology))
533
- assert posts[1].categories.include?(categories(:general))
534
- end
535
-
536
- def test_eager_with_inheritance
537
- posts = SpecialPost.find(:all, :include => [ :comments ])
538
- end
539
-
540
- def test_eager_has_one_with_association_inheritance
541
- post = Post.find(4, :include => [ :very_special_comment ])
542
- assert_equal "VerySpecialComment", post.very_special_comment.class.to_s
543
- end
544
-
545
- def test_eager_has_many_with_association_inheritance
546
- post = Post.find(4, :include => [ :special_comments ])
547
- post.special_comments.each do |special_comment|
548
- assert_equal "SpecialComment", special_comment.class.to_s
549
- end
550
- end
551
-
552
- def test_eager_habtm_with_association_inheritance
553
- post = Post.find(6, :include => [ :special_categories ])
554
- assert_equal 1, post.special_categories.size
555
- post.special_categories.each do |special_category|
556
- assert_equal "SpecialCategory", special_category.class.to_s
557
- end
558
- end
559
-
560
- def test_eager_with_has_one_dependent_does_not_destroy_dependent
561
- assert_not_nil companies(:first_firm).account
562
- f = Firm.find(:first, :include => :account,
563
- :conditions => ["companies.name = ?", "37signals"])
564
- assert_not_nil f.account
565
- assert_equal companies(:first_firm, :reload).account, f.account
566
- end
567
-
568
- def test_eager_with_multi_table_conditional_properly_counts_the_records_when_using_size
569
- author = authors(:david)
570
- posts_with_no_comments = author.posts.select { |post| post.comments.blank? }
571
- assert_equal posts_with_no_comments.size, author.posts_with_no_comments.size
572
- assert_equal posts_with_no_comments, author.posts_with_no_comments
573
- end
574
-
575
- def test_eager_with_invalid_association_reference
576
- assert_raise(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
577
- post = Post.find(6, :include=> :monkeys )
578
- }
579
- assert_raise(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
580
- post = Post.find(6, :include=>[ :monkeys ])
581
- }
582
- assert_raise(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
583
- post = Post.find(6, :include=>[ 'monkeys' ])
584
- }
585
- assert_raise(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys, :elephants") {
586
- post = Post.find(6, :include=>[ :monkeys, :elephants ])
587
- }
588
- end
589
-
590
- def find_all_ordered(className, include=nil)
591
- className.find(:all, :order=>"#{className.table_name}.#{className.primary_key}", :include=>include)
592
- end
593
-
594
- def test_limited_eager_with_order
595
- assert_equal posts(:thinking, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title)', :limit => 2, :offset => 1)
596
- assert_equal posts(:sti_post_and_comments, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC', :limit => 2, :offset => 1)
597
- end
598
-
599
- def test_limited_eager_with_multiple_order_columns
600
- assert_equal posts(:thinking, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title), posts.id', :limit => 2, :offset => 1)
601
- assert_equal posts(:sti_post_and_comments, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC, posts.id', :limit => 2, :offset => 1)
602
- end
603
-
604
- def test_preload_with_interpolation
605
- assert_equal [comments(:greetings)], Post.find(posts(:welcome).id, :include => :comments_with_interpolated_conditions).comments_with_interpolated_conditions
606
- end
607
-
608
- def test_polymorphic_type_condition
609
- post = Post.find(posts(:thinking).id, :include => :taggings)
610
- assert post.taggings.include?(taggings(:thinking_general))
611
- post = SpecialPost.find(posts(:thinking).id, :include => :taggings)
612
- assert post.taggings.include?(taggings(:thinking_general))
613
- end
614
-
615
- def test_eager_with_multiple_associations_with_same_table_has_many_and_habtm
616
- # Eager includes of has many and habtm associations aren't necessarily sorted in the same way
617
- def assert_equal_after_sort(item1, item2, item3 = nil)
618
- assert_equal(item1.sort{|a,b| a.id <=> b.id}, item2.sort{|a,b| a.id <=> b.id})
619
- assert_equal(item3.sort{|a,b| a.id <=> b.id}, item2.sort{|a,b| a.id <=> b.id}) if item3
620
- end
621
- # Test regular association, association with conditions, association with
622
- # STI, and association with conditions assured not to be true
623
- post_types = [:posts, :other_posts, :special_posts]
624
- # test both has_many and has_and_belongs_to_many
625
- [Author, Category].each do |className|
626
- d1 = find_all_ordered(className)
627
- # test including all post types at once
628
- d2 = find_all_ordered(className, post_types)
629
- d1.each_index do |i|
630
- assert_equal(d1[i], d2[i])
631
- assert_equal_after_sort(d1[i].posts, d2[i].posts)
632
- post_types[1..-1].each do |post_type|
633
- # test including post_types together
634
- d3 = find_all_ordered(className, [:posts, post_type])
635
- assert_equal(d1[i], d3[i])
636
- assert_equal_after_sort(d1[i].posts, d3[i].posts)
637
- assert_equal_after_sort(d1[i].send(post_type), d2[i].send(post_type), d3[i].send(post_type))
638
- end
639
- end
640
- end
641
- end
642
-
643
- def test_eager_with_multiple_associations_with_same_table_has_one
644
- d1 = find_all_ordered(Firm)
645
- d2 = find_all_ordered(Firm, :account)
646
- d1.each_index do |i|
647
- assert_equal(d1[i], d2[i])
648
- assert_equal(d1[i].account, d2[i].account)
649
- end
650
- end
651
-
652
- def test_eager_with_multiple_associations_with_same_table_belongs_to
653
- firm_types = [:firm, :firm_with_basic_id, :firm_with_other_name, :firm_with_condition]
654
- d1 = find_all_ordered(Client)
655
- d2 = find_all_ordered(Client, firm_types)
656
- d1.each_index do |i|
657
- assert_equal(d1[i], d2[i])
658
- firm_types.each { |type| assert_equal(d1[i].send(type), d2[i].send(type)) }
659
- end
660
- end
661
- def test_eager_with_valid_association_as_string_not_symbol
662
- assert_nothing_raised { Post.find(:all, :include => 'comments') }
663
- end
664
-
665
- def test_eager_with_floating_point_numbers
666
- assert_queries(2) do
667
- # Before changes, the floating point numbers will be interpreted as table names and will cause this to run in one query
668
- Comment.find :all, :conditions => "123.456 = 123.456", :include => :post
669
- end
670
- end
671
-
672
- def test_preconfigured_includes_with_belongs_to
673
- author = posts(:welcome).author_with_posts
674
- assert_no_queries {assert_equal 5, author.posts.size}
675
- end
676
-
677
- def test_preconfigured_includes_with_has_one
678
- comment = posts(:sti_comments).very_special_comment_with_post
679
- assert_no_queries {assert_equal posts(:sti_comments), comment.post}
680
- end
681
-
682
- def test_preconfigured_includes_with_has_many
683
- posts = authors(:david).posts_with_comments
684
- one = posts.detect { |p| p.id == 1 }
685
- assert_no_queries do
686
- assert_equal 5, posts.size
687
- assert_equal 2, one.comments.size
688
- end
689
- end
690
-
691
- def test_preconfigured_includes_with_habtm
692
- posts = authors(:david).posts_with_categories
693
- one = posts.detect { |p| p.id == 1 }
694
- assert_no_queries do
695
- assert_equal 5, posts.size
696
- assert_equal 2, one.categories.size
697
- end
698
- end
699
-
700
- def test_preconfigured_includes_with_has_many_and_habtm
701
- posts = authors(:david).posts_with_comments_and_categories
702
- one = posts.detect { |p| p.id == 1 }
703
- assert_no_queries do
704
- assert_equal 5, posts.size
705
- assert_equal 2, one.comments.size
706
- assert_equal 2, one.categories.size
707
- end
708
- end
709
-
710
- def test_count_with_include
711
- if current_adapter?(:SybaseAdapter)
712
- assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "len(comments.body) > 15")
713
- elsif current_adapter?(:OpenBaseAdapter)
714
- assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "length(FETCHBLOB(comments.body)) > 15")
715
- else
716
- assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "length(comments.body) > 15")
717
- end
718
- end
719
-
720
- def test_load_with_sti_sharing_association
721
- assert_queries(2) do #should not do 1 query per subclass
722
- Comment.find :all, :include => :post
723
- end
724
- end
725
-
726
- def test_conditions_on_join_table_with_include_and_limit
727
- assert_equal 3, Developer.find(:all, :include => 'projects', :conditions => 'developers_projects.access_level = 1', :limit => 5).size
728
- end
729
-
730
- def test_order_on_join_table_with_include_and_limit
731
- assert_equal 5, Developer.find(:all, :include => 'projects', :order => 'developers_projects.joined_on DESC', :limit => 5).size
732
- end
733
-
734
- def test_eager_loading_with_order_on_joined_table_preloads
735
- posts = assert_queries(2) do
736
- Post.find(:all, :joins => :comments, :include => :author, :order => 'comments.id DESC')
737
- end
738
- assert_equal posts(:eager_other), posts[0]
739
- assert_equal authors(:mary), assert_no_queries { posts[0].author}
740
- end
741
-
742
- def test_eager_loading_with_conditions_on_joined_table_preloads
743
- posts = assert_queries(2) do
744
- Post.find(:all, :select => 'distinct posts.*', :include => :author, :joins => [:comments], :conditions => "comments.body like 'Thank you%'", :order => 'posts.id')
745
- end
746
- assert_equal [posts(:welcome)], posts
747
- assert_equal authors(:david), assert_no_queries { posts[0].author}
748
-
749
- posts = assert_queries(2) do
750
- Post.find(:all, :select => 'distinct posts.*', :include => :author, :joins => [:comments], :conditions => "comments.body like 'Thank you%'", :order => 'posts.id')
751
- end
752
- assert_equal [posts(:welcome)], posts
753
- assert_equal authors(:david), assert_no_queries { posts[0].author}
754
-
755
- posts = assert_queries(2) do
756
- Post.find(:all, :include => :author, :joins => {:taggings => :tag}, :conditions => "tags.name = 'General'", :order => 'posts.id')
757
- end
758
- assert_equal posts(:welcome, :thinking), posts
759
-
760
- posts = assert_queries(2) do
761
- Post.find(:all, :include => :author, :joins => {:taggings => {:tag => :taggings}}, :conditions => "taggings_tags.super_tag_id=2", :order => 'posts.id')
762
- end
763
- assert_equal posts(:welcome, :thinking), posts
764
-
765
- end
766
-
767
- def test_eager_loading_with_conditions_on_string_joined_table_preloads
768
- posts = assert_queries(2) do
769
- Post.find(:all, :select => 'distinct posts.*', :include => :author, :joins => "INNER JOIN comments on comments.post_id = posts.id", :conditions => "comments.body like 'Thank you%'", :order => 'posts.id')
770
- end
771
- assert_equal [posts(:welcome)], posts
772
- assert_equal authors(:david), assert_no_queries { posts[0].author}
773
-
774
- posts = assert_queries(2) do
775
- Post.find(:all, :select => 'distinct posts.*', :include => :author, :joins => ["INNER JOIN comments on comments.post_id = posts.id"], :conditions => "comments.body like 'Thank you%'", :order => 'posts.id')
776
- end
777
- assert_equal [posts(:welcome)], posts
778
- assert_equal authors(:david), assert_no_queries { posts[0].author}
779
-
780
- end
781
-
782
- def test_eager_loading_with_select_on_joined_table_preloads
783
- posts = assert_queries(2) do
784
- Post.find(:all, :select => 'posts.*, authors.name as author_name', :include => :comments, :joins => :author, :order => 'posts.id')
785
- end
786
- assert_equal 'David', posts[0].author_name
787
- assert_equal posts(:welcome).comments, assert_no_queries { posts[0].comments}
788
- end
789
-
790
- def test_eager_loading_with_conditions_on_join_model_preloads
791
- authors = assert_queries(2) do
792
- Author.find(:all, :include => :author_address, :joins => :comments, :conditions => "posts.title like 'Welcome%'")
793
- end
794
- assert_equal authors(:david), authors[0]
795
- assert_equal author_addresses(:david_address), authors[0].author_address
796
- end
797
-
798
- def test_preload_belongs_to_uses_exclusive_scope
799
- people = Person.males.find(:all, :include => :primary_contact)
800
- assert_not_equal people.length, 0
801
- people.each do |person|
802
- assert_no_queries {assert_not_nil person.primary_contact}
803
- assert_equal Person.find(person.id).primary_contact, person.primary_contact
804
- end
805
- end
806
-
807
- def test_preload_has_many_uses_exclusive_scope
808
- people = Person.males.find :all, :include => :agents
809
- people.each do |person|
810
- assert_equal Person.find(person.id).agents, person.agents
811
- end
812
- end
813
-
814
- def test_preload_has_many_using_primary_key
815
- expected = Firm.find(:first).clients_using_primary_key.to_a
816
- firm = Firm.find :first, :include => :clients_using_primary_key
817
- assert_no_queries do
818
- assert_equal expected, firm.clients_using_primary_key
819
- end
820
- end
821
-
822
- def test_include_has_many_using_primary_key
823
- expected = Firm.find(1).clients_using_primary_key.sort_by &:name
824
- firm = Firm.find 1, :include => :clients_using_primary_key, :order => 'clients_using_primary_keys_companies.name'
825
- assert_no_queries do
826
- assert_equal expected, firm.clients_using_primary_key
827
- end
828
- end
829
-
830
- def test_preload_has_one_using_primary_key
831
- expected = Firm.find(:first).account_using_primary_key
832
- firm = Firm.find :first, :include => :account_using_primary_key
833
- assert_no_queries do
834
- assert_equal expected, firm.account_using_primary_key
835
- end
836
- end
837
-
838
- def test_include_has_one_using_primary_key
839
- expected = Firm.find(1).account_using_primary_key
840
- firm = Firm.find(:all, :include => :account_using_primary_key, :order => 'accounts.id').detect {|f| f.id == 1}
841
- assert_no_queries do
842
- assert_equal expected, firm.account_using_primary_key
843
- end
844
- end
845
-
846
- def test_preloading_empty_polymorphic_parent
847
- t = Tagging.create!(:taggable_type => 'Post', :taggable_id => Post.maximum(:id) + 1, :tag => tags(:general))
848
-
849
- assert_queries(2) { @tagging = Tagging.find(t.id, :include => :taggable) }
850
- assert_no_queries { assert ! @tagging.taggable }
851
- end
852
- end