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,76 +0,0 @@
1
- require "cases/helper"
2
- require 'models/topic'
3
-
4
- class FinderRespondToTest < ActiveRecord::TestCase
5
-
6
- fixtures :topics
7
-
8
- def test_should_preserve_normal_respond_to_behaviour_and_respond_to_newly_added_method
9
- class << Topic; self; end.send(:define_method, :method_added_for_finder_respond_to_test) { }
10
- assert Topic.respond_to?(:method_added_for_finder_respond_to_test)
11
- ensure
12
- class << Topic; self; end.send(:remove_method, :method_added_for_finder_respond_to_test)
13
- end
14
-
15
- def test_should_preserve_normal_respond_to_behaviour_and_respond_to_standard_object_method
16
- assert Topic.respond_to?(:to_s)
17
- end
18
-
19
- def test_should_respond_to_find_by_one_attribute_before_caching
20
- ensure_topic_method_is_not_cached(:find_by_title)
21
- assert Topic.respond_to?(:find_by_title)
22
- end
23
-
24
- def test_should_respond_to_find_all_by_one_attribute
25
- ensure_topic_method_is_not_cached(:find_all_by_title)
26
- assert Topic.respond_to?(:find_all_by_title)
27
- end
28
-
29
- def test_should_respond_to_find_all_by_two_attributes
30
- ensure_topic_method_is_not_cached(:find_all_by_title_and_author_name)
31
- assert Topic.respond_to?(:find_all_by_title_and_author_name)
32
- end
33
-
34
- def test_should_respond_to_find_by_two_attributes
35
- ensure_topic_method_is_not_cached(:find_by_title_and_author_name)
36
- assert Topic.respond_to?(:find_by_title_and_author_name)
37
- end
38
-
39
- def test_should_respond_to_find_or_initialize_from_one_attribute
40
- ensure_topic_method_is_not_cached(:find_or_initialize_by_title)
41
- assert Topic.respond_to?(:find_or_initialize_by_title)
42
- end
43
-
44
- def test_should_respond_to_find_or_initialize_from_two_attributes
45
- ensure_topic_method_is_not_cached(:find_or_initialize_by_title_and_author_name)
46
- assert Topic.respond_to?(:find_or_initialize_by_title_and_author_name)
47
- end
48
-
49
- def test_should_respond_to_find_or_create_from_one_attribute
50
- ensure_topic_method_is_not_cached(:find_or_create_by_title)
51
- assert Topic.respond_to?(:find_or_create_by_title)
52
- end
53
-
54
- def test_should_respond_to_find_or_create_from_two_attributes
55
- ensure_topic_method_is_not_cached(:find_or_create_by_title_and_author_name)
56
- assert Topic.respond_to?(:find_or_create_by_title_and_author_name)
57
- end
58
-
59
- def test_should_not_respond_to_find_by_one_missing_attribute
60
- assert !Topic.respond_to?(:find_by_undertitle)
61
- end
62
-
63
- def test_should_not_respond_to_find_by_invalid_method_syntax
64
- assert !Topic.respond_to?(:fail_to_find_by_title)
65
- assert !Topic.respond_to?(:find_by_title?)
66
- assert !Topic.respond_to?(:fail_to_find_or_create_by_title)
67
- assert !Topic.respond_to?(:find_or_create_by_title?)
68
- end
69
-
70
- private
71
-
72
- def ensure_topic_method_is_not_cached(method_id)
73
- class << Topic; self; end.send(:remove_method, method_id) if Topic.public_methods.any? { |m| m.to_s == method_id.to_s }
74
- end
75
-
76
- end
@@ -1,1098 +0,0 @@
1
- require "cases/helper"
2
- require 'models/post'
3
- require 'models/author'
4
- require 'models/categorization'
5
- require 'models/comment'
6
- require 'models/company'
7
- require 'models/topic'
8
- require 'models/reply'
9
- require 'models/entrant'
10
- require 'models/developer'
11
- require 'models/customer'
12
- require 'models/job'
13
- require 'models/categorization'
14
-
15
- class DynamicFinderMatchTest < ActiveRecord::TestCase
16
- def test_find_no_match
17
- assert_nil ActiveRecord::DynamicFinderMatch.match("not_a_finder")
18
- end
19
-
20
- def test_find_by
21
- match = ActiveRecord::DynamicFinderMatch.match("find_by_age_and_sex_and_location")
22
- assert_not_nil match
23
- assert match.finder?
24
- assert_equal :first, match.finder
25
- assert_equal %w(age sex location), match.attribute_names
26
- end
27
-
28
- def find_by_bang
29
- match = ActiveRecord::DynamicFinderMatch.match("find_by_age_and_sex_and_location!")
30
- assert_not_nil match
31
- assert match.finder?
32
- assert match.bang?
33
- assert_equal :first, match.finder
34
- assert_equal %w(age sex location), match.attribute_names
35
- end
36
-
37
- def test_find_all_by
38
- match = ActiveRecord::DynamicFinderMatch.match("find_all_by_age_and_sex_and_location")
39
- assert_not_nil match
40
- assert match.finder?
41
- assert_equal :all, match.finder
42
- assert_equal %w(age sex location), match.attribute_names
43
- end
44
-
45
- def test_find_or_initialize_by
46
- match = ActiveRecord::DynamicFinderMatch.match("find_or_initialize_by_age_and_sex_and_location")
47
- assert_not_nil match
48
- assert !match.finder?
49
- assert match.instantiator?
50
- assert_equal :first, match.finder
51
- assert_equal :new, match.instantiator
52
- assert_equal %w(age sex location), match.attribute_names
53
- end
54
-
55
- def test_find_or_create_by
56
- match = ActiveRecord::DynamicFinderMatch.match("find_or_create_by_age_and_sex_and_location")
57
- assert_not_nil match
58
- assert !match.finder?
59
- assert match.instantiator?
60
- assert_equal :first, match.finder
61
- assert_equal :create, match.instantiator
62
- assert_equal %w(age sex location), match.attribute_names
63
- end
64
- end
65
-
66
- class FinderTest < ActiveRecord::TestCase
67
- fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :comments, :accounts, :authors, :customers
68
-
69
- def test_find_by_id_with_hash
70
- assert_raises(ActiveRecord::StatementInvalid) do
71
- Post.find_by_id(:limit => 1)
72
- end
73
- end
74
-
75
- def test_find_by_title_and_id_with_hash
76
- assert_raises(ActiveRecord::StatementInvalid) do
77
- Post.find_by_title_and_id('foo', :limit => 1)
78
- end
79
- end
80
-
81
- def test_find
82
- assert_equal(topics(:first).title, Topic.find(1).title)
83
- end
84
-
85
- # find should handle strings that come from URLs
86
- # (example: Category.find(params[:id]))
87
- def test_find_with_string
88
- assert_equal(Topic.find(1).title,Topic.find("1").title)
89
- end
90
-
91
- def test_exists
92
- assert Topic.exists?(1)
93
- assert Topic.exists?("1")
94
- assert Topic.exists?(:author_name => "David")
95
- assert Topic.exists?(:author_name => "Mary", :approved => true)
96
- assert Topic.exists?(["parent_id = ?", 1])
97
- assert !Topic.exists?(45)
98
-
99
- begin
100
- assert !Topic.exists?("foo")
101
- rescue ActiveRecord::StatementInvalid
102
- # PostgreSQL complains about string comparison with integer field
103
- rescue Exception
104
- flunk
105
- end
106
-
107
- assert_raise(NoMethodError) { Topic.exists?([1,2]) }
108
- end
109
-
110
- def test_exists_returns_true_with_one_record_and_no_args
111
- assert Topic.exists?
112
- end
113
-
114
- def test_does_not_exist_with_empty_table_and_no_args_given
115
- Topic.delete_all
116
- assert !Topic.exists?
117
- end
118
-
119
- def test_exists_with_aggregate_having_three_mappings
120
- existing_address = customers(:david).address
121
- assert Customer.exists?(:address => existing_address)
122
- end
123
-
124
- def test_exists_with_aggregate_having_three_mappings_with_one_difference
125
- existing_address = customers(:david).address
126
- assert !Customer.exists?(:address =>
127
- Address.new(existing_address.street, existing_address.city, existing_address.country + "1"))
128
- assert !Customer.exists?(:address =>
129
- Address.new(existing_address.street, existing_address.city + "1", existing_address.country))
130
- assert !Customer.exists?(:address =>
131
- Address.new(existing_address.street + "1", existing_address.city, existing_address.country))
132
- end
133
-
134
- def test_exists_with_scoped_include
135
- Developer.with_scope(:find => { :include => :projects, :order => "projects.name" }) do
136
- assert Developer.exists?
137
- end
138
- end
139
-
140
- def test_find_by_array_of_one_id
141
- assert_kind_of(Array, Topic.find([ 1 ]))
142
- assert_equal(1, Topic.find([ 1 ]).length)
143
- end
144
-
145
- def test_find_by_ids
146
- assert_equal 2, Topic.find(1, 2).size
147
- assert_equal topics(:second).title, Topic.find([2]).first.title
148
- end
149
-
150
- def test_find_by_ids_with_limit_and_offset
151
- assert_equal 2, Entrant.find([1,3,2], :limit => 2).size
152
- assert_equal 1, Entrant.find([1,3,2], :limit => 3, :offset => 2).size
153
-
154
- # Also test an edge case: If you have 11 results, and you set a
155
- # limit of 3 and offset of 9, then you should find that there
156
- # will be only 2 results, regardless of the limit.
157
- devs = Developer.find :all
158
- last_devs = Developer.find devs.map(&:id), :limit => 3, :offset => 9
159
- assert_equal 2, last_devs.size
160
- end
161
-
162
- def test_find_an_empty_array
163
- assert_equal [], Topic.find([])
164
- end
165
-
166
- def test_find_by_ids_missing_one
167
- assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1, 2, 45) }
168
- end
169
-
170
- def test_find_all_with_limit
171
- assert_equal(2, Entrant.find(:all, :limit => 2).size)
172
- assert_equal(0, Entrant.find(:all, :limit => 0).size)
173
- end
174
-
175
- def test_find_all_with_prepared_limit_and_offset
176
- entrants = Entrant.find(:all, :order => "id ASC", :limit => 2, :offset => 1)
177
-
178
- assert_equal(2, entrants.size)
179
- assert_equal(entrants(:second).name, entrants.first.name)
180
-
181
- assert_equal 3, Entrant.count
182
- entrants = Entrant.find(:all, :order => "id ASC", :limit => 2, :offset => 2)
183
- assert_equal(1, entrants.size)
184
- assert_equal(entrants(:third).name, entrants.first.name)
185
- end
186
-
187
- def test_find_all_with_limit_and_offset_and_multiple_order_clauses
188
- first_three_posts = Post.find :all, :order => 'author_id, id', :limit => 3, :offset => 0
189
- second_three_posts = Post.find :all, :order => ' author_id,id ', :limit => 3, :offset => 3
190
- last_posts = Post.find :all, :order => ' author_id, id ', :limit => 3, :offset => 6
191
-
192
- assert_equal [[0,3],[1,1],[1,2]], first_three_posts.map { |p| [p.author_id, p.id] }
193
- assert_equal [[1,4],[1,5],[1,6]], second_three_posts.map { |p| [p.author_id, p.id] }
194
- assert_equal [[2,7]], last_posts.map { |p| [p.author_id, p.id] }
195
- end
196
-
197
-
198
- def test_find_with_group
199
- developers = Developer.find(:all, :group => "salary", :select => "salary")
200
- assert_equal 4, developers.size
201
- assert_equal 4, developers.map(&:salary).uniq.size
202
- end
203
-
204
- def test_find_with_group_and_having
205
- developers = Developer.find(:all, :group => "salary", :having => "sum(salary) > 10000", :select => "salary")
206
- assert_equal 3, developers.size
207
- assert_equal 3, developers.map(&:salary).uniq.size
208
- assert developers.all? { |developer| developer.salary > 10000 }
209
- end
210
-
211
- def test_find_with_group_and_sanitized_having
212
- developers = Developer.find(:all, :group => "salary", :having => ["sum(salary) > ?", 10000], :select => "salary")
213
- assert_equal 3, developers.size
214
- assert_equal 3, developers.map(&:salary).uniq.size
215
- assert developers.all? { |developer| developer.salary > 10000 }
216
- end
217
-
218
- def test_find_with_entire_select_statement
219
- topics = Topic.find_by_sql "SELECT * FROM topics WHERE author_name = 'Mary'"
220
-
221
- assert_equal(1, topics.size)
222
- assert_equal(topics(:second).title, topics.first.title)
223
- end
224
-
225
- def test_find_with_prepared_select_statement
226
- topics = Topic.find_by_sql ["SELECT * FROM topics WHERE author_name = ?", "Mary"]
227
-
228
- assert_equal(1, topics.size)
229
- assert_equal(topics(:second).title, topics.first.title)
230
- end
231
-
232
- def test_find_by_sql_with_sti_on_joined_table
233
- accounts = Account.find_by_sql("SELECT * FROM accounts INNER JOIN companies ON companies.id = accounts.firm_id")
234
- assert_equal [Account], accounts.collect(&:class).uniq
235
- end
236
-
237
- def test_find_first
238
- first = Topic.find(:first, :conditions => "title = 'The First Topic'")
239
- assert_equal(topics(:first).title, first.title)
240
- end
241
-
242
- def test_find_first_failing
243
- first = Topic.find(:first, :conditions => "title = 'The First Topic!'")
244
- assert_nil(first)
245
- end
246
-
247
- def test_first
248
- assert_equal topics(:second).title, Topic.first(:conditions => "title = 'The Second Topic of the day'").title
249
- end
250
-
251
- def test_first_failing
252
- assert_nil Topic.first(:conditions => "title = 'The Second Topic of the day!'")
253
- end
254
-
255
- def test_unexisting_record_exception_handling
256
- assert_raise(ActiveRecord::RecordNotFound) {
257
- Topic.find(1).parent
258
- }
259
-
260
- Topic.find(2).topic
261
- end
262
-
263
- def test_find_only_some_columns
264
- topic = Topic.find(1, :select => "author_name")
265
- assert_raise(ActiveRecord::MissingAttributeError) {topic.title}
266
- assert_equal "David", topic.author_name
267
- assert !topic.attribute_present?("title")
268
- #assert !topic.respond_to?("title")
269
- assert topic.attribute_present?("author_name")
270
- assert topic.respond_to?("author_name")
271
- end
272
-
273
- def test_find_on_blank_conditions
274
- [nil, " ", [], {}].each do |blank|
275
- assert_nothing_raised { Topic.find(:first, :conditions => blank) }
276
- end
277
- end
278
-
279
- def test_find_on_blank_bind_conditions
280
- [ [""], ["",{}] ].each do |blank|
281
- assert_nothing_raised { Topic.find(:first, :conditions => blank) }
282
- end
283
- end
284
-
285
- def test_find_on_array_conditions
286
- assert Topic.find(1, :conditions => ["approved = ?", false])
287
- assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => ["approved = ?", true]) }
288
- end
289
-
290
- def test_find_on_hash_conditions
291
- assert Topic.find(1, :conditions => { :approved => false })
292
- assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { :approved => true }) }
293
- end
294
-
295
- def test_find_on_hash_conditions_with_explicit_table_name
296
- assert Topic.find(1, :conditions => { 'topics.approved' => false })
297
- assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { 'topics.approved' => true }) }
298
- end
299
-
300
- def test_find_on_hash_conditions_with_hashed_table_name
301
- assert Topic.find(1, :conditions => {:topics => { :approved => false }})
302
- assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => {:topics => { :approved => true }}) }
303
- end
304
-
305
- def test_find_with_hash_conditions_on_joined_table
306
- firms = Firm.all :joins => :account, :conditions => {:accounts => { :credit_limit => 50 }}
307
- assert_equal 1, firms.size
308
- assert_equal companies(:first_firm), firms.first
309
- end
310
-
311
- def test_find_with_hash_conditions_on_joined_table_and_with_range
312
- firms = DependentFirm.all :joins => :account, :conditions => {:name => 'RailsCore', :accounts => { :credit_limit => 55..60 }}
313
- assert_equal 1, firms.size
314
- assert_equal companies(:rails_core), firms.first
315
- end
316
-
317
- def test_find_on_hash_conditions_with_explicit_table_name_and_aggregate
318
- david = customers(:david)
319
- assert Customer.find(david.id, :conditions => { 'customers.name' => david.name, :address => david.address })
320
- assert_raise(ActiveRecord::RecordNotFound) {
321
- Customer.find(david.id, :conditions => { 'customers.name' => david.name + "1", :address => david.address })
322
- }
323
- end
324
-
325
- def test_find_on_association_proxy_conditions
326
- assert_equal [1, 2, 3, 5, 6, 7, 8, 9, 10], Comment.find_all_by_post_id(authors(:david).posts).map(&:id).sort
327
- end
328
-
329
- def test_find_on_hash_conditions_with_range
330
- assert_equal [1,2], Topic.find(:all, :conditions => { :id => 1..2 }).map(&:id).sort
331
- assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { :id => 2..3 }) }
332
- end
333
-
334
- def test_find_on_hash_conditions_with_end_exclusive_range
335
- assert_equal [1,2,3], Topic.find(:all, :conditions => { :id => 1..3 }).map(&:id).sort
336
- assert_equal [1,2], Topic.find(:all, :conditions => { :id => 1...3 }).map(&:id).sort
337
- assert_raise(ActiveRecord::RecordNotFound) { Topic.find(3, :conditions => { :id => 2...3 }) }
338
- end
339
-
340
- def test_find_on_hash_conditions_with_multiple_ranges
341
- assert_equal [1,2,3], Comment.find(:all, :conditions => { :id => 1..3, :post_id => 1..2 }).map(&:id).sort
342
- assert_equal [1], Comment.find(:all, :conditions => { :id => 1..1, :post_id => 1..10 }).map(&:id).sort
343
- end
344
-
345
- def test_find_on_multiple_hash_conditions
346
- assert Topic.find(1, :conditions => { :author_name => "David", :title => "The First Topic", :replies_count => 1, :approved => false })
347
- assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { :author_name => "David", :title => "The First Topic", :replies_count => 1, :approved => true }) }
348
- assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { :author_name => "David", :title => "HHC", :replies_count => 1, :approved => false }) }
349
- assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { :author_name => "David", :title => "The First Topic", :replies_count => 1, :approved => true }) }
350
- end
351
-
352
- def test_condition_interpolation
353
- assert_kind_of Firm, Company.find(:first, :conditions => ["name = '%s'", "37signals"])
354
- assert_nil Company.find(:first, :conditions => ["name = '%s'", "37signals!"])
355
- assert_nil Company.find(:first, :conditions => ["name = '%s'", "37signals!' OR 1=1"])
356
- assert_kind_of Time, Topic.find(:first, :conditions => ["id = %d", 1]).written_on
357
- end
358
-
359
- def test_condition_array_interpolation
360
- assert_kind_of Firm, Company.find(:first, :conditions => ["name = '%s'", "37signals"])
361
- assert_nil Company.find(:first, :conditions => ["name = '%s'", "37signals!"])
362
- assert_nil Company.find(:first, :conditions => ["name = '%s'", "37signals!' OR 1=1"])
363
- assert_kind_of Time, Topic.find(:first, :conditions => ["id = %d", 1]).written_on
364
- end
365
-
366
- def test_condition_hash_interpolation
367
- assert_kind_of Firm, Company.find(:first, :conditions => { :name => "37signals"})
368
- assert_nil Company.find(:first, :conditions => { :name => "37signals!"})
369
- assert_kind_of Time, Topic.find(:first, :conditions => {:id => 1}).written_on
370
- end
371
-
372
- def test_hash_condition_find_malformed
373
- assert_raise(ActiveRecord::StatementInvalid) {
374
- Company.find(:first, :conditions => { :id => 2, :dhh => true })
375
- }
376
- end
377
-
378
- def test_hash_condition_find_with_improper_nested_hashes
379
- assert_raise(ActiveRecord::StatementInvalid) {
380
- Company.find(:first, :conditions => { :name => { :companies => { :id => 1 }}})
381
- }
382
- end
383
-
384
- def test_hash_condition_find_with_dot_in_nested_column_name
385
- assert_raise(ActiveRecord::StatementInvalid) {
386
- Company.find(:first, :conditions => { :name => { "companies.id" => 1 }})
387
- }
388
- end
389
-
390
- def test_hash_condition_find_with_dot_in_column_name_okay
391
- assert Company.find(:first, :conditions => { "companies.id" => 1 })
392
- end
393
-
394
- def test_hash_condition_find_with_escaped_characters
395
- Company.create("name" => "Ain't noth'n like' \#stuff")
396
- assert Company.find(:first, :conditions => { :name => "Ain't noth'n like' \#stuff" })
397
- end
398
-
399
- def test_hash_condition_find_with_array
400
- p1, p2 = Post.find(:all, :limit => 2, :order => 'id asc')
401
- assert_equal [p1, p2], Post.find(:all, :conditions => { :id => [p1, p2] }, :order => 'id asc')
402
- assert_equal [p1, p2], Post.find(:all, :conditions => { :id => [p1, p2.id] }, :order => 'id asc')
403
- end
404
-
405
- def test_hash_condition_find_with_nil
406
- topic = Topic.find(:first, :conditions => { :last_read => nil } )
407
- assert_not_nil topic
408
- assert_nil topic.last_read
409
- end
410
-
411
- def test_hash_condition_find_with_aggregate_having_one_mapping
412
- balance = customers(:david).balance
413
- assert_kind_of Money, balance
414
- found_customer = Customer.find(:first, :conditions => {:balance => balance})
415
- assert_equal customers(:david), found_customer
416
- end
417
-
418
- def test_hash_condition_find_with_aggregate_attribute_having_same_name_as_field_and_key_value_being_aggregate
419
- gps_location = customers(:david).gps_location
420
- assert_kind_of GpsLocation, gps_location
421
- found_customer = Customer.find(:first, :conditions => {:gps_location => gps_location})
422
- assert_equal customers(:david), found_customer
423
- end
424
-
425
- def test_hash_condition_find_with_aggregate_having_one_mapping_and_key_value_being_attribute_value
426
- balance = customers(:david).balance
427
- assert_kind_of Money, balance
428
- found_customer = Customer.find(:first, :conditions => {:balance => balance.amount})
429
- assert_equal customers(:david), found_customer
430
- end
431
-
432
- def test_hash_condition_find_with_aggregate_attribute_having_same_name_as_field_and_key_value_being_attribute_value
433
- gps_location = customers(:david).gps_location
434
- assert_kind_of GpsLocation, gps_location
435
- found_customer = Customer.find(:first, :conditions => {:gps_location => gps_location.gps_location})
436
- assert_equal customers(:david), found_customer
437
- end
438
-
439
- def test_hash_condition_find_with_aggregate_having_three_mappings
440
- address = customers(:david).address
441
- assert_kind_of Address, address
442
- found_customer = Customer.find(:first, :conditions => {:address => address})
443
- assert_equal customers(:david), found_customer
444
- end
445
-
446
- def test_hash_condition_find_with_one_condition_being_aggregate_and_another_not
447
- address = customers(:david).address
448
- assert_kind_of Address, address
449
- found_customer = Customer.find(:first, :conditions => {:address => address, :name => customers(:david).name})
450
- assert_equal customers(:david), found_customer
451
- end
452
-
453
- def test_bind_variables
454
- assert_kind_of Firm, Company.find(:first, :conditions => ["name = ?", "37signals"])
455
- assert_nil Company.find(:first, :conditions => ["name = ?", "37signals!"])
456
- assert_nil Company.find(:first, :conditions => ["name = ?", "37signals!' OR 1=1"])
457
- assert_kind_of Time, Topic.find(:first, :conditions => ["id = ?", 1]).written_on
458
- assert_raise(ActiveRecord::PreparedStatementInvalid) {
459
- Company.find(:first, :conditions => ["id=? AND name = ?", 2])
460
- }
461
- assert_raise(ActiveRecord::PreparedStatementInvalid) {
462
- Company.find(:first, :conditions => ["id=?", 2, 3, 4])
463
- }
464
- end
465
-
466
- def test_bind_variables_with_quotes
467
- Company.create("name" => "37signals' go'es agains")
468
- assert Company.find(:first, :conditions => ["name = ?", "37signals' go'es agains"])
469
- end
470
-
471
- def test_named_bind_variables_with_quotes
472
- Company.create("name" => "37signals' go'es agains")
473
- assert Company.find(:first, :conditions => ["name = :name", {:name => "37signals' go'es agains"}])
474
- end
475
-
476
- def test_bind_arity
477
- assert_nothing_raised { bind '' }
478
- assert_raise(ActiveRecord::PreparedStatementInvalid) { bind '', 1 }
479
-
480
- assert_raise(ActiveRecord::PreparedStatementInvalid) { bind '?' }
481
- assert_nothing_raised { bind '?', 1 }
482
- assert_raise(ActiveRecord::PreparedStatementInvalid) { bind '?', 1, 1 }
483
- end
484
-
485
- def test_named_bind_variables
486
- assert_equal '1', bind(':a', :a => 1) # ' ruby-mode
487
- assert_equal '1 1', bind(':a :a', :a => 1) # ' ruby-mode
488
-
489
- assert_nothing_raised { bind("'+00:00'", :foo => "bar") }
490
-
491
- assert_kind_of Firm, Company.find(:first, :conditions => ["name = :name", { :name => "37signals" }])
492
- assert_nil Company.find(:first, :conditions => ["name = :name", { :name => "37signals!" }])
493
- assert_nil Company.find(:first, :conditions => ["name = :name", { :name => "37signals!' OR 1=1" }])
494
- assert_kind_of Time, Topic.find(:first, :conditions => ["id = :id", { :id => 1 }]).written_on
495
- end
496
-
497
- def test_bind_enumerable
498
- quoted_abc = %(#{ActiveRecord::Base.connection.quote('a')},#{ActiveRecord::Base.connection.quote('b')},#{ActiveRecord::Base.connection.quote('c')})
499
-
500
- assert_equal '1,2,3', bind('?', [1, 2, 3])
501
- assert_equal quoted_abc, bind('?', %w(a b c))
502
-
503
- assert_equal '1,2,3', bind(':a', :a => [1, 2, 3])
504
- assert_equal quoted_abc, bind(':a', :a => %w(a b c)) # '
505
-
506
- require 'set'
507
- assert_equal '1,2,3', bind('?', Set.new([1, 2, 3]))
508
- assert_equal quoted_abc, bind('?', Set.new(%w(a b c)))
509
-
510
- assert_equal '1,2,3', bind(':a', :a => Set.new([1, 2, 3]))
511
- assert_equal quoted_abc, bind(':a', :a => Set.new(%w(a b c))) # '
512
- end
513
-
514
- def test_bind_empty_enumerable
515
- quoted_nil = ActiveRecord::Base.connection.quote(nil)
516
- assert_equal quoted_nil, bind('?', [])
517
- assert_equal " in (#{quoted_nil})", bind(' in (?)', [])
518
- assert_equal "foo in (#{quoted_nil})", bind('foo in (?)', [])
519
- end
520
-
521
- def test_bind_string
522
- assert_equal ActiveRecord::Base.connection.quote(''), bind('?', '')
523
- end
524
-
525
- def test_bind_chars
526
- quoted_bambi = ActiveRecord::Base.connection.quote("Bambi")
527
- quoted_bambi_and_thumper = ActiveRecord::Base.connection.quote("Bambi\nand\nThumper")
528
- assert_equal "name=#{quoted_bambi}", bind('name=?', "Bambi")
529
- assert_equal "name=#{quoted_bambi_and_thumper}", bind('name=?', "Bambi\nand\nThumper")
530
- assert_equal "name=#{quoted_bambi}", bind('name=?', "Bambi".mb_chars)
531
- assert_equal "name=#{quoted_bambi_and_thumper}", bind('name=?', "Bambi\nand\nThumper".mb_chars)
532
- end
533
-
534
- def test_bind_record
535
- o = Struct.new(:quoted_id).new(1)
536
- assert_equal '1', bind('?', o)
537
-
538
- os = [o] * 3
539
- assert_equal '1,1,1', bind('?', os)
540
- end
541
-
542
- def test_named_bind_with_postgresql_type_casts
543
- l = Proc.new { bind(":a::integer '2009-01-01'::date", :a => '10') }
544
- assert_nothing_raised(&l)
545
- assert_equal "#{ActiveRecord::Base.quote_value('10')}::integer '2009-01-01'::date", l.call
546
- end
547
-
548
- def test_string_sanitation
549
- assert_not_equal "'something ' 1=1'", ActiveRecord::Base.sanitize("something ' 1=1")
550
- assert_equal "'something; select table'", ActiveRecord::Base.sanitize("something; select table")
551
- end
552
-
553
- def test_count
554
- assert_equal(0, Entrant.count(:conditions => "id > 3"))
555
- assert_equal(1, Entrant.count(:conditions => ["id > ?", 2]))
556
- assert_equal(2, Entrant.count(:conditions => ["id > ?", 1]))
557
- end
558
-
559
- def test_count_by_sql
560
- assert_equal(0, Entrant.count_by_sql("SELECT COUNT(*) FROM entrants WHERE id > 3"))
561
- assert_equal(1, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 2]))
562
- assert_equal(2, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 1]))
563
- end
564
-
565
- def test_dynamic_finders_should_go_through_the_find_class_method
566
- Topic.expects(:find).with(:first, :conditions => { :title => 'The First Topic!' })
567
- Topic.find_by_title("The First Topic!")
568
-
569
- Topic.expects(:find).with(:last, :conditions => { :title => 'The Last Topic!' })
570
- Topic.find_last_by_title("The Last Topic!")
571
-
572
- Topic.expects(:find).with(:all, :conditions => { :title => 'A Topic.' })
573
- Topic.find_all_by_title("A Topic.")
574
-
575
- Topic.expects(:find).with(:first, :conditions => { :title => 'Does not exist yet for sure!' }).times(2)
576
- Topic.find_or_initialize_by_title('Does not exist yet for sure!')
577
- Topic.find_or_create_by_title('Does not exist yet for sure!')
578
- end
579
-
580
- def test_find_by_one_attribute
581
- assert_equal topics(:first), Topic.find_by_title("The First Topic")
582
- assert_nil Topic.find_by_title("The First Topic!")
583
- end
584
-
585
- def test_find_by_one_attribute_bang
586
- assert_equal topics(:first), Topic.find_by_title!("The First Topic")
587
- assert_raise(ActiveRecord::RecordNotFound) { Topic.find_by_title!("The First Topic!") }
588
- end
589
-
590
- def test_find_by_one_attribute_caches_dynamic_finder
591
- # ensure this test can run independently of order
592
- class << Topic; self; end.send(:remove_method, :find_by_title) if Topic.public_methods.any? { |m| m.to_s == 'find_by_title' }
593
- assert !Topic.public_methods.any? { |m| m.to_s == 'find_by_title' }
594
- t = Topic.find_by_title("The First Topic")
595
- assert Topic.public_methods.any? { |m| m.to_s == 'find_by_title' }
596
- end
597
-
598
- def test_dynamic_finder_returns_same_results_after_caching
599
- # ensure this test can run independently of order
600
- class << Topic; self; end.send(:remove_method, :find_by_title) if Topic.public_method_defined?(:find_by_title)
601
- t = Topic.find_by_title("The First Topic")
602
- assert_equal t, Topic.find_by_title("The First Topic") # find_by_title has been cached
603
- end
604
-
605
- def test_find_by_one_attribute_with_order_option
606
- assert_equal accounts(:signals37), Account.find_by_credit_limit(50, :order => 'id')
607
- assert_equal accounts(:rails_core_account), Account.find_by_credit_limit(50, :order => 'id DESC')
608
- end
609
-
610
- def test_find_by_one_attribute_with_conditions
611
- assert_equal accounts(:rails_core_account), Account.find_by_credit_limit(50, :conditions => ['firm_id = ?', 6])
612
- end
613
-
614
- def test_find_by_one_attribute_that_is_an_aggregate
615
- address = customers(:david).address
616
- assert_kind_of Address, address
617
- found_customer = Customer.find_by_address(address)
618
- assert_equal customers(:david), found_customer
619
- end
620
-
621
- def test_find_by_one_attribute_that_is_an_aggregate_with_one_attribute_difference
622
- address = customers(:david).address
623
- assert_kind_of Address, address
624
- missing_address = Address.new(address.street, address.city, address.country + "1")
625
- assert_nil Customer.find_by_address(missing_address)
626
- missing_address = Address.new(address.street, address.city + "1", address.country)
627
- assert_nil Customer.find_by_address(missing_address)
628
- missing_address = Address.new(address.street + "1", address.city, address.country)
629
- assert_nil Customer.find_by_address(missing_address)
630
- end
631
-
632
- def test_find_by_two_attributes_that_are_both_aggregates
633
- balance = customers(:david).balance
634
- address = customers(:david).address
635
- assert_kind_of Money, balance
636
- assert_kind_of Address, address
637
- found_customer = Customer.find_by_balance_and_address(balance, address)
638
- assert_equal customers(:david), found_customer
639
- end
640
-
641
- def test_find_by_two_attributes_with_one_being_an_aggregate
642
- balance = customers(:david).balance
643
- assert_kind_of Money, balance
644
- found_customer = Customer.find_by_balance_and_name(balance, customers(:david).name)
645
- assert_equal customers(:david), found_customer
646
- end
647
-
648
- def test_dynamic_finder_on_one_attribute_with_conditions_caches_method
649
- # ensure this test can run independently of order
650
- class << Account; self; end.send(:remove_method, :find_by_credit_limit) if Account.public_methods.any? { |m| m.to_s == 'find_by_credit_limit' }
651
- assert !Account.public_methods.any? { |m| m.to_s == 'find_by_credit_limit' }
652
- a = Account.find_by_credit_limit(50, :conditions => ['firm_id = ?', 6])
653
- assert Account.public_methods.any? { |m| m.to_s == 'find_by_credit_limit' }
654
- end
655
-
656
- def test_dynamic_finder_on_one_attribute_with_conditions_returns_same_results_after_caching
657
- # ensure this test can run independently of order
658
- class << Account; self; end.send(:remove_method, :find_by_credit_limit) if Account.public_methods.any? { |m| m.to_s == 'find_by_credit_limit' }
659
- a = Account.find_by_credit_limit(50, :conditions => ['firm_id = ?', 6])
660
- assert_equal a, Account.find_by_credit_limit(50, :conditions => ['firm_id = ?', 6]) # find_by_credit_limit has been cached
661
- end
662
-
663
- def test_find_by_one_attribute_with_several_options
664
- assert_equal accounts(:unknown), Account.find_by_credit_limit(50, :order => 'id DESC', :conditions => ['id != ?', 3])
665
- end
666
-
667
- def test_find_by_one_missing_attribute
668
- assert_raise(NoMethodError) { Topic.find_by_undertitle("The First Topic!") }
669
- end
670
-
671
- def test_find_by_invalid_method_syntax
672
- assert_raise(NoMethodError) { Topic.fail_to_find_by_title("The First Topic") }
673
- assert_raise(NoMethodError) { Topic.find_by_title?("The First Topic") }
674
- assert_raise(NoMethodError) { Topic.fail_to_find_or_create_by_title("Nonexistent Title") }
675
- assert_raise(NoMethodError) { Topic.find_or_create_by_title?("Nonexistent Title") }
676
- end
677
-
678
- def test_find_by_two_attributes
679
- assert_equal topics(:first), Topic.find_by_title_and_author_name("The First Topic", "David")
680
- assert_nil Topic.find_by_title_and_author_name("The First Topic", "Mary")
681
- end
682
-
683
- def test_find_last_by_one_attribute
684
- assert_equal Topic.last, Topic.find_last_by_title(Topic.last.title)
685
- assert_nil Topic.find_last_by_title("A title with no matches")
686
- end
687
-
688
- def test_find_last_by_one_attribute_caches_dynamic_finder
689
- # ensure this test can run independently of order
690
- class << Topic; self; end.send(:remove_method, :find_last_by_title) if Topic.public_methods.any? { |m| m.to_s == 'find_last_by_title' }
691
- assert !Topic.public_methods.any? { |m| m.to_s == 'find_last_by_title' }
692
- t = Topic.find_last_by_title(Topic.last.title)
693
- assert Topic.public_methods.any? { |m| m.to_s == 'find_last_by_title' }
694
- end
695
-
696
- def test_find_last_by_invalid_method_syntax
697
- assert_raise(NoMethodError) { Topic.fail_to_find_last_by_title("The First Topic") }
698
- assert_raise(NoMethodError) { Topic.find_last_by_title?("The First Topic") }
699
- end
700
-
701
- def test_find_last_by_one_attribute_with_several_options
702
- assert_equal accounts(:signals37), Account.find_last_by_credit_limit(50, :order => 'id DESC', :conditions => ['id != ?', 3])
703
- end
704
-
705
- def test_find_last_by_one_missing_attribute
706
- assert_raise(NoMethodError) { Topic.find_last_by_undertitle("The Last Topic!") }
707
- end
708
-
709
- def test_find_last_by_two_attributes
710
- topic = Topic.last
711
- assert_equal topic, Topic.find_last_by_title_and_author_name(topic.title, topic.author_name)
712
- assert_nil Topic.find_last_by_title_and_author_name(topic.title, "Anonymous")
713
- end
714
-
715
- def test_find_all_by_one_attribute
716
- topics = Topic.find_all_by_content("Have a nice day")
717
- assert_equal 2, topics.size
718
- assert topics.include?(topics(:first))
719
-
720
- assert_equal [], Topic.find_all_by_title("The First Topic!!")
721
- end
722
-
723
- def test_find_all_by_one_attribute_that_is_an_aggregate
724
- balance = customers(:david).balance
725
- assert_kind_of Money, balance
726
- found_customers = Customer.find_all_by_balance(balance)
727
- assert_equal 1, found_customers.size
728
- assert_equal customers(:david), found_customers.first
729
- end
730
-
731
- def test_find_all_by_two_attributes_that_are_both_aggregates
732
- balance = customers(:david).balance
733
- address = customers(:david).address
734
- assert_kind_of Money, balance
735
- assert_kind_of Address, address
736
- found_customers = Customer.find_all_by_balance_and_address(balance, address)
737
- assert_equal 1, found_customers.size
738
- assert_equal customers(:david), found_customers.first
739
- end
740
-
741
- def test_find_all_by_two_attributes_with_one_being_an_aggregate
742
- balance = customers(:david).balance
743
- assert_kind_of Money, balance
744
- found_customers = Customer.find_all_by_balance_and_name(balance, customers(:david).name)
745
- assert_equal 1, found_customers.size
746
- assert_equal customers(:david), found_customers.first
747
- end
748
-
749
- def test_find_all_by_one_attribute_with_options
750
- topics = Topic.find_all_by_content("Have a nice day", :order => "id DESC")
751
- assert topics(:first), topics.last
752
-
753
- topics = Topic.find_all_by_content("Have a nice day", :order => "id")
754
- assert topics(:first), topics.first
755
- end
756
-
757
- def test_find_all_by_array_attribute
758
- assert_equal 2, Topic.find_all_by_title(["The First Topic", "The Second Topic of the day"]).size
759
- end
760
-
761
- def test_find_all_by_boolean_attribute
762
- topics = Topic.find_all_by_approved(false)
763
- assert_equal 1, topics.size
764
- assert topics.include?(topics(:first))
765
-
766
- topics = Topic.find_all_by_approved(true)
767
- assert_equal 3, topics.size
768
- assert topics.include?(topics(:second))
769
- end
770
-
771
- def test_find_by_nil_attribute
772
- topic = Topic.find_by_last_read nil
773
- assert_not_nil topic
774
- assert_nil topic.last_read
775
- end
776
-
777
- def test_find_all_by_nil_attribute
778
- topics = Topic.find_all_by_last_read nil
779
- assert_equal 3, topics.size
780
- assert topics.collect(&:last_read).all?(&:nil?)
781
- end
782
-
783
- def test_find_by_nil_and_not_nil_attributes
784
- topic = Topic.find_by_last_read_and_author_name nil, "Mary"
785
- assert_equal "Mary", topic.author_name
786
- end
787
-
788
- def test_find_all_by_nil_and_not_nil_attributes
789
- topics = Topic.find_all_by_last_read_and_author_name nil, "Mary"
790
- assert_equal 1, topics.size
791
- assert_equal "Mary", topics[0].author_name
792
- end
793
-
794
- def test_find_or_create_from_one_attribute
795
- number_of_companies = Company.count
796
- sig38 = Company.find_or_create_by_name("38signals")
797
- assert_equal number_of_companies + 1, Company.count
798
- assert_equal sig38, Company.find_or_create_by_name("38signals")
799
- assert !sig38.new_record?
800
- end
801
-
802
- def test_find_or_create_from_two_attributes
803
- number_of_topics = Topic.count
804
- another = Topic.find_or_create_by_title_and_author_name("Another topic","John")
805
- assert_equal number_of_topics + 1, Topic.count
806
- assert_equal another, Topic.find_or_create_by_title_and_author_name("Another topic", "John")
807
- assert !another.new_record?
808
- end
809
-
810
- def test_find_or_create_from_two_attributes_with_one_being_an_aggregate
811
- number_of_customers = Customer.count
812
- created_customer = Customer.find_or_create_by_balance_and_name(Money.new(123), "Elizabeth")
813
- assert_equal number_of_customers + 1, Customer.count
814
- assert_equal created_customer, Customer.find_or_create_by_balance(Money.new(123), "Elizabeth")
815
- assert !created_customer.new_record?
816
- end
817
-
818
- def test_find_or_create_from_one_attribute_and_hash
819
- number_of_companies = Company.count
820
- sig38 = Company.find_or_create_by_name({:name => "38signals", :firm_id => 17, :client_of => 23})
821
- assert_equal number_of_companies + 1, Company.count
822
- assert_equal sig38, Company.find_or_create_by_name({:name => "38signals", :firm_id => 17, :client_of => 23})
823
- assert !sig38.new_record?
824
- assert_equal "38signals", sig38.name
825
- assert_equal 17, sig38.firm_id
826
- assert_equal 23, sig38.client_of
827
- end
828
-
829
- def test_find_or_create_from_one_aggregate_attribute
830
- number_of_customers = Customer.count
831
- created_customer = Customer.find_or_create_by_balance(Money.new(123))
832
- assert_equal number_of_customers + 1, Customer.count
833
- assert_equal created_customer, Customer.find_or_create_by_balance(Money.new(123))
834
- assert !created_customer.new_record?
835
- end
836
-
837
- def test_find_or_create_from_one_aggregate_attribute_and_hash
838
- number_of_customers = Customer.count
839
- balance = Money.new(123)
840
- name = "Elizabeth"
841
- created_customer = Customer.find_or_create_by_balance({:balance => balance, :name => name})
842
- assert_equal number_of_customers + 1, Customer.count
843
- assert_equal created_customer, Customer.find_or_create_by_balance({:balance => balance, :name => name})
844
- assert !created_customer.new_record?
845
- assert_equal balance, created_customer.balance
846
- assert_equal name, created_customer.name
847
- end
848
-
849
- def test_find_or_initialize_from_one_attribute
850
- sig38 = Company.find_or_initialize_by_name("38signals")
851
- assert_equal "38signals", sig38.name
852
- assert sig38.new_record?
853
- end
854
-
855
- def test_find_or_initialize_from_one_aggregate_attribute
856
- new_customer = Customer.find_or_initialize_by_balance(Money.new(123))
857
- assert_equal 123, new_customer.balance.amount
858
- assert new_customer.new_record?
859
- end
860
-
861
- def test_find_or_initialize_from_one_attribute_should_not_set_attribute_even_when_protected
862
- c = Company.find_or_initialize_by_name({:name => "Fortune 1000", :rating => 1000})
863
- assert_equal "Fortune 1000", c.name
864
- assert_not_equal 1000, c.rating
865
- assert c.valid?
866
- assert c.new_record?
867
- end
868
-
869
- def test_find_or_create_from_one_attribute_should_not_set_attribute_even_when_protected
870
- c = Company.find_or_create_by_name({:name => "Fortune 1000", :rating => 1000})
871
- assert_equal "Fortune 1000", c.name
872
- assert_not_equal 1000, c.rating
873
- assert c.valid?
874
- assert !c.new_record?
875
- end
876
-
877
- def test_find_or_initialize_from_one_attribute_should_set_attribute_even_when_protected_and_also_set_the_hash
878
- c = Company.find_or_initialize_by_rating(1000, {:name => "Fortune 1000"})
879
- assert_equal "Fortune 1000", c.name
880
- assert_equal 1000, c.rating
881
- assert c.valid?
882
- assert c.new_record?
883
- end
884
-
885
- def test_find_or_create_from_one_attribute_should_set_attribute_even_when_protected_and_also_set_the_hash
886
- c = Company.find_or_create_by_rating(1000, {:name => "Fortune 1000"})
887
- assert_equal "Fortune 1000", c.name
888
- assert_equal 1000, c.rating
889
- assert c.valid?
890
- assert !c.new_record?
891
- end
892
-
893
- def test_find_or_initialize_from_one_attribute_should_set_attribute_even_when_protected
894
- c = Company.find_or_initialize_by_name_and_rating("Fortune 1000", 1000)
895
- assert_equal "Fortune 1000", c.name
896
- assert_equal 1000, c.rating
897
- assert c.valid?
898
- assert c.new_record?
899
- end
900
-
901
- def test_find_or_create_from_one_attribute_should_set_attribute_even_when_protected
902
- c = Company.find_or_create_by_name_and_rating("Fortune 1000", 1000)
903
- assert_equal "Fortune 1000", c.name
904
- assert_equal 1000, c.rating
905
- assert c.valid?
906
- assert !c.new_record?
907
- end
908
-
909
- def test_find_or_initialize_should_set_protected_attributes_if_given_as_block
910
- c = Company.find_or_initialize_by_name(:name => "Fortune 1000") { |f| f.rating = 1000 }
911
- assert_equal "Fortune 1000", c.name
912
- assert_equal 1000.to_f, c.rating.to_f
913
- assert c.valid?
914
- assert c.new_record?
915
- end
916
-
917
- def test_find_or_create_should_set_protected_attributes_if_given_as_block
918
- c = Company.find_or_create_by_name(:name => "Fortune 1000") { |f| f.rating = 1000 }
919
- assert_equal "Fortune 1000", c.name
920
- assert_equal 1000.to_f, c.rating.to_f
921
- assert c.valid?
922
- assert !c.new_record?
923
- end
924
-
925
- def test_find_or_create_should_work_with_block_on_first_call
926
- class << Company
927
- undef_method(:find_or_create_by_name) if method_defined?(:find_or_create_by_name)
928
- end
929
- c = Company.find_or_create_by_name(:name => "Fortune 1000") { |f| f.rating = 1000 }
930
- assert_equal "Fortune 1000", c.name
931
- assert_equal 1000.to_f, c.rating.to_f
932
- assert c.valid?
933
- assert !c.new_record?
934
- end
935
-
936
- def test_dynamic_find_or_initialize_from_one_attribute_caches_method
937
- class << Company; self; end.send(:remove_method, :find_or_initialize_by_name) if Company.public_methods.any? { |m| m.to_s == 'find_or_initialize_by_name' }
938
- assert !Company.public_methods.any? { |m| m.to_s == 'find_or_initialize_by_name' }
939
- sig38 = Company.find_or_initialize_by_name("38signals")
940
- assert Company.public_methods.any? { |m| m.to_s == 'find_or_initialize_by_name' }
941
- end
942
-
943
- def test_find_or_initialize_from_two_attributes
944
- another = Topic.find_or_initialize_by_title_and_author_name("Another topic","John")
945
- assert_equal "Another topic", another.title
946
- assert_equal "John", another.author_name
947
- assert another.new_record?
948
- end
949
-
950
- def test_find_or_initialize_from_one_aggregate_attribute_and_one_not
951
- new_customer = Customer.find_or_initialize_by_balance_and_name(Money.new(123), "Elizabeth")
952
- assert_equal 123, new_customer.balance.amount
953
- assert_equal "Elizabeth", new_customer.name
954
- assert new_customer.new_record?
955
- end
956
-
957
- def test_find_or_initialize_from_one_attribute_and_hash
958
- sig38 = Company.find_or_initialize_by_name({:name => "38signals", :firm_id => 17, :client_of => 23})
959
- assert_equal "38signals", sig38.name
960
- assert_equal 17, sig38.firm_id
961
- assert_equal 23, sig38.client_of
962
- assert sig38.new_record?
963
- end
964
-
965
- def test_find_or_initialize_from_one_aggregate_attribute_and_hash
966
- balance = Money.new(123)
967
- name = "Elizabeth"
968
- new_customer = Customer.find_or_initialize_by_balance({:balance => balance, :name => name})
969
- assert_equal balance, new_customer.balance
970
- assert_equal name, new_customer.name
971
- assert new_customer.new_record?
972
- end
973
-
974
- def test_find_with_bad_sql
975
- assert_raise(ActiveRecord::StatementInvalid) { Topic.find_by_sql "select 1 from badtable" }
976
- end
977
-
978
- def test_find_with_invalid_params
979
- assert_raise(ArgumentError) { Topic.find :first, :join => "It should be `joins'" }
980
- assert_raise(ArgumentError) { Topic.find :first, :conditions => '1 = 1', :join => "It should be `joins'" }
981
- end
982
-
983
- def test_dynamic_finder_with_invalid_params
984
- assert_raise(ArgumentError) { Topic.find_by_title 'No Title', :join => "It should be `joins'" }
985
- end
986
-
987
- def test_find_all_with_join
988
- developers_on_project_one = Developer.find(
989
- :all,
990
- :joins => 'LEFT JOIN developers_projects ON developers.id = developers_projects.developer_id',
991
- :conditions => 'project_id=1'
992
- )
993
- assert_equal 3, developers_on_project_one.length
994
- developer_names = developers_on_project_one.map { |d| d.name }
995
- assert developer_names.include?('David')
996
- assert developer_names.include?('Jamis')
997
- end
998
-
999
- def test_joins_dont_clobber_id
1000
- first = Firm.find(
1001
- :first,
1002
- :joins => 'INNER JOIN companies AS clients ON clients.firm_id = companies.id',
1003
- :conditions => 'companies.id = 1'
1004
- )
1005
- assert_equal 1, first.id
1006
- end
1007
-
1008
- def test_joins_with_string_array
1009
- person_with_reader_and_post = Post.find(
1010
- :all,
1011
- :joins => [
1012
- "INNER JOIN categorizations ON categorizations.post_id = posts.id",
1013
- "INNER JOIN categories ON categories.id = categorizations.category_id AND categories.type = 'SpecialCategory'"
1014
- ]
1015
- )
1016
- assert_equal 1, person_with_reader_and_post.size
1017
- end
1018
-
1019
- def test_find_by_id_with_conditions_with_or
1020
- assert_nothing_raised do
1021
- Post.find([1,2,3],
1022
- :conditions => "posts.id <= 3 OR posts.#{QUOTED_TYPE} = 'Post'")
1023
- end
1024
- end
1025
-
1026
- # http://dev.rubyonrails.org/ticket/6778
1027
- def test_find_ignores_previously_inserted_record
1028
- post = Post.create!(:title => 'test', :body => 'it out')
1029
- assert_equal [], Post.find_all_by_id(nil)
1030
- end
1031
-
1032
- def test_find_by_empty_ids
1033
- assert_equal [], Post.find([])
1034
- end
1035
-
1036
- def test_find_by_empty_in_condition
1037
- assert_equal [], Post.find(:all, :conditions => ['id in (?)', []])
1038
- end
1039
-
1040
- def test_find_by_records
1041
- p1, p2 = Post.find(:all, :limit => 2, :order => 'id asc')
1042
- assert_equal [p1, p2], Post.find(:all, :conditions => ['id in (?)', [p1, p2]], :order => 'id asc')
1043
- assert_equal [p1, p2], Post.find(:all, :conditions => ['id in (?)', [p1, p2.id]], :order => 'id asc')
1044
- end
1045
-
1046
- def test_select_value
1047
- assert_equal "37signals", Company.connection.select_value("SELECT name FROM companies WHERE id = 1")
1048
- assert_nil Company.connection.select_value("SELECT name FROM companies WHERE id = -1")
1049
- # make sure we didn't break count...
1050
- assert_equal 0, Company.count_by_sql("SELECT COUNT(*) FROM companies WHERE name = 'Halliburton'")
1051
- assert_equal 1, Company.count_by_sql("SELECT COUNT(*) FROM companies WHERE name = '37signals'")
1052
- end
1053
-
1054
- def test_select_values
1055
- assert_equal ["1","2","3","4","5","6","7","8","9"], Company.connection.select_values("SELECT id FROM companies ORDER BY id").map! { |i| i.to_s }
1056
- assert_equal ["37signals","Summit","Microsoft", "Flamboyant Software", "Ex Nihilo", "RailsCore", "Leetsoft", "Jadedpixel", "Odegy"], Company.connection.select_values("SELECT name FROM companies ORDER BY id")
1057
- end
1058
-
1059
- def test_select_rows
1060
- assert_equal(
1061
- [["1", nil, nil, "37signals"],
1062
- ["2", "1", "2", "Summit"],
1063
- ["3", "1", "1", "Microsoft"]],
1064
- Company.connection.select_rows("SELECT id, firm_id, client_of, name FROM companies WHERE id IN (1,2,3) ORDER BY id").map! {|i| i.map! {|j| j.to_s unless j.nil?}})
1065
- assert_equal [["1", "37signals"], ["2", "Summit"], ["3", "Microsoft"]],
1066
- Company.connection.select_rows("SELECT id, name FROM companies WHERE id IN (1,2,3) ORDER BY id").map! {|i| i.map! {|j| j.to_s unless j.nil?}}
1067
- end
1068
-
1069
- def test_find_with_order_on_included_associations_with_construct_finder_sql_for_association_limiting_and_is_distinct
1070
- assert_equal 2, Post.find(:all, :include => { :authors => :author_address }, :order => ' author_addresses.id DESC ', :limit => 2).size
1071
-
1072
- assert_equal 3, Post.find(:all, :include => { :author => :author_address, :authors => :author_address},
1073
- :order => ' author_addresses_authors.id DESC ', :limit => 3).size
1074
- end
1075
-
1076
- def test_with_limiting_with_custom_select
1077
- posts = Post.find(:all, :include => :author, :select => ' posts.*, authors.id as "author_id"', :limit => 3, :order => 'posts.id')
1078
- assert_equal 3, posts.size
1079
- assert_equal [0, 1, 1], posts.map(&:author_id).sort
1080
- end
1081
-
1082
- def test_finder_with_scoped_from
1083
- all_topics = Topic.all
1084
-
1085
- Topic.with_scope(:find => { :from => 'fake_topics' }) do
1086
- assert_equal all_topics, Topic.all(:from => 'topics')
1087
- end
1088
- end
1089
-
1090
- protected
1091
- def bind(statement, *vars)
1092
- if vars.first.is_a?(Hash)
1093
- ActiveRecord::Base.send(:replace_named_bind_variables, statement, vars.first)
1094
- else
1095
- ActiveRecord::Base.send(:replace_bind_variables, statement, vars)
1096
- end
1097
- end
1098
- end