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,62 +0,0 @@
1
- require "cases/helper"
2
- require 'models/post'
3
- require 'models/comment'
4
- require 'models/project'
5
- require 'models/developer'
6
- require 'models/company_in_module'
7
-
8
- class AssociationsExtensionsTest < ActiveRecord::TestCase
9
- fixtures :projects, :developers, :developers_projects, :comments, :posts
10
-
11
- def test_extension_on_has_many
12
- assert_equal comments(:more_greetings), posts(:welcome).comments.find_most_recent
13
- end
14
-
15
- def test_extension_on_habtm
16
- assert_equal projects(:action_controller), developers(:david).projects.find_most_recent
17
- end
18
-
19
- def test_named_extension_on_habtm
20
- assert_equal projects(:action_controller), developers(:david).projects_extended_by_name.find_most_recent
21
- end
22
-
23
- def test_named_two_extensions_on_habtm
24
- assert_equal projects(:action_controller), developers(:david).projects_extended_by_name_twice.find_most_recent
25
- assert_equal projects(:active_record), developers(:david).projects_extended_by_name_twice.find_least_recent
26
- end
27
-
28
- def test_named_extension_and_block_on_habtm
29
- assert_equal projects(:action_controller), developers(:david).projects_extended_by_name_and_block.find_most_recent
30
- assert_equal projects(:active_record), developers(:david).projects_extended_by_name_and_block.find_least_recent
31
- end
32
-
33
- def test_marshalling_extensions
34
- david = developers(:david)
35
- assert_equal projects(:action_controller), david.projects.find_most_recent
36
-
37
- david = Marshal.load(Marshal.dump(david))
38
- assert_equal projects(:action_controller), david.projects.find_most_recent
39
- end
40
-
41
- def test_marshalling_named_extensions
42
- david = developers(:david)
43
- assert_equal projects(:action_controller), david.projects_extended_by_name.find_most_recent
44
-
45
- david = Marshal.load(Marshal.dump(david))
46
- assert_equal projects(:action_controller), david.projects_extended_by_name.find_most_recent
47
- end
48
-
49
-
50
- def test_extension_name
51
- extension = Proc.new {}
52
- name = :association_name
53
-
54
- assert_equal 'DeveloperAssociationNameAssociationExtension', Developer.send(:create_extension_modules, name, extension, []).first.name
55
- assert_equal 'MyApplication::Business::DeveloperAssociationNameAssociationExtension',
56
- MyApplication::Business::Developer.send(:create_extension_modules, name, extension, []).first.name
57
- assert_equal 'MyApplication::Business::DeveloperAssociationNameAssociationExtension', MyApplication::Business::Developer.send(:create_extension_modules, name, extension, []).first.name
58
- assert_equal 'MyApplication::Business::DeveloperAssociationNameAssociationExtension', MyApplication::Business::Developer.send(:create_extension_modules, name, extension, []).first.name
59
- end
60
-
61
-
62
- end
@@ -1,56 +0,0 @@
1
- require 'cases/helper'
2
-
3
- class MyReader < ActiveRecord::Base
4
- has_and_belongs_to_many :my_books
5
- end
6
-
7
- class MyBook < ActiveRecord::Base
8
- has_and_belongs_to_many :my_readers
9
- end
10
-
11
- class HabtmJoinTableTest < ActiveRecord::TestCase
12
- def setup
13
- ActiveRecord::Base.connection.create_table :my_books, :force => true do |t|
14
- t.string :name
15
- end
16
- assert ActiveRecord::Base.connection.table_exists?(:my_books)
17
-
18
- ActiveRecord::Base.connection.create_table :my_readers, :force => true do |t|
19
- t.string :name
20
- end
21
- assert ActiveRecord::Base.connection.table_exists?(:my_readers)
22
-
23
- ActiveRecord::Base.connection.create_table :my_books_my_readers, :force => true do |t|
24
- t.integer :my_book_id
25
- t.integer :my_reader_id
26
- end
27
- assert ActiveRecord::Base.connection.table_exists?(:my_books_my_readers)
28
- end
29
-
30
- def teardown
31
- ActiveRecord::Base.connection.drop_table :my_books
32
- ActiveRecord::Base.connection.drop_table :my_readers
33
- ActiveRecord::Base.connection.drop_table :my_books_my_readers
34
- end
35
-
36
- uses_transaction :test_should_raise_exception_when_join_table_has_a_primary_key
37
- def test_should_raise_exception_when_join_table_has_a_primary_key
38
- if ActiveRecord::Base.connection.supports_primary_key?
39
- assert_raise ActiveRecord::ConfigurationError do
40
- jaime = MyReader.create(:name=>"Jaime")
41
- jaime.my_books << MyBook.create(:name=>'Great Expectations')
42
- end
43
- end
44
- end
45
-
46
- uses_transaction :test_should_cache_result_of_primary_key_check
47
- def test_should_cache_result_of_primary_key_check
48
- if ActiveRecord::Base.connection.supports_primary_key?
49
- ActiveRecord::Base.connection.stubs(:primary_key).with('my_books_my_readers').returns(false).once
50
- weaz = MyReader.create(:name=>'Weaz')
51
-
52
- weaz.my_books << MyBook.create(:name=>'Great Expectations')
53
- weaz.my_books << MyBook.create(:name=>'Greater Expectations')
54
- end
55
- end
56
- end
@@ -1,827 +0,0 @@
1
- require "cases/helper"
2
- require 'models/developer'
3
- require 'models/project'
4
- require 'models/company'
5
- require 'models/topic'
6
- require 'models/reply'
7
- require 'models/computer'
8
- require 'models/customer'
9
- require 'models/order'
10
- require 'models/categorization'
11
- require 'models/category'
12
- require 'models/post'
13
- require 'models/author'
14
- require 'models/comment'
15
- require 'models/tag'
16
- require 'models/tagging'
17
- require 'models/person'
18
- require 'models/reader'
19
- require 'models/parrot'
20
- require 'models/pirate'
21
- require 'models/treasure'
22
- require 'models/price_estimate'
23
- require 'models/club'
24
- require 'models/member'
25
- require 'models/membership'
26
- require 'models/sponsor'
27
-
28
- class ProjectWithAfterCreateHook < ActiveRecord::Base
29
- set_table_name 'projects'
30
- has_and_belongs_to_many :developers,
31
- :class_name => "DeveloperForProjectWithAfterCreateHook",
32
- :join_table => "developers_projects",
33
- :foreign_key => "project_id",
34
- :association_foreign_key => "developer_id"
35
-
36
- after_create :add_david
37
-
38
- def add_david
39
- david = DeveloperForProjectWithAfterCreateHook.find_by_name('David')
40
- david.projects << self
41
- end
42
- end
43
-
44
- class DeveloperForProjectWithAfterCreateHook < ActiveRecord::Base
45
- set_table_name 'developers'
46
- has_and_belongs_to_many :projects,
47
- :class_name => "ProjectWithAfterCreateHook",
48
- :join_table => "developers_projects",
49
- :association_foreign_key => "project_id",
50
- :foreign_key => "developer_id"
51
- end
52
-
53
- class ProjectWithSymbolsForKeys < ActiveRecord::Base
54
- set_table_name 'projects'
55
- has_and_belongs_to_many :developers,
56
- :class_name => "DeveloperWithSymbolsForKeys",
57
- :join_table => :developers_projects,
58
- :foreign_key => :project_id,
59
- :association_foreign_key => "developer_id"
60
- end
61
-
62
- class DeveloperWithSymbolsForKeys < ActiveRecord::Base
63
- set_table_name 'developers'
64
- has_and_belongs_to_many :projects,
65
- :class_name => "ProjectWithSymbolsForKeys",
66
- :join_table => :developers_projects,
67
- :association_foreign_key => :project_id,
68
- :foreign_key => "developer_id"
69
- end
70
-
71
- class DeveloperWithCounterSQL < ActiveRecord::Base
72
- set_table_name 'developers'
73
- has_and_belongs_to_many :projects,
74
- :class_name => "DeveloperWithCounterSQL",
75
- :join_table => "developers_projects",
76
- :association_foreign_key => "project_id",
77
- :foreign_key => "developer_id",
78
- :counter_sql => 'SELECT COUNT(*) AS count_all FROM projects INNER JOIN developers_projects ON projects.id = developers_projects.project_id WHERE developers_projects.developer_id =#{id}'
79
- end
80
-
81
- class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
82
- fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects,
83
- :parrots, :pirates, :treasures, :price_estimates, :tags, :taggings
84
-
85
- def test_has_and_belongs_to_many
86
- david = Developer.find(1)
87
-
88
- assert !david.projects.empty?
89
- assert_equal 2, david.projects.size
90
-
91
- active_record = Project.find(1)
92
- assert !active_record.developers.empty?
93
- assert_equal 3, active_record.developers.size
94
- assert active_record.developers.include?(david)
95
- end
96
-
97
- def test_triple_equality
98
- assert !(Array === Developer.find(1).projects)
99
- assert Developer.find(1).projects === Array
100
- end
101
-
102
- def test_adding_single
103
- jamis = Developer.find(2)
104
- jamis.projects.reload # causing the collection to load
105
- action_controller = Project.find(2)
106
- assert_equal 1, jamis.projects.size
107
- assert_equal 1, action_controller.developers.size
108
-
109
- jamis.projects << action_controller
110
-
111
- assert_equal 2, jamis.projects.size
112
- assert_equal 2, jamis.projects(true).size
113
- assert_equal 2, action_controller.developers(true).size
114
- end
115
-
116
- def test_adding_type_mismatch
117
- jamis = Developer.find(2)
118
- assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << nil }
119
- assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << 1 }
120
- end
121
-
122
- def test_adding_from_the_project
123
- jamis = Developer.find(2)
124
- action_controller = Project.find(2)
125
- action_controller.developers.reload
126
- assert_equal 1, jamis.projects.size
127
- assert_equal 1, action_controller.developers.size
128
-
129
- action_controller.developers << jamis
130
-
131
- assert_equal 2, jamis.projects(true).size
132
- assert_equal 2, action_controller.developers.size
133
- assert_equal 2, action_controller.developers(true).size
134
- end
135
-
136
- def test_adding_from_the_project_fixed_timestamp
137
- jamis = Developer.find(2)
138
- action_controller = Project.find(2)
139
- action_controller.developers.reload
140
- assert_equal 1, jamis.projects.size
141
- assert_equal 1, action_controller.developers.size
142
- updated_at = jamis.updated_at
143
-
144
- action_controller.developers << jamis
145
-
146
- assert_equal updated_at, jamis.updated_at
147
- assert_equal 2, jamis.projects(true).size
148
- assert_equal 2, action_controller.developers.size
149
- assert_equal 2, action_controller.developers(true).size
150
- end
151
-
152
- def test_adding_multiple
153
- aredridel = Developer.new("name" => "Aredridel")
154
- aredridel.save
155
- aredridel.projects.reload
156
- aredridel.projects.push(Project.find(1), Project.find(2))
157
- assert_equal 2, aredridel.projects.size
158
- assert_equal 2, aredridel.projects(true).size
159
- end
160
-
161
- def test_adding_a_collection
162
- aredridel = Developer.new("name" => "Aredridel")
163
- aredridel.save
164
- aredridel.projects.reload
165
- aredridel.projects.concat([Project.find(1), Project.find(2)])
166
- assert_equal 2, aredridel.projects.size
167
- assert_equal 2, aredridel.projects(true).size
168
- end
169
-
170
- def test_adding_uses_default_values_on_join_table
171
- ac = projects(:action_controller)
172
- assert !developers(:jamis).projects.include?(ac)
173
- developers(:jamis).projects << ac
174
-
175
- assert developers(:jamis, :reload).projects.include?(ac)
176
- project = developers(:jamis).projects.detect { |p| p == ac }
177
- assert_equal 1, project.access_level.to_i
178
- end
179
-
180
- def test_habtm_attribute_access_and_respond_to
181
- project = developers(:jamis).projects[0]
182
- assert project.has_attribute?("name")
183
- assert project.has_attribute?("joined_on")
184
- assert project.has_attribute?("access_level")
185
- assert project.respond_to?("name")
186
- assert project.respond_to?("name=")
187
- assert project.respond_to?("name?")
188
- assert project.respond_to?("joined_on")
189
- # given that the 'join attribute' won't be persisted, I don't
190
- # think we should define the mutators
191
- #assert project.respond_to?("joined_on=")
192
- assert project.respond_to?("joined_on?")
193
- assert project.respond_to?("access_level")
194
- #assert project.respond_to?("access_level=")
195
- assert project.respond_to?("access_level?")
196
- end
197
-
198
- def test_habtm_adding_before_save
199
- no_of_devels = Developer.count
200
- no_of_projects = Project.count
201
- aredridel = Developer.new("name" => "Aredridel")
202
- aredridel.projects.concat([Project.find(1), p = Project.new("name" => "Projekt")])
203
- assert aredridel.new_record?
204
- assert p.new_record?
205
- assert aredridel.save
206
- assert !aredridel.new_record?
207
- assert_equal no_of_devels+1, Developer.count
208
- assert_equal no_of_projects+1, Project.count
209
- assert_equal 2, aredridel.projects.size
210
- assert_equal 2, aredridel.projects(true).size
211
- end
212
-
213
- def test_habtm_saving_multiple_relationships
214
- new_project = Project.new("name" => "Grimetime")
215
- amount_of_developers = 4
216
- developers = (0...amount_of_developers).collect {|i| Developer.create(:name => "JME #{i}") }.reverse
217
-
218
- new_project.developer_ids = [developers[0].id, developers[1].id]
219
- new_project.developers_with_callback_ids = [developers[2].id, developers[3].id]
220
- assert new_project.save
221
-
222
- new_project.reload
223
- assert_equal amount_of_developers, new_project.developers.size
224
- assert_equal developers, new_project.developers
225
- end
226
-
227
- def test_habtm_unique_order_preserved
228
- assert_equal developers(:poor_jamis, :jamis, :david), projects(:active_record).non_unique_developers
229
- assert_equal developers(:poor_jamis, :jamis, :david), projects(:active_record).developers
230
- end
231
-
232
- def test_build
233
- devel = Developer.find(1)
234
- proj = assert_no_queries { devel.projects.build("name" => "Projekt") }
235
- assert !devel.projects.loaded?
236
-
237
- assert_equal devel.projects.last, proj
238
- assert devel.projects.loaded?
239
-
240
- assert proj.new_record?
241
- devel.save
242
- assert !proj.new_record?
243
- assert_equal devel.projects.last, proj
244
- assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
245
- end
246
-
247
- def test_build_by_new_record
248
- devel = Developer.new(:name => "Marcel", :salary => 75000)
249
- proj1 = devel.projects.build(:name => "Make bed")
250
- proj2 = devel.projects.build(:name => "Lie in it")
251
- assert_equal devel.projects.last, proj2
252
- assert proj2.new_record?
253
- devel.save
254
- assert !devel.new_record?
255
- assert !proj2.new_record?
256
- assert_equal devel.projects.last, proj2
257
- assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
258
- end
259
-
260
- def test_create
261
- devel = Developer.find(1)
262
- proj = devel.projects.create("name" => "Projekt")
263
- assert !devel.projects.loaded?
264
-
265
- assert_equal devel.projects.last, proj
266
- assert !devel.projects.loaded?
267
-
268
- assert !proj.new_record?
269
- assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
270
- end
271
-
272
- def test_create_by_new_record
273
- devel = Developer.new(:name => "Marcel", :salary => 75000)
274
- proj1 = devel.projects.build(:name => "Make bed")
275
- proj2 = devel.projects.build(:name => "Lie in it")
276
- assert_equal devel.projects.last, proj2
277
- assert proj2.new_record?
278
- devel.save
279
- assert !devel.new_record?
280
- assert !proj2.new_record?
281
- assert_equal devel.projects.last, proj2
282
- assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
283
- end
284
-
285
- def test_creation_respects_hash_condition
286
- post = categories(:general).post_with_conditions.build(:body => '')
287
-
288
- assert post.save
289
- assert_equal 'Yet Another Testing Title', post.title
290
-
291
- another_post = categories(:general).post_with_conditions.create(:body => '')
292
-
293
- assert !another_post.new_record?
294
- assert_equal 'Yet Another Testing Title', another_post.title
295
- end
296
-
297
- def test_uniq_after_the_fact
298
- dev = developers(:jamis)
299
- dev.projects << projects(:active_record)
300
- dev.projects << projects(:active_record)
301
-
302
- assert_equal 3, dev.projects.size
303
- assert_equal 1, dev.projects.uniq.size
304
- end
305
-
306
- def test_uniq_before_the_fact
307
- projects(:active_record).developers << developers(:jamis)
308
- projects(:active_record).developers << developers(:david)
309
- assert_equal 3, projects(:active_record, :reload).developers.size
310
- end
311
-
312
- def test_uniq_option_prevents_duplicate_push
313
- project = projects(:active_record)
314
- project.developers << developers(:jamis)
315
- project.developers << developers(:david)
316
- assert_equal 3, project.developers.size
317
-
318
- project.developers << developers(:david)
319
- project.developers << developers(:jamis)
320
- assert_equal 3, project.developers.size
321
- end
322
-
323
- def test_deleting
324
- david = Developer.find(1)
325
- active_record = Project.find(1)
326
- david.projects.reload
327
- assert_equal 2, david.projects.size
328
- assert_equal 3, active_record.developers.size
329
-
330
- david.projects.delete(active_record)
331
-
332
- assert_equal 1, david.projects.size
333
- assert_equal 1, david.projects(true).size
334
- assert_equal 2, active_record.developers(true).size
335
- end
336
-
337
- def test_deleting_array
338
- david = Developer.find(1)
339
- david.projects.reload
340
- david.projects.delete(Project.find(:all))
341
- assert_equal 0, david.projects.size
342
- assert_equal 0, david.projects(true).size
343
- end
344
-
345
- def test_deleting_with_sql
346
- david = Developer.find(1)
347
- active_record = Project.find(1)
348
- active_record.developers.reload
349
- assert_equal 3, active_record.developers_by_sql.size
350
-
351
- active_record.developers_by_sql.delete(david)
352
- assert_equal 2, active_record.developers_by_sql(true).size
353
- end
354
-
355
- def test_deleting_array_with_sql
356
- active_record = Project.find(1)
357
- active_record.developers.reload
358
- assert_equal 3, active_record.developers_by_sql.size
359
-
360
- active_record.developers_by_sql.delete(Developer.find(:all))
361
- assert_equal 0, active_record.developers_by_sql(true).size
362
- end
363
-
364
- def test_deleting_all
365
- david = Developer.find(1)
366
- david.projects.reload
367
- david.projects.clear
368
- assert_equal 0, david.projects.size
369
- assert_equal 0, david.projects(true).size
370
- end
371
-
372
- def test_removing_associations_on_destroy
373
- david = DeveloperWithBeforeDestroyRaise.find(1)
374
- assert !david.projects.empty?
375
- assert_nothing_raised { david.destroy }
376
- assert david.projects.empty?
377
- assert DeveloperWithBeforeDestroyRaise.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = 1").empty?
378
- end
379
-
380
- def test_additional_columns_from_join_table
381
- assert_date_from_db Date.new(2004, 10, 10), Developer.find(1).projects.first.joined_on.to_date
382
- end
383
-
384
- def test_destroying
385
- david = Developer.find(1)
386
- active_record = Project.find(1)
387
- david.projects.reload
388
- assert_equal 2, david.projects.size
389
- assert_equal 3, active_record.developers.size
390
-
391
- assert_difference "Project.count", -1 do
392
- david.projects.destroy(active_record)
393
- end
394
-
395
- assert_equal 1, david.reload.projects.size
396
- assert_equal 1, david.projects(true).size
397
- end
398
-
399
- def test_destroying_array
400
- david = Developer.find(1)
401
- david.projects.reload
402
-
403
- assert_difference "Project.count", -Project.count do
404
- david.projects.destroy(Project.find(:all))
405
- end
406
-
407
- assert_equal 0, david.reload.projects.size
408
- assert_equal 0, david.projects(true).size
409
- end
410
-
411
- def test_destroy_all
412
- david = Developer.find(1)
413
- david.projects.reload
414
- assert !david.projects.empty?
415
- david.projects.destroy_all
416
- assert david.projects.empty?
417
- assert david.projects(true).empty?
418
- end
419
-
420
- def test_deprecated_push_with_attributes_was_removed
421
- jamis = developers(:jamis)
422
- assert_raise(NoMethodError) do
423
- jamis.projects.push_with_attributes(projects(:action_controller), :joined_on => Date.today)
424
- end
425
- end
426
-
427
- def test_associations_with_conditions
428
- assert_equal 3, projects(:active_record).developers.size
429
- assert_equal 1, projects(:active_record).developers_named_david.size
430
- assert_equal 1, projects(:active_record).developers_named_david_with_hash_conditions.size
431
-
432
- assert_equal developers(:david), projects(:active_record).developers_named_david.find(developers(:david).id)
433
- assert_equal developers(:david), projects(:active_record).developers_named_david_with_hash_conditions.find(developers(:david).id)
434
- assert_equal developers(:david), projects(:active_record).salaried_developers.find(developers(:david).id)
435
-
436
- projects(:active_record).developers_named_david.clear
437
- assert_equal 2, projects(:active_record, :reload).developers.size
438
- end
439
-
440
- def test_find_in_association
441
- # Using sql
442
- assert_equal developers(:david), projects(:active_record).developers.find(developers(:david).id), "SQL find"
443
-
444
- # Using ruby
445
- active_record = projects(:active_record)
446
- active_record.developers.reload
447
- assert_equal developers(:david), active_record.developers.find(developers(:david).id), "Ruby find"
448
- end
449
-
450
- def test_include_uses_array_include_after_loaded
451
- project = projects(:active_record)
452
- project.developers.class # force load target
453
-
454
- developer = project.developers.first
455
-
456
- assert_no_queries do
457
- assert project.developers.loaded?
458
- assert project.developers.include?(developer)
459
- end
460
- end
461
-
462
- def test_include_checks_if_record_exists_if_target_not_loaded
463
- project = projects(:active_record)
464
- developer = project.developers.first
465
-
466
- project.reload
467
- assert ! project.developers.loaded?
468
- assert_queries(1) do
469
- assert project.developers.include?(developer)
470
- end
471
- assert ! project.developers.loaded?
472
- end
473
-
474
- def test_include_returns_false_for_non_matching_record_to_verify_scoping
475
- project = projects(:active_record)
476
- developer = Developer.create :name => "Bryan", :salary => 50_000
477
-
478
- assert ! project.developers.loaded?
479
- assert ! project.developers.include?(developer)
480
- end
481
-
482
- def test_find_in_association_with_custom_finder_sql
483
- assert_equal developers(:david), projects(:active_record).developers_with_finder_sql.find(developers(:david).id), "SQL find"
484
-
485
- active_record = projects(:active_record)
486
- active_record.developers_with_finder_sql.reload
487
- assert_equal developers(:david), active_record.developers_with_finder_sql.find(developers(:david).id), "Ruby find"
488
- end
489
-
490
- def test_find_in_association_with_custom_finder_sql_and_multiple_interpolations
491
- # interpolate once:
492
- assert_equal [developers(:david), developers(:jamis), developers(:poor_jamis)], projects(:active_record).developers_with_finder_sql, "first interpolation"
493
- # interpolate again, for a different project id
494
- assert_equal [developers(:david)], projects(:action_controller).developers_with_finder_sql, "second interpolation"
495
- end
496
-
497
- def test_find_in_association_with_custom_finder_sql_and_string_id
498
- assert_equal developers(:david), projects(:active_record).developers_with_finder_sql.find(developers(:david).id.to_s), "SQL find"
499
- end
500
-
501
- def test_find_with_merged_options
502
- assert_equal 1, projects(:active_record).limited_developers.size
503
- assert_equal 1, projects(:active_record).limited_developers.find(:all).size
504
- assert_equal 3, projects(:active_record).limited_developers.find(:all, :limit => nil).size
505
- end
506
-
507
- def test_dynamic_find_should_respect_association_order
508
- # Developers are ordered 'name DESC, id DESC'
509
- low_id_jamis = developers(:jamis)
510
- middle_id_jamis = developers(:poor_jamis)
511
- high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
512
-
513
- assert_equal high_id_jamis, projects(:active_record).developers.find(:first, :conditions => "name = 'Jamis'")
514
- assert_equal high_id_jamis, projects(:active_record).developers.find_by_name('Jamis')
515
- end
516
-
517
- def test_dynamic_find_order_should_override_association_order
518
- # Developers are ordered 'name DESC, id DESC'
519
- low_id_jamis = developers(:jamis)
520
- middle_id_jamis = developers(:poor_jamis)
521
- high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
522
-
523
- assert_equal low_id_jamis, projects(:active_record).developers.find(:first, :conditions => "name = 'Jamis'", :order => 'id')
524
- assert_equal low_id_jamis, projects(:active_record).developers.find_by_name('Jamis', :order => 'id')
525
- end
526
-
527
- def test_dynamic_find_all_should_respect_association_order
528
- # Developers are ordered 'name DESC, id DESC'
529
- low_id_jamis = developers(:jamis)
530
- middle_id_jamis = developers(:poor_jamis)
531
- high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
532
-
533
- assert_equal [high_id_jamis, middle_id_jamis, low_id_jamis], projects(:active_record).developers.find(:all, :conditions => "name = 'Jamis'")
534
- assert_equal [high_id_jamis, middle_id_jamis, low_id_jamis], projects(:active_record).developers.find_all_by_name('Jamis')
535
- end
536
-
537
- def test_dynamic_find_all_order_should_override_association_order
538
- # Developers are ordered 'name DESC, id DESC'
539
- low_id_jamis = developers(:jamis)
540
- middle_id_jamis = developers(:poor_jamis)
541
- high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
542
-
543
- assert_equal [low_id_jamis, middle_id_jamis, high_id_jamis], projects(:active_record).developers.find(:all, :conditions => "name = 'Jamis'", :order => 'id')
544
- assert_equal [low_id_jamis, middle_id_jamis, high_id_jamis], projects(:active_record).developers.find_all_by_name('Jamis', :order => 'id')
545
- end
546
-
547
- def test_dynamic_find_all_should_respect_association_limit
548
- assert_equal 1, projects(:active_record).limited_developers.find(:all, :conditions => "name = 'Jamis'").length
549
- assert_equal 1, projects(:active_record).limited_developers.find_all_by_name('Jamis').length
550
- end
551
-
552
- def test_dynamic_find_all_order_should_override_association_limit
553
- assert_equal 2, projects(:active_record).limited_developers.find(:all, :conditions => "name = 'Jamis'", :limit => 9_000).length
554
- assert_equal 2, projects(:active_record).limited_developers.find_all_by_name('Jamis', :limit => 9_000).length
555
- end
556
-
557
- def test_dynamic_find_all_should_respect_readonly_access
558
- projects(:active_record).readonly_developers.each { |d| assert_raise(ActiveRecord::ReadOnlyRecord) { d.save! } if d.valid?}
559
- projects(:active_record).readonly_developers.each { |d| d.readonly? }
560
- end
561
-
562
- def test_new_with_values_in_collection
563
- jamis = DeveloperForProjectWithAfterCreateHook.find_by_name('Jamis')
564
- david = DeveloperForProjectWithAfterCreateHook.find_by_name('David')
565
- project = ProjectWithAfterCreateHook.new(:name => "Cooking with Bertie")
566
- project.developers << jamis
567
- project.save!
568
- project.reload
569
-
570
- assert project.developers.include?(jamis)
571
- assert project.developers.include?(david)
572
- end
573
-
574
- def test_find_in_association_with_options
575
- developers = projects(:active_record).developers.find(:all)
576
- assert_equal 3, developers.size
577
-
578
- assert_equal developers(:poor_jamis), projects(:active_record).developers.find(:first, :conditions => "salary < 10000")
579
- assert_equal developers(:jamis), projects(:active_record).developers.find(:first, :order => "salary DESC")
580
- end
581
-
582
- def test_replace_with_less
583
- david = developers(:david)
584
- david.projects = [projects(:action_controller)]
585
- assert david.save
586
- assert_equal 1, david.projects.length
587
- end
588
-
589
- def test_replace_with_new
590
- david = developers(:david)
591
- david.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")]
592
- david.save
593
- assert_equal 2, david.projects.length
594
- assert !david.projects.include?(projects(:active_record))
595
- end
596
-
597
- def test_replace_on_new_object
598
- new_developer = Developer.new("name" => "Matz")
599
- new_developer.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")]
600
- new_developer.save
601
- assert_equal 2, new_developer.projects.length
602
- end
603
-
604
- def test_consider_type
605
- developer = Developer.find(:first)
606
- special_project = SpecialProject.create("name" => "Special Project")
607
-
608
- other_project = developer.projects.first
609
- developer.special_projects << special_project
610
- developer.reload
611
-
612
- assert developer.projects.include?(special_project)
613
- assert developer.special_projects.include?(special_project)
614
- assert !developer.special_projects.include?(other_project)
615
- end
616
-
617
- def test_update_attributes_after_push_without_duplicate_join_table_rows
618
- developer = Developer.new("name" => "Kano")
619
- project = SpecialProject.create("name" => "Special Project")
620
- assert developer.save
621
- developer.projects << project
622
- developer.update_attribute("name", "Bruza")
623
- assert_equal 1, Developer.connection.select_value(<<-end_sql).to_i
624
- SELECT count(*) FROM developers_projects
625
- WHERE project_id = #{project.id}
626
- AND developer_id = #{developer.id}
627
- end_sql
628
- end
629
-
630
- def test_updating_attributes_on_non_rich_associations
631
- welcome = categories(:technology).posts.first
632
- welcome.title = "Something else"
633
- assert welcome.save!
634
- end
635
-
636
- def test_habtm_respects_select
637
- categories(:technology).select_testing_posts(true).each do |o|
638
- assert_respond_to o, :correctness_marker
639
- end
640
- assert_respond_to categories(:technology).select_testing_posts.find(:first), :correctness_marker
641
- end
642
-
643
- def test_updating_attributes_on_rich_associations
644
- david = projects(:action_controller).developers.first
645
- david.name = "DHH"
646
- assert_raise(ActiveRecord::ReadOnlyRecord) { david.save! }
647
- end
648
-
649
- def test_updating_attributes_on_rich_associations_with_limited_find_from_reflection
650
- david = projects(:action_controller).selected_developers.first
651
- david.name = "DHH"
652
- assert_nothing_raised { david.save! }
653
- end
654
-
655
-
656
- def test_updating_attributes_on_rich_associations_with_limited_find
657
- david = projects(:action_controller).developers.find(:all, :select => "developers.*").first
658
- david.name = "DHH"
659
- assert david.save!
660
- end
661
-
662
- def test_join_table_alias
663
- assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL').size
664
- end
665
-
666
- def test_join_with_group
667
- group = Developer.columns.inject([]) do |g, c|
668
- g << "developers.#{c.name}"
669
- g << "developers_projects_2.#{c.name}"
670
- end
671
- Project.columns.each { |c| group << "projects.#{c.name}" }
672
-
673
- assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL', :group => group.join(",")).size
674
- end
675
-
676
- def test_find_grouped
677
- all_posts_from_category1 = Post.find(:all, :conditions => "category_id = 1", :joins => :categories)
678
- grouped_posts_of_category1 = Post.find(:all, :conditions => "category_id = 1", :group => "author_id", :select => 'count(posts.id) as posts_count', :joins => :categories)
679
- assert_equal 4, all_posts_from_category1.size
680
- assert_equal 1, grouped_posts_of_category1.size
681
- end
682
-
683
- def test_find_scoped_grouped
684
- assert_equal 4, categories(:general).posts_gruoped_by_title.size
685
- assert_equal 1, categories(:technology).posts_gruoped_by_title.size
686
- end
687
-
688
- def test_find_scoped_grouped_having
689
- assert_equal 2, projects(:active_record).well_payed_salary_groups.size
690
- assert projects(:active_record).well_payed_salary_groups.all? { |g| g.salary > 10000 }
691
- end
692
-
693
- def test_get_ids
694
- assert_equal projects(:active_record, :action_controller).map(&:id).sort, developers(:david).project_ids.sort
695
- assert_equal [projects(:active_record).id], developers(:jamis).project_ids
696
- end
697
-
698
- def test_get_ids_for_loaded_associations
699
- developer = developers(:david)
700
- developer.projects(true)
701
- assert_queries(0) do
702
- developer.project_ids
703
- developer.project_ids
704
- end
705
- end
706
-
707
- def test_get_ids_for_unloaded_associations_does_not_load_them
708
- developer = developers(:david)
709
- assert !developer.projects.loaded?
710
- assert_equal projects(:active_record, :action_controller).map(&:id).sort, developer.project_ids.sort
711
- assert !developer.projects.loaded?
712
- end
713
-
714
- def test_assign_ids
715
- developer = Developer.new("name" => "Joe")
716
- developer.project_ids = projects(:active_record, :action_controller).map(&:id)
717
- developer.save
718
- developer.reload
719
- assert_equal 2, developer.projects.length
720
- assert_equal [projects(:active_record), projects(:action_controller)].map(&:id).sort, developer.project_ids.sort
721
- end
722
-
723
- def test_assign_ids_ignoring_blanks
724
- developer = Developer.new("name" => "Joe")
725
- developer.project_ids = [projects(:active_record).id, nil, projects(:action_controller).id, '']
726
- developer.save
727
- developer.reload
728
- assert_equal 2, developer.projects.length
729
- assert_equal [projects(:active_record), projects(:action_controller)].map(&:id).sort, developer.project_ids.sort
730
- end
731
-
732
- def test_select_limited_ids_list
733
- # Set timestamps
734
- Developer.transaction do
735
- Developer.find(:all, :order => 'id').each_with_index do |record, i|
736
- record.update_attributes(:created_at => 5.years.ago + (i * 5.minutes))
737
- end
738
- end
739
-
740
- join_base = ActiveRecord::Associations::ClassMethods::JoinDependency::JoinBase.new(Project)
741
- join_dep = ActiveRecord::Associations::ClassMethods::JoinDependency.new(join_base, :developers, nil)
742
- projects = Project.send(:select_limited_ids_list, {:order => 'developers.created_at'}, join_dep)
743
- assert !projects.include?("'"), projects
744
- assert_equal %w(1 2), projects.scan(/\d/).sort
745
- end
746
-
747
- def test_scoped_find_on_through_association_doesnt_return_read_only_records
748
- tag = Post.find(1).tags.find_by_name("General")
749
-
750
- assert_nothing_raised do
751
- tag.save!
752
- end
753
- end
754
-
755
- def test_has_many_through_polymorphic_has_manys_works
756
- assert_equal [10, 20].to_set, pirates(:redbeard).treasure_estimates.map(&:price).to_set
757
- end
758
-
759
- def test_symbols_as_keys
760
- developer = DeveloperWithSymbolsForKeys.new(:name => 'David')
761
- project = ProjectWithSymbolsForKeys.new(:name => 'Rails Testing')
762
- project.developers << developer
763
- project.save!
764
-
765
- assert_equal 1, project.developers.size
766
- assert_equal 1, developer.projects.size
767
- assert_equal developer, project.developers.find(:first)
768
- assert_equal project, developer.projects.find(:first)
769
- end
770
-
771
- def test_self_referential_habtm_without_foreign_key_set_should_raise_exception
772
- assert_raise(ActiveRecord::HasAndBelongsToManyAssociationForeignKeyNeeded) {
773
- Member.class_eval do
774
- has_and_belongs_to_many :friends, :class_name => "Member", :join_table => "member_friends"
775
- end
776
- }
777
- end
778
-
779
- def test_dynamic_find_should_respect_association_include
780
- # SQL error in sort clause if :include is not included
781
- # due to Unknown column 'authors.id'
782
- assert Category.find(1).posts_with_authors_sorted_by_author_id.find_by_title('Welcome to the weblog')
783
- end
784
-
785
- def test_counting_on_habtm_association_and_not_array
786
- david = Developer.find(1)
787
- # Extra parameter just to make sure we aren't falling back to
788
- # Array#count in Ruby >=1.8.7, which would raise an ArgumentError
789
- assert_nothing_raised { david.projects.count(:all, :conditions => '1=1') }
790
- end
791
-
792
- def test_count
793
- david = Developer.find(1)
794
- assert_equal 2, david.projects.count
795
- end
796
-
797
- def test_count_with_counter_sql
798
- developer = DeveloperWithCounterSQL.create(:name => 'tekin')
799
- developer.project_ids = [projects(:active_record).id]
800
- developer.save
801
- developer.reload
802
- assert_equal 1, developer.projects.count
803
- end
804
-
805
- def test_association_proxy_transaction_method_starts_transaction_in_association_class
806
- Post.expects(:transaction)
807
- Category.find(:first).posts.transaction do
808
- # nothing
809
- end
810
- end
811
-
812
- def test_caching_of_columns
813
- david = Developer.find(1)
814
- # clear cache possibly created by other tests
815
- david.projects.reset_column_information
816
- assert_queries(0) { david.projects.columns; david.projects.columns }
817
- # and again to verify that reset_column_information clears the cache correctly
818
- david.projects.reset_column_information
819
- assert_queries(0) { david.projects.columns; david.projects.columns }
820
- end
821
-
822
- def test_include_method_in_has_and_belongs_to_many_association_should_return_true_for_instance_added_with_build
823
- project = Project.new
824
- developer = project.developers.build
825
- assert project.developers.include?(developer)
826
- end
827
- end