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,209 +0,0 @@
1
- require "cases/helper"
2
- require 'models/club'
3
- require 'models/member_type'
4
- require 'models/member'
5
- require 'models/membership'
6
- require 'models/sponsor'
7
- require 'models/organization'
8
- require 'models/member_detail'
9
-
10
- class HasOneThroughAssociationsTest < ActiveRecord::TestCase
11
- fixtures :member_types, :members, :clubs, :memberships, :sponsors, :organizations
12
-
13
- def setup
14
- @member = members(:groucho)
15
- end
16
-
17
- def test_has_one_through_with_has_one
18
- assert_equal clubs(:boring_club), @member.club
19
- end
20
-
21
- def test_has_one_through_with_has_many
22
- assert_equal clubs(:moustache_club), @member.favourite_club
23
- end
24
-
25
- def test_creating_association_creates_through_record
26
- new_member = Member.create(:name => "Chris")
27
- new_member.club = Club.create(:name => "LRUG")
28
- assert_not_nil new_member.current_membership
29
- assert_not_nil new_member.club
30
- end
31
-
32
- def test_creating_association_builds_through_record_for_new
33
- new_member = Member.new(:name => "Jane")
34
- new_member.club = clubs(:moustache_club)
35
- assert new_member.current_membership
36
- assert_equal clubs(:moustache_club), new_member.current_membership.club
37
- assert_equal clubs(:moustache_club), new_member.club
38
- assert new_member.save
39
- assert_equal clubs(:moustache_club), new_member.club
40
- end
41
-
42
- def test_replace_target_record
43
- new_club = Club.create(:name => "Marx Bros")
44
- @member.club = new_club
45
- @member.reload
46
- assert_equal new_club, @member.club
47
- end
48
-
49
- def test_replacing_target_record_deletes_old_association
50
- assert_no_difference "Membership.count" do
51
- new_club = Club.create(:name => "Bananarama")
52
- @member.club = new_club
53
- @member.reload
54
- end
55
- end
56
-
57
- def test_set_record_to_nil_should_delete_association
58
- @member.club = nil
59
- @member.reload
60
- assert_equal nil, @member.current_membership
61
- assert_nil @member.club
62
- end
63
-
64
- def test_has_one_through_polymorphic
65
- assert_equal clubs(:moustache_club), @member.sponsor_club
66
- end
67
-
68
- def has_one_through_to_has_many
69
- assert_equal 2, @member.fellow_members.size
70
- end
71
-
72
- def test_has_one_through_eager_loading
73
- members = assert_queries(3) do #base table, through table, clubs table
74
- Member.find(:all, :include => :club, :conditions => ["name = ?", "Groucho Marx"])
75
- end
76
- assert_equal 1, members.size
77
- assert_not_nil assert_no_queries {members[0].club}
78
- end
79
-
80
- def test_has_one_through_eager_loading_through_polymorphic
81
- members = assert_queries(3) do #base table, through table, clubs table
82
- Member.find(:all, :include => :sponsor_club, :conditions => ["name = ?", "Groucho Marx"])
83
- end
84
- assert_equal 1, members.size
85
- assert_not_nil assert_no_queries {members[0].sponsor_club}
86
- end
87
-
88
- def test_has_one_through_polymorphic_with_source_type
89
- assert_equal members(:groucho), clubs(:moustache_club).sponsored_member
90
- end
91
-
92
- def test_eager_has_one_through_polymorphic_with_source_type
93
- clubs = Club.find(:all, :include => :sponsored_member, :conditions => ["name = ?","Moustache and Eyebrow Fancier Club"])
94
- # Only the eyebrow fanciers club has a sponsored_member
95
- assert_not_nil assert_no_queries {clubs[0].sponsored_member}
96
- end
97
-
98
- def test_has_one_through_nonpreload_eagerloading
99
- members = assert_queries(1) do
100
- Member.find(:all, :include => :club, :conditions => ["members.name = ?", "Groucho Marx"], :order => 'clubs.name') #force fallback
101
- end
102
- assert_equal 1, members.size
103
- assert_not_nil assert_no_queries {members[0].club}
104
- end
105
-
106
- def test_has_one_through_nonpreload_eager_loading_through_polymorphic
107
- members = assert_queries(1) do
108
- Member.find(:all, :include => :sponsor_club, :conditions => ["members.name = ?", "Groucho Marx"], :order => 'clubs.name') #force fallback
109
- end
110
- assert_equal 1, members.size
111
- assert_not_nil assert_no_queries {members[0].sponsor_club}
112
- end
113
-
114
- def test_has_one_through_nonpreload_eager_loading_through_polymorphic_with_more_than_one_through_record
115
- Sponsor.new(:sponsor_club => clubs(:crazy_club), :sponsorable => members(:groucho)).save!
116
- members = assert_queries(1) do
117
- Member.find(:all, :include => :sponsor_club, :conditions => ["members.name = ?", "Groucho Marx"], :order => 'clubs.name DESC') #force fallback
118
- end
119
- assert_equal 1, members.size
120
- assert_not_nil assert_no_queries { members[0].sponsor_club }
121
- assert_equal clubs(:crazy_club), members[0].sponsor_club
122
- end
123
-
124
- def test_uninitialized_has_one_through_should_return_nil_for_unsaved_record
125
- assert_nil Member.new.club
126
- end
127
-
128
- def test_assigning_association_correctly_assigns_target
129
- new_member = Member.create(:name => "Chris")
130
- new_member.club = new_club = Club.create(:name => "LRUG")
131
- assert_equal new_club, new_member.club.target
132
- end
133
-
134
- def test_has_one_through_proxy_should_not_respond_to_private_methods
135
- assert_raise(NoMethodError) { clubs(:moustache_club).private_method }
136
- assert_raise(NoMethodError) { @member.club.private_method }
137
- end
138
-
139
- def test_has_one_through_proxy_should_respond_to_private_methods_via_send
140
- clubs(:moustache_club).send(:private_method)
141
- @member.club.send(:private_method)
142
- end
143
-
144
- def test_assigning_to_has_one_through_preserves_decorated_join_record
145
- @organization = organizations(:nsa)
146
- assert_difference 'MemberDetail.count', 1 do
147
- @member_detail = MemberDetail.new(:extra_data => 'Extra')
148
- @member.member_detail = @member_detail
149
- @member.organization = @organization
150
- end
151
- assert_equal @organization, @member.organization
152
- assert @organization.members.include?(@member)
153
- assert_equal 'Extra', @member.member_detail.extra_data
154
- end
155
-
156
- def test_reassigning_has_one_through
157
- @organization = organizations(:nsa)
158
- @new_organization = organizations(:discordians)
159
-
160
- assert_difference 'MemberDetail.count', 1 do
161
- @member_detail = MemberDetail.new(:extra_data => 'Extra')
162
- @member.member_detail = @member_detail
163
- @member.organization = @organization
164
- end
165
- assert_equal @organization, @member.organization
166
- assert_equal 'Extra', @member.member_detail.extra_data
167
- assert @organization.members.include?(@member)
168
- assert !@new_organization.members.include?(@member)
169
-
170
- assert_no_difference 'MemberDetail.count' do
171
- @member.organization = @new_organization
172
- end
173
- assert_equal @new_organization, @member.organization
174
- assert_equal 'Extra', @member.member_detail.extra_data
175
- assert !@organization.members.include?(@member)
176
- assert @new_organization.members.include?(@member)
177
- end
178
-
179
- def test_preloading_has_one_through_on_belongs_to
180
- assert_not_nil @member.member_type
181
- @organization = organizations(:nsa)
182
- @member_detail = MemberDetail.new
183
- @member.member_detail = @member_detail
184
- @member.organization = @organization
185
- @member_details = assert_queries(3) do
186
- MemberDetail.find(:all, :include => :member_type)
187
- end
188
- @new_detail = @member_details[0]
189
- assert @new_detail.loaded_member_type?
190
- assert_not_nil assert_no_queries { @new_detail.member_type }
191
- end
192
-
193
- def test_save_of_record_with_loaded_has_one_through
194
- @club = @member.club
195
- assert_not_nil @club.sponsored_member
196
-
197
- assert_nothing_raised do
198
- Club.find(@club.id).save!
199
- Club.find(@club.id, :include => :sponsored_member).save!
200
- end
201
-
202
- @club.sponsor.destroy
203
-
204
- assert_nothing_raised do
205
- Club.find(@club.id).save!
206
- Club.find(@club.id, :include => :sponsored_member).save!
207
- end
208
- end
209
- end
@@ -1,93 +0,0 @@
1
- require "cases/helper"
2
- require 'models/post'
3
- require 'models/comment'
4
- require 'models/author'
5
- require 'models/category'
6
- require 'models/categorization'
7
-
8
- class InnerJoinAssociationTest < ActiveRecord::TestCase
9
- fixtures :authors, :posts, :comments, :categories, :categories_posts, :categorizations
10
-
11
- def test_construct_finder_sql_creates_inner_joins
12
- sql = Author.send(:construct_finder_sql, :joins => :posts)
13
- assert_match /INNER JOIN .?posts.? ON .?posts.?.author_id = authors.id/, sql
14
- end
15
-
16
- def test_construct_finder_sql_cascades_inner_joins
17
- sql = Author.send(:construct_finder_sql, :joins => {:posts => :comments})
18
- assert_match /INNER JOIN .?posts.? ON .?posts.?.author_id = authors.id/, sql
19
- assert_match /INNER JOIN .?comments.? ON .?comments.?.post_id = posts.id/, sql
20
- end
21
-
22
- def test_construct_finder_sql_inner_joins_through_associations
23
- sql = Author.send(:construct_finder_sql, :joins => :categorized_posts)
24
- assert_match /INNER JOIN .?categorizations.?.*INNER JOIN .?posts.?/, sql
25
- end
26
-
27
- def test_construct_finder_sql_applies_association_conditions
28
- sql = Author.send(:construct_finder_sql, :joins => :categories_like_general, :conditions => "TERMINATING_MARKER")
29
- assert_match /INNER JOIN .?categories.? ON.*AND.*.?General.?.*TERMINATING_MARKER/, sql
30
- end
31
-
32
- def test_construct_finder_sql_applies_aliases_tables_on_association_conditions
33
- result = Author.find(:all, :joins => [:thinking_posts, :welcome_posts])
34
- assert_equal authors(:david), result.first
35
- end
36
-
37
- def test_construct_finder_sql_unpacks_nested_joins
38
- sql = Author.send(:construct_finder_sql, :joins => {:posts => [[:comments]]})
39
- assert_no_match /inner join.*inner join.*inner join/i, sql, "only two join clauses should be present"
40
- assert_match /INNER JOIN .?posts.? ON .?posts.?.author_id = authors.id/, sql
41
- assert_match /INNER JOIN .?comments.? ON .?comments.?.post_id = .?posts.?.id/, sql
42
- end
43
-
44
- def test_construct_finder_sql_ignores_empty_joins_hash
45
- sql = Author.send(:construct_finder_sql, :joins => {})
46
- assert_no_match /JOIN/i, sql
47
- end
48
-
49
- def test_construct_finder_sql_ignores_empty_joins_array
50
- sql = Author.send(:construct_finder_sql, :joins => [])
51
- assert_no_match /JOIN/i, sql
52
- end
53
-
54
- def test_find_with_implicit_inner_joins_honors_readonly_without_select
55
- authors = Author.find(:all, :joins => :posts)
56
- assert !authors.empty?, "expected authors to be non-empty"
57
- assert authors.all? {|a| a.readonly? }, "expected all authors to be readonly"
58
- end
59
-
60
- def test_find_with_implicit_inner_joins_honors_readonly_with_select
61
- authors = Author.find(:all, :select => 'authors.*', :joins => :posts)
62
- assert !authors.empty?, "expected authors to be non-empty"
63
- assert authors.all? {|a| !a.readonly? }, "expected no authors to be readonly"
64
- end
65
-
66
- def test_find_with_implicit_inner_joins_honors_readonly_false
67
- authors = Author.find(:all, :joins => :posts, :readonly => false)
68
- assert !authors.empty?, "expected authors to be non-empty"
69
- assert authors.all? {|a| !a.readonly? }, "expected no authors to be readonly"
70
- end
71
-
72
- def test_find_with_implicit_inner_joins_does_not_set_associations
73
- authors = Author.find(:all, :select => 'authors.*', :joins => :posts)
74
- assert !authors.empty?, "expected authors to be non-empty"
75
- assert authors.all? {|a| !a.send(:instance_variable_names).include?("@posts")}, "expected no authors to have the @posts association loaded"
76
- end
77
-
78
- def test_count_honors_implicit_inner_joins
79
- real_count = Author.find(:all).sum{|a| a.posts.count }
80
- assert_equal real_count, Author.count(:joins => :posts), "plain inner join count should match the number of referenced posts records"
81
- end
82
-
83
- def test_calculate_honors_implicit_inner_joins
84
- real_count = Author.find(:all).sum{|a| a.posts.count }
85
- assert_equal real_count, Author.calculate(:count, 'authors.id', :joins => :posts), "plain inner join count should match the number of referenced posts records"
86
- end
87
-
88
- def test_calculate_honors_implicit_inner_joins_and_distinct_and_conditions
89
- real_count = Author.find(:all).select {|a| a.posts.any? {|p| p.title =~ /^Welcome/} }.length
90
- authors_with_welcoming_post_titles = Author.calculate(:count, 'authors.id', :joins => :posts, :distinct => true, :conditions => "posts.title like 'Welcome%'")
91
- assert_equal real_count, authors_with_welcoming_post_titles, "inner join and conditions should have only returned authors posting titles starting with 'Welcome'"
92
- end
93
- end
@@ -1,566 +0,0 @@
1
- require "cases/helper"
2
- require 'models/man'
3
- require 'models/face'
4
- require 'models/interest'
5
- require 'models/zine'
6
- require 'models/club'
7
- require 'models/sponsor'
8
-
9
- class InverseAssociationTests < ActiveRecord::TestCase
10
- def test_should_allow_for_inverse_of_options_in_associations
11
- assert_nothing_raised(ArgumentError, 'ActiveRecord should allow the inverse_of options on has_many') do
12
- Class.new(ActiveRecord::Base).has_many(:wheels, :inverse_of => :car)
13
- end
14
-
15
- assert_nothing_raised(ArgumentError, 'ActiveRecord should allow the inverse_of options on has_one') do
16
- Class.new(ActiveRecord::Base).has_one(:engine, :inverse_of => :car)
17
- end
18
-
19
- assert_nothing_raised(ArgumentError, 'ActiveRecord should allow the inverse_of options on belongs_to') do
20
- Class.new(ActiveRecord::Base).belongs_to(:car, :inverse_of => :driver)
21
- end
22
- end
23
-
24
- def test_should_be_able_to_ask_a_reflection_if_it_has_an_inverse
25
- has_one_with_inverse_ref = Man.reflect_on_association(:face)
26
- assert has_one_with_inverse_ref.respond_to?(:has_inverse?)
27
- assert has_one_with_inverse_ref.has_inverse?
28
-
29
- has_many_with_inverse_ref = Man.reflect_on_association(:interests)
30
- assert has_many_with_inverse_ref.respond_to?(:has_inverse?)
31
- assert has_many_with_inverse_ref.has_inverse?
32
-
33
- belongs_to_with_inverse_ref = Face.reflect_on_association(:man)
34
- assert belongs_to_with_inverse_ref.respond_to?(:has_inverse?)
35
- assert belongs_to_with_inverse_ref.has_inverse?
36
-
37
- has_one_without_inverse_ref = Club.reflect_on_association(:sponsor)
38
- assert has_one_without_inverse_ref.respond_to?(:has_inverse?)
39
- assert !has_one_without_inverse_ref.has_inverse?
40
-
41
- has_many_without_inverse_ref = Club.reflect_on_association(:memberships)
42
- assert has_many_without_inverse_ref.respond_to?(:has_inverse?)
43
- assert !has_many_without_inverse_ref.has_inverse?
44
-
45
- belongs_to_without_inverse_ref = Sponsor.reflect_on_association(:sponsor_club)
46
- assert belongs_to_without_inverse_ref.respond_to?(:has_inverse?)
47
- assert !belongs_to_without_inverse_ref.has_inverse?
48
- end
49
-
50
- def test_should_be_able_to_ask_a_reflection_what_it_is_the_inverse_of
51
- has_one_ref = Man.reflect_on_association(:face)
52
- assert has_one_ref.respond_to?(:inverse_of)
53
-
54
- has_many_ref = Man.reflect_on_association(:interests)
55
- assert has_many_ref.respond_to?(:inverse_of)
56
-
57
- belongs_to_ref = Face.reflect_on_association(:man)
58
- assert belongs_to_ref.respond_to?(:inverse_of)
59
- end
60
-
61
- def test_inverse_of_method_should_supply_the_actual_reflection_instance_it_is_the_inverse_of
62
- has_one_ref = Man.reflect_on_association(:face)
63
- assert_equal Face.reflect_on_association(:man), has_one_ref.inverse_of
64
-
65
- has_many_ref = Man.reflect_on_association(:interests)
66
- assert_equal Interest.reflect_on_association(:man), has_many_ref.inverse_of
67
-
68
- belongs_to_ref = Face.reflect_on_association(:man)
69
- assert_equal Man.reflect_on_association(:face), belongs_to_ref.inverse_of
70
- end
71
-
72
- def test_associations_with_no_inverse_of_should_return_nil
73
- has_one_ref = Club.reflect_on_association(:sponsor)
74
- assert_nil has_one_ref.inverse_of
75
-
76
- has_many_ref = Club.reflect_on_association(:memberships)
77
- assert_nil has_many_ref.inverse_of
78
-
79
- belongs_to_ref = Sponsor.reflect_on_association(:sponsor_club)
80
- assert_nil belongs_to_ref.inverse_of
81
- end
82
- end
83
-
84
- class InverseHasOneTests < ActiveRecord::TestCase
85
- fixtures :men, :faces
86
-
87
- def test_parent_instance_should_be_shared_with_child_on_find
88
- m = men(:gordon)
89
- f = m.face
90
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
91
- m.name = 'Bongo'
92
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
93
- f.man.name = 'Mungo'
94
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to child-owned instance"
95
- end
96
-
97
- def test_parent_instance_should_be_shared_with_eager_loaded_child_on_find
98
- m = Man.find(:first, :conditions => {:name => 'Gordon'}, :include => :face)
99
- f = m.face
100
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
101
- m.name = 'Bongo'
102
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
103
- f.man.name = 'Mungo'
104
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to child-owned instance"
105
-
106
- m = Man.find(:first, :conditions => {:name => 'Gordon'}, :include => :face, :order => 'faces.id')
107
- f = m.face
108
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
109
- m.name = 'Bongo'
110
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
111
- f.man.name = 'Mungo'
112
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to child-owned instance"
113
- end
114
-
115
- def test_parent_instance_should_be_shared_with_newly_built_child
116
- m = men(:gordon)
117
- f = m.build_face(:description => 'haunted')
118
- assert_not_nil f.man
119
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
120
- m.name = 'Bongo'
121
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
122
- f.man.name = 'Mungo'
123
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to just-built-child-owned instance"
124
- end
125
-
126
- def test_parent_instance_should_be_shared_with_newly_created_child
127
- m = men(:gordon)
128
- f = m.create_face(:description => 'haunted')
129
- assert_not_nil f.man
130
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
131
- m.name = 'Bongo'
132
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
133
- f.man.name = 'Mungo'
134
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to newly-created-child-owned instance"
135
- end
136
-
137
- def test_parent_instance_should_be_shared_with_newly_created_child_via_bang_method
138
- m = Man.find(:first)
139
- f = m.face.create!(:description => 'haunted')
140
- assert_not_nil f.man
141
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
142
- m.name = 'Bongo'
143
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
144
- f.man.name = 'Mungo'
145
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to newly-created-child-owned instance"
146
- end
147
-
148
- def test_parent_instance_should_be_shared_with_newly_built_child_when_we_dont_replace_existing
149
- m = Man.find(:first)
150
- f = m.build_face({:description => 'haunted'}, false)
151
- assert_not_nil f.man
152
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
153
- m.name = 'Bongo'
154
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
155
- f.man.name = 'Mungo'
156
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to just-built-child-owned instance"
157
- end
158
-
159
- def test_parent_instance_should_be_shared_with_newly_created_child_when_we_dont_replace_existing
160
- m = Man.find(:first)
161
- f = m.create_face({:description => 'haunted'}, false)
162
- assert_not_nil f.man
163
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
164
- m.name = 'Bongo'
165
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
166
- f.man.name = 'Mungo'
167
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to newly-created-child-owned instance"
168
- end
169
-
170
- def test_parent_instance_should_be_shared_with_newly_created_child_via_bang_method_when_we_dont_replace_existing
171
- m = Man.find(:first)
172
- f = m.face.create!({:description => 'haunted'}, false)
173
- assert_not_nil f.man
174
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
175
- m.name = 'Bongo'
176
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
177
- f.man.name = 'Mungo'
178
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to newly-created-child-owned instance"
179
- end
180
-
181
- def test_parent_instance_should_be_shared_with_replaced_via_accessor_child
182
- m = Man.find(:first)
183
- f = Face.new(:description => 'haunted')
184
- m.face = f
185
- assert_not_nil f.man
186
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
187
- m.name = 'Bongo'
188
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
189
- f.man.name = 'Mungo'
190
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to replaced-child-owned instance"
191
- end
192
-
193
- def test_parent_instance_should_be_shared_with_replaced_via_method_child
194
- m = Man.find(:first)
195
- f = Face.new(:description => 'haunted')
196
- m.face.replace(f)
197
- assert_not_nil f.man
198
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
199
- m.name = 'Bongo'
200
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
201
- f.man.name = 'Mungo'
202
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to replaced-child-owned instance"
203
- end
204
-
205
- def test_parent_instance_should_be_shared_with_replaced_via_method_child_when_we_dont_replace_existing
206
- m = Man.find(:first)
207
- f = Face.new(:description => 'haunted')
208
- m.face.replace(f, false)
209
- assert_not_nil f.man
210
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
211
- m.name = 'Bongo'
212
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
213
- f.man.name = 'Mungo'
214
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to replaced-child-owned instance"
215
- end
216
-
217
- def test_trying_to_use_inverses_that_dont_exist_should_raise_an_error
218
- assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Man.find(:first).dirty_face }
219
- end
220
- end
221
-
222
- class InverseHasManyTests < ActiveRecord::TestCase
223
- fixtures :men, :interests
224
-
225
- def test_parent_instance_should_be_shared_with_every_child_on_find
226
- m = men(:gordon)
227
- is = m.interests
228
- is.each do |i|
229
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
230
- m.name = 'Bongo'
231
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
232
- i.man.name = 'Mungo'
233
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to child-owned instance"
234
- end
235
- end
236
-
237
- def test_parent_instance_should_be_shared_with_eager_loaded_children
238
- m = Man.find(:first, :conditions => {:name => 'Gordon'}, :include => :interests)
239
- is = m.interests
240
- is.each do |i|
241
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
242
- m.name = 'Bongo'
243
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
244
- i.man.name = 'Mungo'
245
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to child-owned instance"
246
- end
247
-
248
- m = Man.find(:first, :conditions => {:name => 'Gordon'}, :include => :interests, :order => 'interests.id')
249
- is = m.interests
250
- is.each do |i|
251
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
252
- m.name = 'Bongo'
253
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
254
- i.man.name = 'Mungo'
255
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to child-owned instance"
256
- end
257
- end
258
-
259
- def test_parent_instance_should_be_shared_with_newly_built_child
260
- m = men(:gordon)
261
- i = m.interests.build(:topic => 'Industrial Revolution Re-enactment')
262
- assert_not_nil i.man
263
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
264
- m.name = 'Bongo'
265
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
266
- i.man.name = 'Mungo'
267
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to just-built-child-owned instance"
268
- end
269
-
270
- def test_parent_instance_should_be_shared_with_newly_block_style_built_child
271
- m = Man.find(:first)
272
- i = m.interests.build {|ii| ii.topic = 'Industrial Revolution Re-enactment'}
273
- assert_not_nil i.topic, "Child attributes supplied to build via blocks should be populated"
274
- assert_not_nil i.man
275
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
276
- m.name = 'Bongo'
277
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
278
- i.man.name = 'Mungo'
279
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to just-built-child-owned instance"
280
- end
281
-
282
- def test_parent_instance_should_be_shared_with_newly_created_child
283
- m = men(:gordon)
284
- i = m.interests.create(:topic => 'Industrial Revolution Re-enactment')
285
- assert_not_nil i.man
286
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
287
- m.name = 'Bongo'
288
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
289
- i.man.name = 'Mungo'
290
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to newly-created-child-owned instance"
291
- end
292
-
293
- def test_parent_instance_should_be_shared_with_newly_created_via_bang_method_child
294
- m = Man.find(:first)
295
- i = m.interests.create!(:topic => 'Industrial Revolution Re-enactment')
296
- assert_not_nil i.man
297
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
298
- m.name = 'Bongo'
299
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
300
- i.man.name = 'Mungo'
301
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to newly-created-child-owned instance"
302
- end
303
-
304
- def test_parent_instance_should_be_shared_with_newly_block_style_created_child
305
- m = Man.find(:first)
306
- i = m.interests.create {|ii| ii.topic = 'Industrial Revolution Re-enactment'}
307
- assert_not_nil i.topic, "Child attributes supplied to create via blocks should be populated"
308
- assert_not_nil i.man
309
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
310
- m.name = 'Bongo'
311
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
312
- i.man.name = 'Mungo'
313
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to newly-created-child-owned instance"
314
- end
315
-
316
- def test_parent_instance_should_be_shared_with_poked_in_child
317
- m = men(:gordon)
318
- i = Interest.create(:topic => 'Industrial Revolution Re-enactment')
319
- m.interests << i
320
- assert_not_nil i.man
321
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
322
- m.name = 'Bongo'
323
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
324
- i.man.name = 'Mungo'
325
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to newly-created-child-owned instance"
326
- end
327
-
328
- def test_parent_instance_should_be_shared_with_replaced_via_accessor_children
329
- m = Man.find(:first)
330
- i = Interest.new(:topic => 'Industrial Revolution Re-enactment')
331
- m.interests = [i]
332
- assert_not_nil i.man
333
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
334
- m.name = 'Bongo'
335
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
336
- i.man.name = 'Mungo'
337
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to replaced-child-owned instance"
338
- end
339
-
340
- def test_parent_instance_should_be_shared_with_replaced_via_method_children
341
- m = Man.find(:first)
342
- i = Interest.new(:topic => 'Industrial Revolution Re-enactment')
343
- m.interests.replace([i])
344
- assert_not_nil i.man
345
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
346
- m.name = 'Bongo'
347
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
348
- i.man.name = 'Mungo'
349
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to replaced-child-owned instance"
350
- end
351
-
352
- def test_trying_to_use_inverses_that_dont_exist_should_raise_an_error
353
- assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Man.find(:first).secret_interests }
354
- end
355
- end
356
-
357
- class InverseBelongsToTests < ActiveRecord::TestCase
358
- fixtures :men, :faces, :interests
359
-
360
- def test_child_instance_should_be_shared_with_parent_on_find
361
- f = faces(:trusting)
362
- m = f.man
363
- assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance"
364
- f.description = 'gormless'
365
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance"
366
- m.face.description = 'pleasing'
367
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to parent-owned instance"
368
- end
369
-
370
- def test_eager_loaded_child_instance_should_be_shared_with_parent_on_find
371
- f = Face.find(:first, :include => :man, :conditions => {:description => 'trusting'})
372
- m = f.man
373
- assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance"
374
- f.description = 'gormless'
375
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance"
376
- m.face.description = 'pleasing'
377
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to parent-owned instance"
378
-
379
- f = Face.find(:first, :include => :man, :order => 'men.id', :conditions => {:description => 'trusting'})
380
- m = f.man
381
- assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance"
382
- f.description = 'gormless'
383
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance"
384
- m.face.description = 'pleasing'
385
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to parent-owned instance"
386
- end
387
-
388
- def test_child_instance_should_be_shared_with_newly_built_parent
389
- f = faces(:trusting)
390
- m = f.build_man(:name => 'Charles')
391
- assert_not_nil m.face
392
- assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance"
393
- f.description = 'gormless'
394
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance"
395
- m.face.description = 'pleasing'
396
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to just-built-parent-owned instance"
397
- end
398
-
399
- def test_child_instance_should_be_shared_with_newly_created_parent
400
- f = faces(:trusting)
401
- m = f.create_man(:name => 'Charles')
402
- assert_not_nil m.face
403
- assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance"
404
- f.description = 'gormless'
405
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance"
406
- m.face.description = 'pleasing'
407
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to newly-created-parent-owned instance"
408
- end
409
-
410
- def test_should_not_try_to_set_inverse_instances_when_the_inverse_is_a_has_many
411
- i = interests(:trainspotting)
412
- m = i.man
413
- assert_not_nil m.interests
414
- iz = m.interests.detect {|iz| iz.id == i.id}
415
- assert_not_nil iz
416
- assert_equal i.topic, iz.topic, "Interest topics should be the same before changes to child"
417
- i.topic = 'Eating cheese with a spoon'
418
- assert_not_equal i.topic, iz.topic, "Interest topics should not be the same after changes to child"
419
- iz.topic = 'Cow tipping'
420
- assert_not_equal i.topic, iz.topic, "Interest topics should not be the same after changes to parent-owned instance"
421
- end
422
-
423
- def test_child_instance_should_be_shared_with_replaced_via_accessor_parent
424
- f = Face.find(:first)
425
- m = Man.new(:name => 'Charles')
426
- f.man = m
427
- assert_not_nil m.face
428
- assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance"
429
- f.description = 'gormless'
430
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance"
431
- m.face.description = 'pleasing'
432
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to replaced-parent-owned instance"
433
- end
434
-
435
- def test_child_instance_should_be_shared_with_replaced_via_method_parent
436
- f = faces(:trusting)
437
- assert_not_nil f.man
438
- m = Man.new(:name => 'Charles')
439
- f.man.replace(m)
440
- assert_not_nil m.face
441
- assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance"
442
- f.description = 'gormless'
443
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance"
444
- m.face.description = 'pleasing'
445
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to replaced-parent-owned instance"
446
- end
447
-
448
- def test_trying_to_use_inverses_that_dont_exist_should_raise_an_error
449
- assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Face.find(:first).horrible_man }
450
- end
451
- end
452
-
453
- class InversePolymorphicBelongsToTests < ActiveRecord::TestCase
454
- fixtures :men, :faces, :interests
455
-
456
- def test_child_instance_should_be_shared_with_parent_on_find
457
- f = Face.find(:first, :conditions => {:description => 'confused'})
458
- m = f.polymorphic_man
459
- assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same before changes to child instance"
460
- f.description = 'gormless'
461
- assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same after changes to child instance"
462
- m.polymorphic_face.description = 'pleasing'
463
- assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same after changes to parent-owned instance"
464
- end
465
-
466
- def test_eager_loaded_child_instance_should_be_shared_with_parent_on_find
467
- f = Face.find(:first, :conditions => {:description => 'confused'}, :include => :man)
468
- m = f.polymorphic_man
469
- assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same before changes to child instance"
470
- f.description = 'gormless'
471
- assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same after changes to child instance"
472
- m.polymorphic_face.description = 'pleasing'
473
- assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same after changes to parent-owned instance"
474
-
475
- f = Face.find(:first, :conditions => {:description => 'confused'}, :include => :man, :order => 'men.id')
476
- m = f.polymorphic_man
477
- assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same before changes to child instance"
478
- f.description = 'gormless'
479
- assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same after changes to child instance"
480
- m.polymorphic_face.description = 'pleasing'
481
- assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same after changes to parent-owned instance"
482
- end
483
-
484
- def test_child_instance_should_be_shared_with_replaced_via_accessor_parent
485
- face = faces(:confused)
486
- old_man = face.polymorphic_man
487
- new_man = Man.new
488
-
489
- assert_not_nil face.polymorphic_man
490
- face.polymorphic_man = new_man
491
-
492
- assert_equal face.description, new_man.polymorphic_face.description, "Description of face should be the same before changes to parent instance"
493
- face.description = 'Bongo'
494
- assert_equal face.description, new_man.polymorphic_face.description, "Description of face should be the same after changes to parent instance"
495
- new_man.polymorphic_face.description = 'Mungo'
496
- assert_equal face.description, new_man.polymorphic_face.description, "Description of face should be the same after changes to replaced-parent-owned instance"
497
- end
498
-
499
- def test_child_instance_should_be_shared_with_replaced_via_method_parent
500
- face = faces(:confused)
501
- old_man = face.polymorphic_man
502
- new_man = Man.new
503
-
504
- assert_not_nil face.polymorphic_man
505
- face.polymorphic_man.replace(new_man)
506
-
507
- assert_equal face.description, new_man.polymorphic_face.description, "Description of face should be the same before changes to parent instance"
508
- face.description = 'Bongo'
509
- assert_equal face.description, new_man.polymorphic_face.description, "Description of face should be the same after changes to parent instance"
510
- new_man.polymorphic_face.description = 'Mungo'
511
- assert_equal face.description, new_man.polymorphic_face.description, "Description of face should be the same after changes to replaced-parent-owned instance"
512
- end
513
-
514
- def test_should_not_try_to_set_inverse_instances_when_the_inverse_is_a_has_many
515
- i = interests(:llama_wrangling)
516
- m = i.polymorphic_man
517
- assert_not_nil m.polymorphic_interests
518
- iz = m.polymorphic_interests.detect {|iz| iz.id == i.id}
519
- assert_not_nil iz
520
- assert_equal i.topic, iz.topic, "Interest topics should be the same before changes to child"
521
- i.topic = 'Eating cheese with a spoon'
522
- assert_not_equal i.topic, iz.topic, "Interest topics should not be the same after changes to child"
523
- iz.topic = 'Cow tipping'
524
- assert_not_equal i.topic, iz.topic, "Interest topics should not be the same after changes to parent-owned instance"
525
- end
526
-
527
- def test_trying_to_access_inverses_that_dont_exist_shouldnt_raise_an_error
528
- # Ideally this would, if only for symmetry's sake with other association types
529
- assert_nothing_raised(ActiveRecord::InverseOfAssociationNotFoundError) { Face.find(:first).horrible_polymorphic_man }
530
- end
531
-
532
- def test_trying_to_set_polymorphic_inverses_that_dont_exist_at_all_should_raise_an_error
533
- # fails because no class has the correct inverse_of for horrible_polymorphic_man
534
- assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Face.find(:first).horrible_polymorphic_man = Man.first }
535
- end
536
-
537
- def test_trying_to_set_polymorphic_inverses_that_dont_exist_on_the_instance_being_set_should_raise_an_error
538
- # passes because Man does have the correct inverse_of
539
- assert_nothing_raised(ActiveRecord::InverseOfAssociationNotFoundError) { Face.find(:first).polymorphic_man = Man.first }
540
- # fails because Interest does have the correct inverse_of
541
- assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Face.find(:first).polymorphic_man = Interest.first }
542
- end
543
- end
544
-
545
- # NOTE - these tests might not be meaningful, ripped as they were from the parental_control plugin
546
- # which would guess the inverse rather than look for an explicit configuration option.
547
- class InverseMultipleHasManyInversesForSameModel < ActiveRecord::TestCase
548
- fixtures :men, :interests, :zines
549
-
550
- def test_that_we_can_load_associations_that_have_the_same_reciprocal_name_from_different_models
551
- assert_nothing_raised(ActiveRecord::AssociationTypeMismatch) do
552
- i = Interest.find(:first)
553
- z = i.zine
554
- m = i.man
555
- end
556
- end
557
-
558
- def test_that_we_can_create_associations_that_have_the_same_reciprocal_name_from_different_models
559
- assert_nothing_raised(ActiveRecord::AssociationTypeMismatch) do
560
- i = Interest.find(:first)
561
- i.build_zine(:title => 'Get Some in Winter! 2008')
562
- i.build_man(:name => 'Gordon')
563
- i.save!
564
- end
565
- end
566
- end