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
data/CHANGELOG CHANGED
@@ -1,35 +1,115 @@
1
- *2.3.11 (February 9, 2011)*
1
+ *Edge*
2
2
 
3
- *2.3.10 (October 15, 2010)*
3
+ * PostgreSQLAdapter: set time_zone to UTC when Base.default_timezone == :utc so that Postgres doesn't incorrectly offset-adjust values inserted into TIMESTAMP WITH TIME ZONE columns. #3777 [Jack Christensen]
4
4
 
5
- * Security Release to fix CVE-2010-3933
5
+ * Allow relations to be used as scope.
6
6
 
7
- *2.3.9 (September 4, 2010)*
8
- *2.3.8 (May 24, 2010)*
9
- *2.3.7 (May 24, 2010)*
7
+ class Item
8
+ scope :red, where(:colour => 'red')
9
+ end
10
10
 
11
- * Version bump.
11
+ Item.red.limit(10) # Ten red items
12
12
 
13
+ * Rename named_scope to scope. [Pratik Naik]
13
14
 
14
- *2.3.6 (May 23, 2010)*
15
+ * Changed ActiveRecord::Base.store_full_sti_class to be true by default reflecting the previously announced Rails 3 default [DHH]
15
16
 
16
- * Add index length support for MySQL. #1852 [Emili Parreno, Pratik Naik]
17
+ * Add Relation#except. [Pratik Naik]
17
18
 
18
- Example:
19
+ one_red_item = Item.where(:colour => 'red').limit(1)
20
+ all_items = one_red_item.except(:where, :limit)
21
+
22
+ * Add Relation#delete_all. [Pratik Naik]
23
+
24
+ Item.where(:colour => 'red').delete_all
25
+
26
+ * Add Model.having and Relation#having. [Pratik Naik]
27
+
28
+ Developer.group("salary").having("sum(salary) > 10000").select("salary")
29
+
30
+ * Add Relation#count. [Pratik Naik]
31
+
32
+ legends = People.where("age > 100")
33
+ legends.count
34
+ legends.count(:age, :distinct => true)
35
+ legends.select('id').count
36
+
37
+ * Add Model.readonly and association_collection#readonly finder method. [Pratik Naik]
38
+
39
+ Post.readonly.to_a # Load all posts in readonly mode
40
+ @user.items.readonly(false).to_a # Load all the user items in writable mode
41
+
42
+ * Add .lock finder method [Pratik Naik]
43
+
44
+ User.lock.where(:name => 'lifo').to_a
45
+
46
+ old_items = Item.where("age > 100")
47
+ old_items.lock.each {|i| .. }
48
+
49
+ * Add Model.from and association_collection#from finder methods [Pratik Naik]
50
+
51
+ user = User.scoped
52
+ user.select('*').from('users, items')
53
+
54
+ * Add relation.destroy_all [Pratik Naik]
55
+
56
+ old_items = Item.where("age > 100")
57
+ old_items.destroy_all
58
+
59
+ * Add relation.exists? [Pratik Naik]
60
+
61
+ red_items = Item.where(:colours => 'red')
62
+ red_items.exists?
63
+ red_items.exists?(1)
19
64
 
20
- add_index(:accounts, :name, :name => 'by_name', :length => 10)
21
- => CREATE INDEX by_name ON accounts(name(10))
65
+ * Add find(ids) to relations. [Pratik Naik]
22
66
 
23
- add_index(:accounts, [:name, :surname], :name => 'by_name_surname', :length => {:name => 10, :surname => 15})
24
- => CREATE INDEX by_name_surname ON accounts(name(10), surname(15))
67
+ old_users = User.order("age DESC")
68
+ old_users.find(1)
69
+ old_users.find(1, 2, 3)
25
70
 
26
- * find_or_create_by_attr(value, ...) works when attr is protected. #4457 [Santiago Pastorino, Marc-André Lafortune]
71
+ * Add new finder methods to association collection. [Pratik Naik]
27
72
 
28
- * JSON supports a custom root option: to_json(:root => 'custom') #4515 [Jatinder Singh]
73
+ class User < ActiveRecord::Base
74
+ has_many :items
75
+ end
76
+
77
+ user = User.first
78
+ user.items.where(:items => {:colour => 'red'})
79
+ user.items.select('items.id')
80
+
81
+ * Add relation.reload to force reloading the records. [Pratik Naik]
82
+
83
+ topics = Topic.scoped
84
+ topics.to_a # force load
85
+ topics.first # returns a cached record
86
+ topics.reload
87
+ topics.first # Fetches a new record from the database
88
+
89
+ * Rename Model.conditions and relation.conditions to .where. [Pratik Naik]
90
+
91
+ Before :
92
+ User.conditions(:name => 'lifo')
93
+ User.select('id').conditions(["age > ?", 21])
94
+
95
+ Now :
96
+ User.where(:name => 'lifo')
97
+ User.select('id').where(["age > ?", 21])
98
+
99
+ * Add Model.select/group/order/limit/joins/conditions/preload/eager_load class methods returning a lazy relation. [Pratik Naik]
100
+
101
+ Examples :
102
+
103
+ posts = Post.select('id).order('name') # Returns a lazy relation
104
+ posts.each {|p| puts p.id } # Fires "select id from posts order by name"
29
105
 
30
- * Destroy uses optimistic locking. If lock_version on the record you're destroying doesn't match lock_version in the database, a StaleObjectError is raised. #1966 [Curtis Hawthorne]
106
+ * Model.scoped now returns a relation if invoked without any arguments. [Pratik Naik]
31
107
 
32
- * To prefix the table names of all models in a module, define self.table_name_prefix on the module. #4032 [Andrew White]
108
+ Example :
109
+
110
+ posts = Post.scoped
111
+ posts.size # Fires "select count(*) from posts" and returns the count
112
+ posts.each {|p| puts p.name } # Fires "select * from posts" and loads post objects
33
113
 
34
114
  * Association inverses for belongs_to, has_one, and has_many. Optimization to reduce database queries. #3533 [Murray Steele]
35
115
 
@@ -42,29 +122,20 @@
42
122
 
43
123
  * Reset your Active Record counter caches with the reset_counter_cache class method. #1211 [Mike Breen, Gabe da Silveira]
44
124
 
45
-
46
- *2.3.5 (November 25, 2009)*
47
-
48
- * Minor Bug Fixes and deprecation warnings
49
-
50
- * 1.9 Compatibility
51
-
52
- * Numerous fixes to the nested attributes functionality
53
-
54
-
55
- *2.3.4 (September 4, 2009)*
125
+ * Remove support for SQLite 2. Please upgrade to SQLite 3+ or install the plugin from git://github.com/rails/sqlite2_adapter.git [Pratik Naik]
56
126
 
57
127
  * PostgreSQL: XML datatype support. #1874 [Leonardo Borges]
58
128
 
59
- * SQLite: deprecate the 'dbfile' option in favor of 'database.' #2363 [Paul Hinze, Jeremy Kemper]
129
+ * quoted_date converts time-like objects to ActiveRecord::Base.default_timezone before serialization. This allows you to use Time.now in find conditions and have it correctly be serialized as the current time in UTC when default_timezone == :utc. #2946 [Geoff Buesing]
60
130
 
61
-
62
- *2.3.3 (July 12, 2009)*
131
+ * SQLite: drop support for 'dbfile' option in favor of 'database.' #2363 [Paul Hinze, Jeremy Kemper]
63
132
 
64
133
  * Added :primary_key option to belongs_to associations. #765 [Szymon Nowak, Philip Hallstrom, Noel Rocha]
65
134
  # employees.company_name references companies.name
66
135
  Employee.belongs_to :company, :primary_key => 'name', :foreign_key => 'company_name'
67
136
 
137
+ * Implement #many? for NamedScope and AssociationCollection using #size. #1500 [Chris Kampmeier]
138
+
68
139
  * Added :touch option to belongs_to associations that will touch the parent record when the current record is saved or destroyed [DHH]
69
140
 
70
141
  * Added ActiveRecord::Base#touch to update the updated_at/on attributes (or another specified timestamp) with the current time [DHH]
@@ -2252,7 +2323,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing]
2252
2323
 
2253
2324
  * Escape database name in MySQL adapter when creating and dropping databases. #3409 [anna@wota.jp]
2254
2325
 
2255
- * Disambiguate table names for columns in validates_uniquness_of's WHERE clause. #3423 [alex.borovsky@gmail.com]
2326
+ * Disambiguate table names for columns in validates_uniqueness_of's WHERE clause. #3423 [alex.borovsky@gmail.com]
2256
2327
 
2257
2328
  * .with_scope imposed create parameters now bypass attr_protected [Tobias Lütke]
2258
2329
 
@@ -3767,7 +3838,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio
3767
3838
 
3768
3839
  * Escape database name in MySQL adapter when creating and dropping databases. #3409 [anna@wota.jp]
3769
3840
 
3770
- * Disambiguate table names for columns in validates_uniquness_of's WHERE clause. #3423 [alex.borovsky@gmail.com]
3841
+ * Disambiguate table names for columns in validates_uniqueness_of's WHERE clause. #3423 [alex.borovsky@gmail.com]
3771
3842
 
3772
3843
  * .with_scope imposed create parameters now bypass attr_protected [Tobias Lütke]
3773
3844
 
@@ -12,8 +12,6 @@ require 'rbench'
12
12
 
13
13
  __DIR__ = File.dirname(__FILE__)
14
14
  $:.unshift "#{__DIR__}/../lib"
15
- $:.unshift "#{__DIR__}/../../activesupport/lib"
16
-
17
15
  require 'active_record'
18
16
 
19
17
  conn = { :adapter => 'mysql',
@@ -27,7 +25,7 @@ conn[:socket] = Pathname.glob(%w[
27
25
  /tmp/mysql.sock
28
26
  /var/mysql/mysql.sock
29
27
  /var/run/mysqld/mysqld.sock
30
- ]).find { |path| path.socket? }.to_s
28
+ ]).find { |path| path.socket? }
31
29
 
32
30
  ActiveRecord::Base.establish_connection(conn)
33
31
 
@@ -60,7 +58,7 @@ end
60
58
  sqlfile = "#{__DIR__}/performance.sql"
61
59
 
62
60
  if File.exists?(sqlfile)
63
- mysql_bin = %w[mysql mysql5].detect { |bin| `which #{bin}`.length > 0 }
61
+ mysql_bin = %w[mysql mysql5].select { |bin| `which #{bin}`.length > 0 }
64
62
  `#{mysql_bin} -u #{conn[:username]} #{"-p#{conn[:password]}" unless conn[:password].blank?} #{conn[:database]} < #{sqlfile}`
65
63
  else
66
64
  puts 'Generating data...'
@@ -90,7 +88,7 @@ else
90
88
  )
91
89
  end
92
90
 
93
- mysqldump_bin = %w[mysqldump mysqldump5].detect { |bin| `which #{bin}`.length > 0 }
91
+ mysqldump_bin = %w[mysqldump mysqldump5].select { |bin| `which #{bin}`.length > 0 }
94
92
  `#{mysqldump_bin} -u #{conn[:username]} #{"-p#{conn[:password]}" unless conn[:password].blank?} #{conn[:database]} exhibits users > #{sqlfile}`
95
93
  end
96
94
 
@@ -157,40 +155,6 @@ RBench.run(TIMES) do
157
155
  ar { Exhibit.transaction { Exhibit.new } }
158
156
  end
159
157
 
160
- report 'Model.find(id)' do
161
- id = Exhibit.first.id
162
- ar { Exhibit.find(id) }
163
- end
164
-
165
- report 'Model.find_by_sql' do
166
- ar { Exhibit.find_by_sql("SELECT * FROM exhibits WHERE id = #{(rand * 1000 + 1).to_i}").first }
167
- end
168
-
169
- report 'Model.log', (TIMES * 10) do
170
- ar { Exhibit.connection.send(:log, "hello", "world") {} }
171
- end
172
-
173
- report 'AR.execute(query)', (TIMES / 2) do
174
- ar { ActiveRecord::Base.connection.execute("Select * from exhibits where id = #{(rand * 1000 + 1).to_i}") }
175
- end
176
-
177
- report 'Model.find(id)' do
178
- id = Exhibit.first.id
179
- ar { Exhibit.find(id) }
180
- end
181
-
182
- report 'Model.find_by_sql' do
183
- ar { Exhibit.find_by_sql("SELECT * FROM exhibits WHERE id = #{(rand * 1000 + 1).to_i}").first }
184
- end
185
-
186
- report 'Model.log', (TIMES * 10) do
187
- ar { Exhibit.connection.send(:log, "hello", "world") {} }
188
- end
189
-
190
- report 'AR.execute(query)', (TIMES / 2) do
191
- ar { ActiveRecord::Base.connection.execute("Select * from exhibits where id = #{(rand * 1000 + 1).to_i}") }
192
- end
193
-
194
158
  summary 'Total'
195
159
  end
196
160
 
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
2
+ require 'active_record'
3
+
4
+ class Person < ActiveRecord::Base
5
+ establish_connection :adapter => 'sqlite3', :database => 'foobar.db'
6
+ connection.create_table table_name, :force => true do |t|
7
+ t.string :name
8
+ end
9
+ end
10
+
11
+ bob = Person.create!(:name => 'bob')
12
+ puts Person.all.inspect
13
+ bob.destroy
14
+ puts Person.all.inspect
@@ -21,63 +21,97 @@
21
21
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  #++
23
23
 
24
- begin
25
- require 'active_support'
26
- rescue LoadError
27
- activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
28
- if File.directory?(activesupport_path)
29
- $:.unshift activesupport_path
30
- require 'active_support'
31
- end
32
- end
24
+
25
+ activesupport_path = File.expand_path('../../../activesupport/lib', __FILE__)
26
+ $:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path)
27
+
28
+ activemodel_path = File.expand_path('../../../activemodel/lib', __FILE__)
29
+ $:.unshift(activemodel_path) if File.directory?(activemodel_path) && !$:.include?(activemodel_path)
30
+
31
+ require 'active_support'
32
+ require 'active_model'
33
+ require 'arel'
33
34
 
34
35
  module ActiveRecord
35
- # TODO: Review explicit loads to see if they will automatically be handled by the initilizer.
36
- def self.load_all!
37
- [Base, DynamicFinderMatch, ConnectionAdapters::AbstractAdapter]
36
+ extend ActiveSupport::Autoload
37
+
38
+ eager_autoload do
39
+ autoload :VERSION
40
+
41
+ autoload :ActiveRecordError, 'active_record/base'
42
+ autoload :ConnectionNotEstablished, 'active_record/base'
43
+
44
+ autoload :Aggregations
45
+ autoload :AssociationPreload
46
+ autoload :Associations
47
+ autoload :AttributeMethods
48
+ autoload :AutosaveAssociation
49
+
50
+ autoload :Relation
51
+
52
+ autoload_under 'relation' do
53
+ autoload :QueryMethods
54
+ autoload :FinderMethods
55
+ autoload :Calculations
56
+ autoload :PredicateBuilder
57
+ autoload :SpawnMethods
58
+ end
59
+
60
+ autoload :Base
61
+ autoload :Batches
62
+ autoload :Callbacks
63
+ autoload :DynamicFinderMatch
64
+ autoload :DynamicScopeMatch
65
+ autoload :Migration
66
+ autoload :Migrator, 'active_record/migration'
67
+ autoload :NamedScope
68
+ autoload :NestedAttributes
69
+ autoload :Observer
70
+ autoload :QueryCache
71
+ autoload :Reflection
72
+ autoload :Schema
73
+ autoload :SchemaDumper
74
+ autoload :Serialization
75
+ autoload :SessionStore
76
+ autoload :Timestamp
77
+ autoload :Transactions
78
+ autoload :Validations
38
79
  end
39
80
 
40
- autoload :VERSION, 'active_record/version'
41
-
42
- autoload :ActiveRecordError, 'active_record/base'
43
- autoload :ConnectionNotEstablished, 'active_record/base'
44
-
45
- autoload :Aggregations, 'active_record/aggregations'
46
- autoload :AssociationPreload, 'active_record/association_preload'
47
- autoload :Associations, 'active_record/associations'
48
- autoload :AttributeMethods, 'active_record/attribute_methods'
49
- autoload :AutosaveAssociation, 'active_record/autosave_association'
50
- autoload :Base, 'active_record/base'
51
- autoload :Batches, 'active_record/batches'
52
- autoload :Calculations, 'active_record/calculations'
53
- autoload :Callbacks, 'active_record/callbacks'
54
- autoload :Dirty, 'active_record/dirty'
55
- autoload :DynamicFinderMatch, 'active_record/dynamic_finder_match'
56
- autoload :DynamicScopeMatch, 'active_record/dynamic_scope_match'
57
- autoload :Migration, 'active_record/migration'
58
- autoload :Migrator, 'active_record/migration'
59
- autoload :NamedScope, 'active_record/named_scope'
60
- autoload :NestedAttributes, 'active_record/nested_attributes'
61
- autoload :Observing, 'active_record/observer'
62
- autoload :QueryCache, 'active_record/query_cache'
63
- autoload :Reflection, 'active_record/reflection'
64
- autoload :Schema, 'active_record/schema'
65
- autoload :SchemaDumper, 'active_record/schema_dumper'
66
- autoload :Serialization, 'active_record/serialization'
67
- autoload :SessionStore, 'active_record/session_store'
68
- autoload :TestCase, 'active_record/test_case'
69
- autoload :Timestamp, 'active_record/timestamp'
70
- autoload :Transactions, 'active_record/transactions'
71
- autoload :Validations, 'active_record/validations'
81
+ module AttributeMethods
82
+ extend ActiveSupport::Autoload
83
+
84
+ eager_autoload do
85
+ autoload :BeforeTypeCast
86
+ autoload :Dirty
87
+ autoload :PrimaryKey
88
+ autoload :Query
89
+ autoload :Read
90
+ autoload :TimeZoneConversion
91
+ autoload :Write
92
+ end
93
+ end
72
94
 
73
95
  module Locking
74
- autoload :Optimistic, 'active_record/locking/optimistic'
75
- autoload :Pessimistic, 'active_record/locking/pessimistic'
96
+ extend ActiveSupport::Autoload
97
+
98
+ eager_autoload do
99
+ autoload :Optimistic
100
+ autoload :Pessimistic
101
+ end
76
102
  end
77
103
 
78
104
  module ConnectionAdapters
79
- autoload :AbstractAdapter, 'active_record/connection_adapters/abstract_adapter'
105
+ extend ActiveSupport::Autoload
106
+
107
+ eager_autoload do
108
+ autoload :AbstractAdapter
109
+ end
80
110
  end
111
+
112
+ autoload :TestCase
113
+ autoload :TestFixtures, 'active_record/fixtures'
81
114
  end
82
115
 
116
+ Arel::Table.engine = Arel::Sql::Engine.new(ActiveRecord::Base)
83
117
  I18n.load_path << File.dirname(__FILE__) + '/active_record/locale/en.yml'
@@ -1,8 +1,6 @@
1
1
  module ActiveRecord
2
2
  module Aggregations # :nodoc:
3
- def self.included(base)
4
- base.extend(ClassMethods)
5
- end
3
+ extend ActiveSupport::Concern
6
4
 
7
5
  def clear_aggregation_cache #:nodoc:
8
6
  self.class.reflect_on_all_aggregations.to_a.each do |assoc|
@@ -1,9 +1,10 @@
1
+ require 'active_support/core_ext/array/wrap'
2
+ require 'active_support/core_ext/enumerable'
3
+
1
4
  module ActiveRecord
2
5
  # See ActiveRecord::AssociationPreload::ClassMethods for documentation.
3
6
  module AssociationPreload #:nodoc:
4
- def self.included(base)
5
- base.extend(ClassMethods)
6
- end
7
+ extend ActiveSupport::Concern
7
8
 
8
9
  # Implements the details of eager loading of ActiveRecord associations.
9
10
  # Application developers should not use this module directly.
@@ -30,7 +31,7 @@ module ActiveRecord
30
31
  # 'books' table is useful; the joined 'authors' data is just redundant, and
31
32
  # processing this redundant data takes memory and CPU time. The problem
32
33
  # quickly becomes worse and worse as the level of eager loading increases
33
- # (i.e. if ActiveRecord is to eager load the associations' assocations as
34
+ # (i.e. if ActiveRecord is to eager load the associations' associations as
34
35
  # well).
35
36
  #
36
37
  # The second strategy is to use multiple database queries, one for each
@@ -60,7 +61,7 @@ module ActiveRecord
60
61
  # +associations+ specifies one or more associations that you want to
61
62
  # preload. It may be:
62
63
  # - a Symbol or a String which specifies a single association name. For
63
- # example, specifiying +:books+ allows this method to preload all books
64
+ # example, specifying +:books+ allows this method to preload all books
64
65
  # for an Author.
65
66
  # - an Array which specifies multiple association names. This array
66
67
  # is processed recursively. For example, specifying <tt>[:avatar, :books]</tt>
@@ -84,7 +85,7 @@ module ActiveRecord
84
85
  # only one level deep in the +associations+ argument, i.e. it's not passed
85
86
  # to the child associations when +associations+ is a Hash.
86
87
  def preload_associations(records, associations, preload_options={})
87
- records = [records].flatten.compact.uniq
88
+ records = Array.wrap(records).compact.uniq
88
89
  return if records.empty?
89
90
  case associations
90
91
  when Array then associations.each {|association| preload_associations(records, association, preload_options)}
@@ -94,7 +95,7 @@ module ActiveRecord
94
95
  raise "parent must be an association name" unless parent.is_a?(String) || parent.is_a?(Symbol)
95
96
  preload_associations(records, parent, preload_options)
96
97
  reflection = reflections[parent]
97
- parents = records.map {|record| record.send(reflection.name)}.flatten.compact
98
+ parents = records.sum { |record| Array.wrap(record.send(reflection.name)) }
98
99
  unless parents.empty?
99
100
  parents.first.class.preload_associations(parents, child)
100
101
  end
@@ -125,7 +126,8 @@ module ActiveRecord
125
126
  parent_records.each do |parent_record|
126
127
  association_proxy = parent_record.send(reflection_name)
127
128
  association_proxy.loaded
128
- association_proxy.target.push(*[associated_record].flatten)
129
+ association_proxy.target.push *Array.wrap(associated_record)
130
+
129
131
  association_proxy.__send__(:set_inverse_instance, associated_record, parent_record)
130
132
  end
131
133
  end
@@ -157,11 +159,6 @@ module ActiveRecord
157
159
  association_proxy.__send__(:set_inverse_instance, associated_record, mapped_record)
158
160
  end
159
161
  end
160
-
161
- id_to_record_map.each do |id, records|
162
- next if seen_keys.include?(id.to_s)
163
- records.each {|record| record.send("set_#{reflection_name}_target", nil) }
164
- end
165
162
  end
166
163
 
167
164
  # Given a collection of ActiveRecord objects, constructs a Hash which maps
@@ -190,13 +187,12 @@ module ActiveRecord
190
187
  conditions = "t0.#{reflection.primary_key_name} #{in_or_equals_for_ids(ids)}"
191
188
  conditions << append_conditions(reflection, preload_options)
192
189
 
193
- associated_records = reflection.klass.with_exclusive_scope do
194
- reflection.klass.find(:all, :conditions => [conditions, ids],
195
- :include => options[:include],
196
- :joins => "INNER JOIN #{connection.quote_table_name options[:join_table]} t0 ON #{reflection.klass.quoted_table_name}.#{reflection.klass.primary_key} = t0.#{reflection.association_foreign_key}",
197
- :select => "#{options[:select] || table_name+'.*'}, t0.#{reflection.primary_key_name} as the_parent_record_id",
198
- :order => options[:order])
199
- end
190
+ associated_records = reflection.klass.unscoped.where([conditions, ids]).
191
+ includes(options[:include]).
192
+ joins("INNER JOIN #{connection.quote_table_name options[:join_table]} t0 ON #{reflection.klass.quoted_table_name}.#{reflection.klass.primary_key} = t0.#{reflection.association_foreign_key}").
193
+ select("#{options[:select] || table_name+'.*'}, t0.#{reflection.primary_key_name} as the_parent_record_id").
194
+ order(options[:order]).to_a
195
+
200
196
  set_association_collection_records(id_to_record_map, reflection.name, associated_records, 'the_parent_record_id')
201
197
  end
202
198
 
@@ -261,6 +257,7 @@ module ActiveRecord
261
257
  through_reflection = reflections[through_association]
262
258
  through_primary_key = through_reflection.primary_key_name
263
259
 
260
+ through_records = []
264
261
  if reflection.options[:source_type]
265
262
  interface = reflection.source_reflection.options[:foreign_type]
266
263
  preload_options = {:conditions => ["#{connection.quote_column_name interface} = ?", reflection.options[:source_type]]}
@@ -269,27 +266,22 @@ module ActiveRecord
269
266
  records.first.class.preload_associations(records, through_association, preload_options)
270
267
 
271
268
  # Dont cache the association - we would only be caching a subset
272
- through_records = []
273
269
  records.each do |record|
274
270
  proxy = record.send(through_association)
275
271
 
276
272
  if proxy.respond_to?(:target)
277
- through_records << proxy.target
273
+ through_records.concat Array.wrap(proxy.target)
278
274
  proxy.reset
279
275
  else # this is a has_one :through reflection
280
276
  through_records << proxy if proxy
281
277
  end
282
278
  end
283
- through_records.flatten!
284
279
  else
285
- options = {}
286
- options[:include] = reflection.options[:include] || reflection.options[:source] if reflection.options[:conditions] || reflection.options[:order]
287
- options[:order] = reflection.options[:order]
288
- options[:conditions] = reflection.options[:conditions]
289
- records.first.class.preload_associations(records, through_association, options)
290
- through_records = records.map {|record| record.send(through_association)}.flatten
280
+ records.first.class.preload_associations(records, through_association)
281
+ records.each do |record|
282
+ through_records.concat Array.wrap(record.send(through_association))
283
+ end
291
284
  end
292
- through_records.compact!
293
285
  through_records
294
286
  end
295
287
 
@@ -332,8 +324,9 @@ module ActiveRecord
332
324
  klass = klass_name.constantize
333
325
 
334
326
  table_name = klass.quoted_table_name
335
- primary_key = reflection.options[:primary_key] || klass.primary_key
327
+ primary_key = klass.primary_key
336
328
  column_type = klass.columns.detect{|c| c.name == primary_key}.type
329
+
337
330
  ids = id_map.keys.map do |id|
338
331
  if column_type == :integer
339
332
  id.to_i
@@ -343,15 +336,12 @@ module ActiveRecord
343
336
  id
344
337
  end
345
338
  end
339
+
346
340
  conditions = "#{table_name}.#{connection.quote_column_name(primary_key)} #{in_or_equals_for_ids(ids)}"
347
341
  conditions << append_conditions(reflection, preload_options)
348
- associated_records = klass.with_exclusive_scope do
349
- klass.find(:all, :conditions => [conditions, ids],
350
- :include => options[:include],
351
- :select => options[:select],
352
- :joins => options[:joins],
353
- :order => options[:order])
354
- end
342
+
343
+ associated_records = klass.unscoped.where([conditions, ids]).apply_finder_options(options.slice(:include, :select, :joins, :order)).to_a
344
+
355
345
  set_association_single_records(id_map, reflection.name, associated_records, primary_key)
356
346
  end
357
347
  end
@@ -361,13 +351,7 @@ module ActiveRecord
361
351
  table_name = reflection.klass.quoted_table_name
362
352
 
363
353
  if interface = reflection.options[:as]
364
- parent_type = if reflection.active_record.abstract_class?
365
- self.base_class.sti_name
366
- else
367
- reflection.active_record.sti_name
368
- end
369
-
370
- conditions = "#{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_id"} #{in_or_equals_for_ids(ids)} and #{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_type"} = '#{parent_type}'"
354
+ conditions = "#{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_id"} #{in_or_equals_for_ids(ids)} and #{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_type"} = '#{self.base_class.sti_name}'"
371
355
  else
372
356
  foreign_key = reflection.primary_key_name
373
357
  conditions = "#{reflection.klass.quoted_table_name}.#{foreign_key} #{in_or_equals_for_ids(ids)}"
@@ -375,15 +359,16 @@ module ActiveRecord
375
359
 
376
360
  conditions << append_conditions(reflection, preload_options)
377
361
 
378
- reflection.klass.with_exclusive_scope do
379
- reflection.klass.find(:all,
380
- :select => (preload_options[:select] || options[:select] || "#{table_name}.*"),
381
- :include => preload_options[:include] || options[:include],
382
- :conditions => [conditions, ids],
383
- :joins => options[:joins],
384
- :group => preload_options[:group] || options[:group],
385
- :order => preload_options[:order] || options[:order])
386
- end
362
+ find_options = {
363
+ :select => preload_options[:select] || options[:select] || "#{table_name}.*",
364
+ :include => preload_options[:include] || options[:include],
365
+ :conditions => [conditions, ids],
366
+ :joins => options[:joins],
367
+ :group => preload_options[:group] || options[:group],
368
+ :order => preload_options[:order] || options[:order]
369
+ }
370
+
371
+ reflection.klass.unscoped.apply_finder_options(find_options).to_a
387
372
  end
388
373
 
389
374