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,282 +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 AssociationsTest < ActiveRecord::TestCase
29
- fixtures :accounts, :companies, :developers, :projects, :developers_projects,
30
- :computers, :people, :readers
31
-
32
- def test_include_with_order_works
33
- assert_nothing_raised {Account.find(:first, :order => 'id', :include => :firm)}
34
- assert_nothing_raised {Account.find(:first, :order => :id, :include => :firm)}
35
- end
36
-
37
- def test_bad_collection_keys
38
- assert_raise(ArgumentError, 'ActiveRecord should have barked on bad collection keys') do
39
- Class.new(ActiveRecord::Base).has_many(:wheels, :name => 'wheels')
40
- end
41
- end
42
-
43
- def test_should_construct_new_finder_sql_after_create
44
- person = Person.new :first_name => 'clark'
45
- assert_equal [], person.readers.find(:all)
46
- person.save!
47
- reader = Reader.create! :person => person, :post => Post.new(:title => "foo", :body => "bar")
48
- assert person.readers.find(reader.id)
49
- end
50
-
51
- def test_force_reload
52
- firm = Firm.new("name" => "A New Firm, Inc")
53
- firm.save
54
- firm.clients.each {|c|} # forcing to load all clients
55
- assert firm.clients.empty?, "New firm shouldn't have client objects"
56
- assert_equal 0, firm.clients.size, "New firm should have 0 clients"
57
-
58
- client = Client.new("name" => "TheClient.com", "firm_id" => firm.id)
59
- client.save
60
-
61
- assert firm.clients.empty?, "New firm should have cached no client objects"
62
- assert_equal 0, firm.clients.size, "New firm should have cached 0 clients count"
63
-
64
- assert !firm.clients(true).empty?, "New firm should have reloaded client objects"
65
- assert_equal 1, firm.clients(true).size, "New firm should have reloaded clients count"
66
- end
67
-
68
- def test_force_reload_is_uncached
69
- firm = Firm.create!("name" => "A New Firm, Inc")
70
- client = Client.create!("name" => "TheClient.com", :firm => firm)
71
- ActiveRecord::Base.cache do
72
- firm.clients.each {}
73
- assert_queries(0) { assert_not_nil firm.clients.each {} }
74
- assert_queries(1) { assert_not_nil firm.clients(true).each {} }
75
- end
76
- end
77
-
78
- def test_using_limitable_reflections_helper
79
- using_limitable_reflections = lambda { |reflections| ActiveRecord::Base.send :using_limitable_reflections?, reflections }
80
- belongs_to_reflections = [Tagging.reflect_on_association(:tag), Tagging.reflect_on_association(:super_tag)]
81
- has_many_reflections = [Tag.reflect_on_association(:taggings), Developer.reflect_on_association(:projects)]
82
- mixed_reflections = (belongs_to_reflections + has_many_reflections).uniq
83
- assert using_limitable_reflections.call(belongs_to_reflections), "Belong to associations are limitable"
84
- assert !using_limitable_reflections.call(has_many_reflections), "All has many style associations are not limitable"
85
- assert !using_limitable_reflections.call(mixed_reflections), "No collection associations (has many style) should pass"
86
- end
87
-
88
- def test_storing_in_pstore
89
- require "tmpdir"
90
- store_filename = File.join(Dir.tmpdir, "ar-pstore-association-test")
91
- File.delete(store_filename) if File.exist?(store_filename)
92
- require "pstore"
93
- apple = Firm.create("name" => "Apple")
94
- natural = Client.new("name" => "Natural Company")
95
- apple.clients << natural
96
-
97
- db = PStore.new(store_filename)
98
- db.transaction do
99
- db["apple"] = apple
100
- end
101
-
102
- db = PStore.new(store_filename)
103
- db.transaction do
104
- assert_equal "Natural Company", db["apple"].clients.first.name
105
- end
106
- end
107
- end
108
-
109
- class AssociationProxyTest < ActiveRecord::TestCase
110
- fixtures :authors, :posts, :categorizations, :categories, :developers, :projects, :developers_projects
111
-
112
- def test_proxy_accessors
113
- welcome = posts(:welcome)
114
- assert_equal welcome, welcome.author.proxy_owner
115
- assert_equal welcome.class.reflect_on_association(:author), welcome.author.proxy_reflection
116
- welcome.author.class # force load target
117
- assert_equal welcome.author, welcome.author.proxy_target
118
-
119
- david = authors(:david)
120
- assert_equal david, david.posts.proxy_owner
121
- assert_equal david.class.reflect_on_association(:posts), david.posts.proxy_reflection
122
- david.posts.class # force load target
123
- assert_equal david.posts, david.posts.proxy_target
124
-
125
- assert_equal david, david.posts_with_extension.testing_proxy_owner
126
- assert_equal david.class.reflect_on_association(:posts_with_extension), david.posts_with_extension.testing_proxy_reflection
127
- david.posts_with_extension.class # force load target
128
- assert_equal david.posts_with_extension, david.posts_with_extension.testing_proxy_target
129
- end
130
-
131
- def test_push_does_not_load_target
132
- david = authors(:david)
133
-
134
- david.posts << (post = Post.new(:title => "New on Edge", :body => "More cool stuff!"))
135
- assert !david.posts.loaded?
136
- assert david.posts.include?(post)
137
- end
138
-
139
- def test_push_has_many_through_does_not_load_target
140
- david = authors(:david)
141
-
142
- david.categories << categories(:technology)
143
- assert !david.categories.loaded?
144
- assert david.categories.include?(categories(:technology))
145
- end
146
-
147
- def test_push_followed_by_save_does_not_load_target
148
- david = authors(:david)
149
-
150
- david.posts << (post = Post.new(:title => "New on Edge", :body => "More cool stuff!"))
151
- assert !david.posts.loaded?
152
- david.save
153
- assert !david.posts.loaded?
154
- assert david.posts.include?(post)
155
- end
156
-
157
- def test_push_does_not_lose_additions_to_new_record
158
- josh = Author.new(:name => "Josh")
159
- josh.posts << Post.new(:title => "New on Edge", :body => "More cool stuff!")
160
- assert josh.posts.loaded?
161
- assert_equal 1, josh.posts.size
162
- end
163
-
164
- def test_save_on_parent_does_not_load_target
165
- david = developers(:david)
166
-
167
- assert !david.projects.loaded?
168
- david.update_attribute(:created_at, Time.now)
169
- assert !david.projects.loaded?
170
- end
171
-
172
- def test_inspect_does_not_reload_a_not_yet_loaded_target
173
- andreas = Developer.new :name => 'Andreas', :log => 'new developer added'
174
- assert !andreas.audit_logs.loaded?
175
- assert_match(/message: "new developer added"/, andreas.audit_logs.inspect)
176
- end
177
-
178
- def test_save_on_parent_saves_children
179
- developer = Developer.create :name => "Bryan", :salary => 50_000
180
- assert_equal 1, developer.reload.audit_logs.size
181
- end
182
-
183
- def test_create_via_association_with_block
184
- post = authors(:david).posts.create(:title => "New on Edge") {|p| p.body = "More cool stuff!"}
185
- assert_equal post.title, "New on Edge"
186
- assert_equal post.body, "More cool stuff!"
187
- end
188
-
189
- def test_create_with_bang_via_association_with_block
190
- post = authors(:david).posts.create!(:title => "New on Edge") {|p| p.body = "More cool stuff!"}
191
- assert_equal post.title, "New on Edge"
192
- assert_equal post.body, "More cool stuff!"
193
- end
194
-
195
- def test_failed_reload_returns_nil
196
- p = setup_dangling_association
197
- assert_nil p.author.reload
198
- end
199
-
200
- def test_failed_reset_returns_nil
201
- p = setup_dangling_association
202
- assert_nil p.author.reset
203
- end
204
-
205
- def test_reload_returns_assocition
206
- david = developers(:david)
207
- assert_nothing_raised do
208
- assert_equal david.projects, david.projects.reload.reload
209
- end
210
- end
211
-
212
- def setup_dangling_association
213
- josh = Author.create(:name => "Josh")
214
- p = Post.create(:title => "New on Edge", :body => "More cool stuff!", :author => josh)
215
- josh.destroy
216
- p
217
- end
218
- end
219
-
220
- class OverridingAssociationsTest < ActiveRecord::TestCase
221
- class Person < ActiveRecord::Base; end
222
- class DifferentPerson < ActiveRecord::Base; end
223
-
224
- class PeopleList < ActiveRecord::Base
225
- has_and_belongs_to_many :has_and_belongs_to_many, :before_add => :enlist
226
- has_many :has_many, :before_add => :enlist
227
- belongs_to :belongs_to
228
- has_one :has_one
229
- end
230
-
231
- class DifferentPeopleList < PeopleList
232
- # Different association with the same name, callbacks should be omitted here.
233
- has_and_belongs_to_many :has_and_belongs_to_many, :class_name => 'DifferentPerson'
234
- has_many :has_many, :class_name => 'DifferentPerson'
235
- belongs_to :belongs_to, :class_name => 'DifferentPerson'
236
- has_one :has_one, :class_name => 'DifferentPerson'
237
- end
238
-
239
- def test_habtm_association_redefinition_callbacks_should_differ_and_not_inherited
240
- # redeclared association on AR descendant should not inherit callbacks from superclass
241
- callbacks = PeopleList.read_inheritable_attribute(:before_add_for_has_and_belongs_to_many)
242
- assert_equal([:enlist], callbacks)
243
- callbacks = DifferentPeopleList.read_inheritable_attribute(:before_add_for_has_and_belongs_to_many)
244
- assert_equal([], callbacks)
245
- end
246
-
247
- def test_has_many_association_redefinition_callbacks_should_differ_and_not_inherited
248
- # redeclared association on AR descendant should not inherit callbacks from superclass
249
- callbacks = PeopleList.read_inheritable_attribute(:before_add_for_has_many)
250
- assert_equal([:enlist], callbacks)
251
- callbacks = DifferentPeopleList.read_inheritable_attribute(:before_add_for_has_many)
252
- assert_equal([], callbacks)
253
- end
254
-
255
- def test_habtm_association_redefinition_reflections_should_differ_and_not_inherited
256
- assert_not_equal(
257
- PeopleList.reflect_on_association(:has_and_belongs_to_many),
258
- DifferentPeopleList.reflect_on_association(:has_and_belongs_to_many)
259
- )
260
- end
261
-
262
- def test_has_many_association_redefinition_reflections_should_differ_and_not_inherited
263
- assert_not_equal(
264
- PeopleList.reflect_on_association(:has_many),
265
- DifferentPeopleList.reflect_on_association(:has_many)
266
- )
267
- end
268
-
269
- def test_belongs_to_association_redefinition_reflections_should_differ_and_not_inherited
270
- assert_not_equal(
271
- PeopleList.reflect_on_association(:belongs_to),
272
- DifferentPeopleList.reflect_on_association(:belongs_to)
273
- )
274
- end
275
-
276
- def test_has_one_association_redefinition_reflections_should_differ_and_not_inherited
277
- assert_not_equal(
278
- PeopleList.reflect_on_association(:has_one),
279
- DifferentPeopleList.reflect_on_association(:has_one)
280
- )
281
- end
282
- end
@@ -1,305 +0,0 @@
1
- require "cases/helper"
2
- require 'models/topic'
3
- require 'models/minimalistic'
4
-
5
- class AttributeMethodsTest < ActiveRecord::TestCase
6
- fixtures :topics
7
- def setup
8
- @old_suffixes = ActiveRecord::Base.send(:attribute_method_suffixes).dup
9
- @target = Class.new(ActiveRecord::Base)
10
- @target.table_name = 'topics'
11
- end
12
-
13
- def teardown
14
- ActiveRecord::Base.send(:attribute_method_suffixes).clear
15
- ActiveRecord::Base.attribute_method_suffix *@old_suffixes
16
- end
17
-
18
- def test_match_attribute_method_query_returns_match_data
19
- assert_not_nil md = @target.match_attribute_method?('title=')
20
- assert_equal 'title', md.pre_match
21
- assert_equal ['='], md.captures
22
-
23
- %w(_hello_world ist! _maybe?).each do |suffix|
24
- @target.class_eval "def attribute#{suffix}(*args) args end"
25
- @target.attribute_method_suffix suffix
26
-
27
- assert_not_nil md = @target.match_attribute_method?("title#{suffix}")
28
- assert_equal 'title', md.pre_match
29
- assert_equal [suffix], md.captures
30
- end
31
- end
32
-
33
- def test_declared_attribute_method_affects_respond_to_and_method_missing
34
- topic = @target.new(:title => 'Budget')
35
- assert topic.respond_to?('title')
36
- assert_equal 'Budget', topic.title
37
- assert !topic.respond_to?('title_hello_world')
38
- assert_raise(NoMethodError) { topic.title_hello_world }
39
-
40
- %w(_hello_world _it! _candidate= able?).each do |suffix|
41
- @target.class_eval "def attribute#{suffix}(*args) args end"
42
- @target.attribute_method_suffix suffix
43
-
44
- meth = "title#{suffix}"
45
- assert topic.respond_to?(meth)
46
- assert_equal ['title'], topic.send(meth)
47
- assert_equal ['title', 'a'], topic.send(meth, 'a')
48
- assert_equal ['title', 1, 2, 3], topic.send(meth, 1, 2, 3)
49
- end
50
- end
51
-
52
- def test_should_unserialize_attributes_for_frozen_records
53
- myobj = {:value1 => :value2}
54
- topic = Topic.create("content" => myobj)
55
- topic.freeze
56
- assert_equal myobj, topic.content
57
- end
58
-
59
- def test_typecast_attribute_from_select_to_false
60
- topic = Topic.create(:title => 'Budget')
61
- topic = Topic.find(:first, :select => "topics.*, 1=2 as is_test")
62
- assert !topic.is_test?
63
- end
64
-
65
- def test_typecast_attribute_from_select_to_true
66
- topic = Topic.create(:title => 'Budget')
67
- topic = Topic.find(:first, :select => "topics.*, 2=2 as is_test")
68
- assert topic.is_test?
69
- end
70
-
71
- def test_kernel_methods_not_implemented_in_activerecord
72
- %w(test name display y).each do |method|
73
- assert !ActiveRecord::Base.instance_method_already_implemented?(method), "##{method} is defined"
74
- end
75
- end
76
-
77
- def test_primary_key_implemented
78
- assert Class.new(ActiveRecord::Base).instance_method_already_implemented?('id')
79
- end
80
-
81
- def test_defined_kernel_methods_implemented_in_model
82
- %w(test name display y).each do |method|
83
- klass = Class.new ActiveRecord::Base
84
- klass.class_eval "def #{method}() 'defined #{method}' end"
85
- assert klass.instance_method_already_implemented?(method), "##{method} is not defined"
86
- end
87
- end
88
-
89
- def test_defined_kernel_methods_implemented_in_model_abstract_subclass
90
- %w(test name display y).each do |method|
91
- abstract = Class.new ActiveRecord::Base
92
- abstract.class_eval "def #{method}() 'defined #{method}' end"
93
- abstract.abstract_class = true
94
- klass = Class.new abstract
95
- assert klass.instance_method_already_implemented?(method), "##{method} is not defined"
96
- end
97
- end
98
-
99
- def test_raises_dangerous_attribute_error_when_defining_activerecord_method_in_model
100
- %w(save create_or_update).each do |method|
101
- klass = Class.new ActiveRecord::Base
102
- klass.class_eval "def #{method}() 'defined #{method}' end"
103
- assert_raise ActiveRecord::DangerousAttributeError do
104
- klass.instance_method_already_implemented?(method)
105
- end
106
- end
107
- end
108
-
109
- def test_only_time_related_columns_are_meant_to_be_cached_by_default
110
- expected = %w(datetime timestamp time date).sort
111
- assert_equal expected, ActiveRecord::Base.attribute_types_cached_by_default.map(&:to_s).sort
112
- end
113
-
114
- def test_declaring_attributes_as_cached_adds_them_to_the_attributes_cached_by_default
115
- default_attributes = Topic.cached_attributes
116
- Topic.cache_attributes :replies_count
117
- expected = default_attributes + ["replies_count"]
118
- assert_equal expected.sort, Topic.cached_attributes.sort
119
- Topic.instance_variable_set "@cached_attributes", nil
120
- end
121
-
122
- def test_time_related_columns_are_actually_cached
123
- column_types = %w(datetime timestamp time date).map(&:to_sym)
124
- column_names = Topic.columns.select{|c| column_types.include?(c.type) }.map(&:name)
125
-
126
- assert_equal column_names.sort, Topic.cached_attributes.sort
127
- assert_equal time_related_columns_on_topic.sort, Topic.cached_attributes.sort
128
- end
129
-
130
- def test_accessing_cached_attributes_caches_the_converted_values_and_nothing_else
131
- t = topics(:first)
132
- cache = t.instance_variable_get "@attributes_cache"
133
-
134
- assert_not_nil cache
135
- assert cache.empty?
136
-
137
- all_columns = Topic.columns.map(&:name)
138
- cached_columns = time_related_columns_on_topic
139
- uncached_columns = all_columns - cached_columns
140
-
141
- all_columns.each do |attr_name|
142
- attribute_gets_cached = Topic.cache_attribute?(attr_name)
143
- val = t.send attr_name unless attr_name == "type"
144
- if attribute_gets_cached
145
- assert cached_columns.include?(attr_name)
146
- assert_equal val, cache[attr_name]
147
- else
148
- assert uncached_columns.include?(attr_name)
149
- assert !cache.include?(attr_name)
150
- end
151
- end
152
- end
153
-
154
- def test_time_attributes_are_retrieved_in_current_time_zone
155
- in_time_zone "Pacific Time (US & Canada)" do
156
- utc_time = Time.utc(2008, 1, 1)
157
- record = @target.new
158
- record[:written_on] = utc_time
159
- assert_equal utc_time, record.written_on # record.written on is equal to (i.e., simultaneous with) utc_time
160
- assert_kind_of ActiveSupport::TimeWithZone, record.written_on # but is a TimeWithZone
161
- assert_equal ActiveSupport::TimeZone["Pacific Time (US & Canada)"], record.written_on.time_zone # and is in the current Time.zone
162
- assert_equal Time.utc(2007, 12, 31, 16), record.written_on.time # and represents time values adjusted accordingly
163
- end
164
- end
165
-
166
- def test_setting_time_zone_aware_attribute_to_utc
167
- in_time_zone "Pacific Time (US & Canada)" do
168
- utc_time = Time.utc(2008, 1, 1)
169
- record = @target.new
170
- record.written_on = utc_time
171
- assert_equal utc_time, record.written_on
172
- assert_equal ActiveSupport::TimeZone["Pacific Time (US & Canada)"], record.written_on.time_zone
173
- assert_equal Time.utc(2007, 12, 31, 16), record.written_on.time
174
- end
175
- end
176
-
177
- def test_setting_time_zone_aware_attribute_in_other_time_zone
178
- utc_time = Time.utc(2008, 1, 1)
179
- cst_time = utc_time.in_time_zone("Central Time (US & Canada)")
180
- in_time_zone "Pacific Time (US & Canada)" do
181
- record = @target.new
182
- record.written_on = cst_time
183
- assert_equal utc_time, record.written_on
184
- assert_equal ActiveSupport::TimeZone["Pacific Time (US & Canada)"], record.written_on.time_zone
185
- assert_equal Time.utc(2007, 12, 31, 16), record.written_on.time
186
- end
187
- end
188
-
189
- def test_setting_time_zone_aware_attribute_with_string
190
- utc_time = Time.utc(2008, 1, 1)
191
- (-11..13).each do |timezone_offset|
192
- time_string = utc_time.in_time_zone(timezone_offset).to_s
193
- in_time_zone "Pacific Time (US & Canada)" do
194
- record = @target.new
195
- record.written_on = time_string
196
- assert_equal Time.zone.parse(time_string), record.written_on
197
- assert_equal ActiveSupport::TimeZone["Pacific Time (US & Canada)"], record.written_on.time_zone
198
- assert_equal Time.utc(2007, 12, 31, 16), record.written_on.time
199
- end
200
- end
201
- end
202
-
203
- def test_setting_time_zone_aware_attribute_to_blank_string_returns_nil
204
- in_time_zone "Pacific Time (US & Canada)" do
205
- record = @target.new
206
- record.written_on = ' '
207
- assert_nil record.written_on
208
- end
209
- end
210
-
211
- def test_setting_time_zone_aware_attribute_interprets_time_zone_unaware_string_in_time_zone
212
- time_string = 'Tue Jan 01 00:00:00 2008'
213
- (-11..13).each do |timezone_offset|
214
- in_time_zone timezone_offset do
215
- record = @target.new
216
- record.written_on = time_string
217
- assert_equal Time.zone.parse(time_string), record.written_on
218
- assert_equal ActiveSupport::TimeZone[timezone_offset], record.written_on.time_zone
219
- assert_equal Time.utc(2008, 1, 1), record.written_on.time
220
- end
221
- end
222
- end
223
-
224
- def test_setting_time_zone_aware_attribute_in_current_time_zone
225
- utc_time = Time.utc(2008, 1, 1)
226
- in_time_zone "Pacific Time (US & Canada)" do
227
- record = @target.new
228
- record.written_on = utc_time.in_time_zone
229
- assert_equal utc_time, record.written_on
230
- assert_equal ActiveSupport::TimeZone["Pacific Time (US & Canada)"], record.written_on.time_zone
231
- assert_equal Time.utc(2007, 12, 31, 16), record.written_on.time
232
- end
233
- end
234
-
235
- def test_setting_time_zone_conversion_for_attributes_should_write_value_on_class_variable
236
- Topic.skip_time_zone_conversion_for_attributes = [:field_a]
237
- Minimalistic.skip_time_zone_conversion_for_attributes = [:field_b]
238
-
239
- assert_equal [:field_a], Topic.skip_time_zone_conversion_for_attributes
240
- assert_equal [:field_b], Minimalistic.skip_time_zone_conversion_for_attributes
241
- end
242
-
243
- def test_read_attributes_respect_access_control
244
- privatize("title")
245
-
246
- topic = @target.new(:title => "The pros and cons of programming naked.")
247
- assert !topic.respond_to?(:title)
248
- exception = assert_raise(NoMethodError) { topic.title }
249
- assert_equal "Attempt to call private method", exception.message
250
- assert_equal "I'm private", topic.send(:title)
251
- end
252
-
253
- def test_write_attributes_respect_access_control
254
- privatize("title=(value)")
255
-
256
- topic = @target.new
257
- assert !topic.respond_to?(:title=)
258
- exception = assert_raise(NoMethodError) { topic.title = "Pants"}
259
- assert_equal "Attempt to call private method", exception.message
260
- topic.send(:title=, "Very large pants")
261
- end
262
-
263
- def test_question_attributes_respect_access_control
264
- privatize("title?")
265
-
266
- topic = @target.new(:title => "Isaac Newton's pants")
267
- assert !topic.respond_to?(:title?)
268
- exception = assert_raise(NoMethodError) { topic.title? }
269
- assert_equal "Attempt to call private method", exception.message
270
- assert topic.send(:title?)
271
- end
272
-
273
- def test_bulk_update_respects_access_control
274
- privatize("title=(value)")
275
-
276
- assert_raise(ActiveRecord::UnknownAttributeError) { topic = @target.new(:title => "Rants about pants") }
277
- assert_raise(ActiveRecord::UnknownAttributeError) { @target.new.attributes = { :title => "Ants in pants" } }
278
- end
279
-
280
- private
281
- def time_related_columns_on_topic
282
- Topic.columns.select{|c| [:time, :date, :datetime, :timestamp].include?(c.type)}.map(&:name)
283
- end
284
-
285
- def in_time_zone(zone)
286
- old_zone = Time.zone
287
- old_tz = ActiveRecord::Base.time_zone_aware_attributes
288
-
289
- Time.zone = zone ? ActiveSupport::TimeZone[zone] : nil
290
- ActiveRecord::Base.time_zone_aware_attributes = !zone.nil?
291
- yield
292
- ensure
293
- Time.zone = old_zone
294
- ActiveRecord::Base.time_zone_aware_attributes = old_tz
295
- end
296
-
297
- def privatize(method_signature)
298
- @target.class_eval <<-private_method
299
- private
300
- def #{method_signature}
301
- "I'm private"
302
- end
303
- private_method
304
- end
305
- end