activerecord 2.3.18 → 3.2.22

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 (454) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1014 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +222 -0
  5. data/examples/performance.rb +100 -126
  6. data/examples/simple.rb +14 -0
  7. data/lib/active_record/aggregations.rb +93 -99
  8. data/lib/active_record/associations/alias_tracker.rb +76 -0
  9. data/lib/active_record/associations/association.rb +247 -0
  10. data/lib/active_record/associations/association_scope.rb +134 -0
  11. data/lib/active_record/associations/belongs_to_association.rb +54 -61
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +17 -59
  13. data/lib/active_record/associations/builder/association.rb +55 -0
  14. data/lib/active_record/associations/builder/belongs_to.rb +88 -0
  15. data/lib/active_record/associations/builder/collection_association.rb +75 -0
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +57 -0
  17. data/lib/active_record/associations/builder/has_many.rb +71 -0
  18. data/lib/active_record/associations/builder/has_one.rb +62 -0
  19. data/lib/active_record/associations/builder/singular_association.rb +32 -0
  20. data/lib/active_record/associations/collection_association.rb +580 -0
  21. data/lib/active_record/associations/collection_proxy.rb +133 -0
  22. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +39 -119
  23. data/lib/active_record/associations/has_many_association.rb +60 -79
  24. data/lib/active_record/associations/has_many_through_association.rb +127 -206
  25. data/lib/active_record/associations/has_one_association.rb +55 -114
  26. data/lib/active_record/associations/has_one_through_association.rb +25 -26
  27. data/lib/active_record/associations/join_dependency/join_association.rb +159 -0
  28. data/lib/active_record/associations/join_dependency/join_base.rb +24 -0
  29. data/lib/active_record/associations/join_dependency/join_part.rb +78 -0
  30. data/lib/active_record/associations/join_dependency.rb +214 -0
  31. data/lib/active_record/associations/join_helper.rb +55 -0
  32. data/lib/active_record/associations/preloader/association.rb +125 -0
  33. data/lib/active_record/associations/preloader/belongs_to.rb +17 -0
  34. data/lib/active_record/associations/preloader/collection_association.rb +24 -0
  35. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +60 -0
  36. data/lib/active_record/associations/preloader/has_many.rb +17 -0
  37. data/lib/active_record/associations/preloader/has_many_through.rb +15 -0
  38. data/lib/active_record/associations/preloader/has_one.rb +23 -0
  39. data/lib/active_record/associations/preloader/has_one_through.rb +9 -0
  40. data/lib/active_record/associations/preloader/singular_association.rb +21 -0
  41. data/lib/active_record/associations/preloader/through_association.rb +67 -0
  42. data/lib/active_record/associations/preloader.rb +181 -0
  43. data/lib/active_record/associations/singular_association.rb +64 -0
  44. data/lib/active_record/associations/through_association.rb +87 -0
  45. data/lib/active_record/associations.rb +693 -1337
  46. data/lib/active_record/attribute_assignment.rb +221 -0
  47. data/lib/active_record/attribute_methods/before_type_cast.rb +31 -0
  48. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +32 -0
  49. data/lib/active_record/attribute_methods/dirty.rb +111 -0
  50. data/lib/active_record/attribute_methods/primary_key.rb +114 -0
  51. data/lib/active_record/attribute_methods/query.rb +39 -0
  52. data/lib/active_record/attribute_methods/read.rb +136 -0
  53. data/lib/active_record/attribute_methods/serialization.rb +120 -0
  54. data/lib/active_record/attribute_methods/time_zone_conversion.rb +65 -0
  55. data/lib/active_record/attribute_methods/write.rb +70 -0
  56. data/lib/active_record/attribute_methods.rb +211 -339
  57. data/lib/active_record/autosave_association.rb +179 -149
  58. data/lib/active_record/base.rb +401 -2907
  59. data/lib/active_record/callbacks.rb +91 -176
  60. data/lib/active_record/coders/yaml_column.rb +41 -0
  61. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +236 -119
  62. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +110 -58
  63. data/lib/active_record/connection_adapters/abstract/database_limits.rb +12 -11
  64. data/lib/active_record/connection_adapters/abstract/database_statements.rb +175 -74
  65. data/lib/active_record/connection_adapters/abstract/query_cache.rb +31 -35
  66. data/lib/active_record/connection_adapters/abstract/quoting.rb +71 -21
  67. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +81 -311
  68. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +194 -78
  69. data/lib/active_record/connection_adapters/abstract_adapter.rb +130 -83
  70. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +676 -0
  71. data/lib/active_record/connection_adapters/column.rb +296 -0
  72. data/lib/active_record/connection_adapters/mysql2_adapter.rb +280 -0
  73. data/lib/active_record/connection_adapters/mysql_adapter.rb +272 -493
  74. data/lib/active_record/connection_adapters/postgresql_adapter.rb +650 -405
  75. data/lib/active_record/connection_adapters/schema_cache.rb +69 -0
  76. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +30 -9
  77. data/lib/active_record/connection_adapters/sqlite_adapter.rb +276 -147
  78. data/lib/active_record/connection_adapters/statement_pool.rb +40 -0
  79. data/lib/active_record/counter_cache.rb +123 -0
  80. data/lib/active_record/dynamic_finder_match.rb +41 -14
  81. data/lib/active_record/dynamic_matchers.rb +84 -0
  82. data/lib/active_record/dynamic_scope_match.rb +13 -15
  83. data/lib/active_record/errors.rb +195 -0
  84. data/lib/active_record/explain.rb +86 -0
  85. data/lib/active_record/explain_subscriber.rb +25 -0
  86. data/lib/active_record/fixtures/file.rb +65 -0
  87. data/lib/active_record/fixtures.rb +695 -770
  88. data/lib/active_record/identity_map.rb +162 -0
  89. data/lib/active_record/inheritance.rb +174 -0
  90. data/lib/active_record/integration.rb +60 -0
  91. data/lib/active_record/locale/en.yml +9 -27
  92. data/lib/active_record/locking/optimistic.rb +76 -73
  93. data/lib/active_record/locking/pessimistic.rb +32 -10
  94. data/lib/active_record/log_subscriber.rb +72 -0
  95. data/lib/active_record/migration/command_recorder.rb +105 -0
  96. data/lib/active_record/migration.rb +415 -205
  97. data/lib/active_record/model_schema.rb +368 -0
  98. data/lib/active_record/nested_attributes.rb +153 -63
  99. data/lib/active_record/observer.rb +27 -103
  100. data/lib/active_record/persistence.rb +376 -0
  101. data/lib/active_record/query_cache.rb +49 -8
  102. data/lib/active_record/querying.rb +58 -0
  103. data/lib/active_record/railtie.rb +131 -0
  104. data/lib/active_record/railties/console_sandbox.rb +6 -0
  105. data/lib/active_record/railties/controller_runtime.rb +49 -0
  106. data/lib/active_record/railties/databases.rake +659 -0
  107. data/lib/active_record/railties/jdbcmysql_error.rb +16 -0
  108. data/lib/active_record/readonly_attributes.rb +26 -0
  109. data/lib/active_record/reflection.rb +269 -120
  110. data/lib/active_record/relation/batches.rb +90 -0
  111. data/lib/active_record/relation/calculations.rb +372 -0
  112. data/lib/active_record/relation/delegation.rb +49 -0
  113. data/lib/active_record/relation/finder_methods.rb +402 -0
  114. data/lib/active_record/relation/predicate_builder.rb +63 -0
  115. data/lib/active_record/relation/query_methods.rb +417 -0
  116. data/lib/active_record/relation/spawn_methods.rb +180 -0
  117. data/lib/active_record/relation.rb +537 -0
  118. data/lib/active_record/result.rb +40 -0
  119. data/lib/active_record/sanitization.rb +194 -0
  120. data/lib/active_record/schema.rb +9 -6
  121. data/lib/active_record/schema_dumper.rb +55 -32
  122. data/lib/active_record/scoping/default.rb +142 -0
  123. data/lib/active_record/scoping/named.rb +200 -0
  124. data/lib/active_record/scoping.rb +152 -0
  125. data/lib/active_record/serialization.rb +8 -91
  126. data/lib/active_record/serializers/xml_serializer.rb +43 -197
  127. data/lib/active_record/session_store.rb +129 -103
  128. data/lib/active_record/store.rb +52 -0
  129. data/lib/active_record/test_case.rb +30 -23
  130. data/lib/active_record/timestamp.rb +95 -52
  131. data/lib/active_record/transactions.rb +212 -66
  132. data/lib/active_record/translation.rb +22 -0
  133. data/lib/active_record/validations/associated.rb +43 -0
  134. data/lib/active_record/validations/uniqueness.rb +180 -0
  135. data/lib/active_record/validations.rb +43 -1106
  136. data/lib/active_record/version.rb +5 -4
  137. data/lib/active_record.rb +121 -48
  138. data/lib/rails/generators/active_record/migration/migration_generator.rb +25 -0
  139. data/lib/rails/generators/active_record/migration/templates/migration.rb +34 -0
  140. data/lib/rails/generators/active_record/migration.rb +15 -0
  141. data/lib/rails/generators/active_record/model/model_generator.rb +47 -0
  142. data/lib/rails/generators/active_record/model/templates/migration.rb +15 -0
  143. data/lib/rails/generators/active_record/model/templates/model.rb +12 -0
  144. data/lib/rails/generators/active_record/model/templates/module.rb +7 -0
  145. data/lib/rails/generators/active_record/observer/observer_generator.rb +15 -0
  146. data/lib/rails/generators/active_record/observer/templates/observer.rb +4 -0
  147. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +25 -0
  148. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +12 -0
  149. data/lib/rails/generators/active_record.rb +25 -0
  150. metadata +187 -363
  151. data/CHANGELOG +0 -5904
  152. data/README +0 -351
  153. data/RUNNING_UNIT_TESTS +0 -36
  154. data/Rakefile +0 -268
  155. data/install.rb +0 -30
  156. data/lib/active_record/association_preload.rb +0 -406
  157. data/lib/active_record/associations/association_collection.rb +0 -533
  158. data/lib/active_record/associations/association_proxy.rb +0 -288
  159. data/lib/active_record/batches.rb +0 -85
  160. data/lib/active_record/calculations.rb +0 -321
  161. data/lib/active_record/dirty.rb +0 -183
  162. data/lib/active_record/named_scope.rb +0 -197
  163. data/lib/active_record/serializers/json_serializer.rb +0 -91
  164. data/lib/activerecord.rb +0 -2
  165. data/test/assets/example.log +0 -1
  166. data/test/assets/flowers.jpg +0 -0
  167. data/test/cases/aaa_create_tables_test.rb +0 -24
  168. data/test/cases/active_schema_test_mysql.rb +0 -122
  169. data/test/cases/active_schema_test_postgresql.rb +0 -24
  170. data/test/cases/adapter_test.rb +0 -144
  171. data/test/cases/aggregations_test.rb +0 -167
  172. data/test/cases/ar_schema_test.rb +0 -32
  173. data/test/cases/associations/belongs_to_associations_test.rb +0 -438
  174. data/test/cases/associations/callbacks_test.rb +0 -161
  175. data/test/cases/associations/cascaded_eager_loading_test.rb +0 -131
  176. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +0 -36
  177. data/test/cases/associations/eager_load_nested_include_test.rb +0 -131
  178. data/test/cases/associations/eager_load_nested_polymorphic_include.rb +0 -19
  179. data/test/cases/associations/eager_singularization_test.rb +0 -145
  180. data/test/cases/associations/eager_test.rb +0 -852
  181. data/test/cases/associations/extension_test.rb +0 -62
  182. data/test/cases/associations/habtm_join_table_test.rb +0 -56
  183. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +0 -827
  184. data/test/cases/associations/has_many_associations_test.rb +0 -1273
  185. data/test/cases/associations/has_many_through_associations_test.rb +0 -360
  186. data/test/cases/associations/has_one_associations_test.rb +0 -330
  187. data/test/cases/associations/has_one_through_associations_test.rb +0 -209
  188. data/test/cases/associations/inner_join_association_test.rb +0 -93
  189. data/test/cases/associations/inverse_associations_test.rb +0 -566
  190. data/test/cases/associations/join_model_test.rb +0 -712
  191. data/test/cases/associations_test.rb +0 -282
  192. data/test/cases/attribute_methods_test.rb +0 -305
  193. data/test/cases/autosave_association_test.rb +0 -1218
  194. data/test/cases/base_test.rb +0 -2166
  195. data/test/cases/batches_test.rb +0 -81
  196. data/test/cases/binary_test.rb +0 -30
  197. data/test/cases/calculations_test.rb +0 -360
  198. data/test/cases/callbacks_observers_test.rb +0 -38
  199. data/test/cases/callbacks_test.rb +0 -438
  200. data/test/cases/class_inheritable_attributes_test.rb +0 -32
  201. data/test/cases/column_alias_test.rb +0 -17
  202. data/test/cases/column_definition_test.rb +0 -70
  203. data/test/cases/connection_pool_test.rb +0 -25
  204. data/test/cases/connection_test_firebird.rb +0 -8
  205. data/test/cases/connection_test_mysql.rb +0 -65
  206. data/test/cases/copy_table_test_sqlite.rb +0 -80
  207. data/test/cases/counter_cache_test.rb +0 -84
  208. data/test/cases/database_statements_test.rb +0 -12
  209. data/test/cases/datatype_test_postgresql.rb +0 -204
  210. data/test/cases/date_time_test.rb +0 -37
  211. data/test/cases/default_test_firebird.rb +0 -16
  212. data/test/cases/defaults_test.rb +0 -111
  213. data/test/cases/deprecated_finder_test.rb +0 -30
  214. data/test/cases/dirty_test.rb +0 -316
  215. data/test/cases/finder_respond_to_test.rb +0 -76
  216. data/test/cases/finder_test.rb +0 -1098
  217. data/test/cases/fixtures_test.rb +0 -661
  218. data/test/cases/helper.rb +0 -68
  219. data/test/cases/i18n_test.rb +0 -46
  220. data/test/cases/inheritance_test.rb +0 -262
  221. data/test/cases/invalid_date_test.rb +0 -24
  222. data/test/cases/json_serialization_test.rb +0 -219
  223. data/test/cases/lifecycle_test.rb +0 -193
  224. data/test/cases/locking_test.rb +0 -350
  225. data/test/cases/method_scoping_test.rb +0 -704
  226. data/test/cases/migration_test.rb +0 -1649
  227. data/test/cases/migration_test_firebird.rb +0 -124
  228. data/test/cases/mixin_test.rb +0 -96
  229. data/test/cases/modules_test.rb +0 -109
  230. data/test/cases/multiple_db_test.rb +0 -85
  231. data/test/cases/named_scope_test.rb +0 -372
  232. data/test/cases/nested_attributes_test.rb +0 -840
  233. data/test/cases/pk_test.rb +0 -119
  234. data/test/cases/pooled_connections_test.rb +0 -103
  235. data/test/cases/query_cache_test.rb +0 -129
  236. data/test/cases/readonly_test.rb +0 -107
  237. data/test/cases/reflection_test.rb +0 -234
  238. data/test/cases/reload_models_test.rb +0 -22
  239. data/test/cases/repair_helper.rb +0 -50
  240. data/test/cases/reserved_word_test_mysql.rb +0 -176
  241. data/test/cases/sanitize_test.rb +0 -25
  242. data/test/cases/schema_authorization_test_postgresql.rb +0 -75
  243. data/test/cases/schema_dumper_test.rb +0 -211
  244. data/test/cases/schema_test_postgresql.rb +0 -178
  245. data/test/cases/serialization_test.rb +0 -47
  246. data/test/cases/sp_test_mysql.rb +0 -16
  247. data/test/cases/synonym_test_oracle.rb +0 -17
  248. data/test/cases/timestamp_test.rb +0 -75
  249. data/test/cases/transactions_test.rb +0 -543
  250. data/test/cases/unconnected_test.rb +0 -32
  251. data/test/cases/validations_i18n_test.rb +0 -925
  252. data/test/cases/validations_test.rb +0 -1684
  253. data/test/cases/xml_serialization_test.rb +0 -240
  254. data/test/cases/yaml_serialization_test.rb +0 -11
  255. data/test/config.rb +0 -5
  256. data/test/connections/jdbc_jdbcderby/connection.rb +0 -18
  257. data/test/connections/jdbc_jdbch2/connection.rb +0 -18
  258. data/test/connections/jdbc_jdbchsqldb/connection.rb +0 -18
  259. data/test/connections/jdbc_jdbcmysql/connection.rb +0 -26
  260. data/test/connections/jdbc_jdbcpostgresql/connection.rb +0 -26
  261. data/test/connections/jdbc_jdbcsqlite3/connection.rb +0 -25
  262. data/test/connections/native_db2/connection.rb +0 -25
  263. data/test/connections/native_firebird/connection.rb +0 -26
  264. data/test/connections/native_frontbase/connection.rb +0 -27
  265. data/test/connections/native_mysql/connection.rb +0 -25
  266. data/test/connections/native_openbase/connection.rb +0 -21
  267. data/test/connections/native_oracle/connection.rb +0 -27
  268. data/test/connections/native_postgresql/connection.rb +0 -21
  269. data/test/connections/native_sqlite/connection.rb +0 -25
  270. data/test/connections/native_sqlite3/connection.rb +0 -25
  271. data/test/connections/native_sqlite3/in_memory_connection.rb +0 -18
  272. data/test/connections/native_sybase/connection.rb +0 -23
  273. data/test/fixtures/accounts.yml +0 -29
  274. data/test/fixtures/all/developers.yml +0 -0
  275. data/test/fixtures/all/people.csv +0 -0
  276. data/test/fixtures/all/tasks.yml +0 -0
  277. data/test/fixtures/author_addresses.yml +0 -5
  278. data/test/fixtures/author_favorites.yml +0 -4
  279. data/test/fixtures/authors.yml +0 -9
  280. data/test/fixtures/binaries.yml +0 -132
  281. data/test/fixtures/books.yml +0 -7
  282. data/test/fixtures/categories/special_categories.yml +0 -9
  283. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +0 -4
  284. data/test/fixtures/categories.yml +0 -14
  285. data/test/fixtures/categories_ordered.yml +0 -7
  286. data/test/fixtures/categories_posts.yml +0 -23
  287. data/test/fixtures/categorizations.yml +0 -17
  288. data/test/fixtures/clubs.yml +0 -6
  289. data/test/fixtures/comments.yml +0 -59
  290. data/test/fixtures/companies.yml +0 -56
  291. data/test/fixtures/computers.yml +0 -4
  292. data/test/fixtures/courses.yml +0 -7
  293. data/test/fixtures/customers.yml +0 -26
  294. data/test/fixtures/developers.yml +0 -21
  295. data/test/fixtures/developers_projects.yml +0 -17
  296. data/test/fixtures/edges.yml +0 -6
  297. data/test/fixtures/entrants.yml +0 -14
  298. data/test/fixtures/faces.yml +0 -11
  299. data/test/fixtures/fk_test_has_fk.yml +0 -3
  300. data/test/fixtures/fk_test_has_pk.yml +0 -2
  301. data/test/fixtures/funny_jokes.yml +0 -10
  302. data/test/fixtures/interests.yml +0 -33
  303. data/test/fixtures/items.yml +0 -4
  304. data/test/fixtures/jobs.yml +0 -7
  305. data/test/fixtures/legacy_things.yml +0 -3
  306. data/test/fixtures/mateys.yml +0 -4
  307. data/test/fixtures/member_types.yml +0 -6
  308. data/test/fixtures/members.yml +0 -6
  309. data/test/fixtures/memberships.yml +0 -20
  310. data/test/fixtures/men.yml +0 -5
  311. data/test/fixtures/minimalistics.yml +0 -2
  312. data/test/fixtures/mixed_case_monkeys.yml +0 -6
  313. data/test/fixtures/mixins.yml +0 -29
  314. data/test/fixtures/movies.yml +0 -7
  315. data/test/fixtures/naked/csv/accounts.csv +0 -1
  316. data/test/fixtures/naked/yml/accounts.yml +0 -1
  317. data/test/fixtures/naked/yml/companies.yml +0 -1
  318. data/test/fixtures/naked/yml/courses.yml +0 -1
  319. data/test/fixtures/organizations.yml +0 -5
  320. data/test/fixtures/owners.yml +0 -7
  321. data/test/fixtures/parrots.yml +0 -27
  322. data/test/fixtures/parrots_pirates.yml +0 -7
  323. data/test/fixtures/people.yml +0 -15
  324. data/test/fixtures/pets.yml +0 -14
  325. data/test/fixtures/pirates.yml +0 -9
  326. data/test/fixtures/polymorphic_designs.yml +0 -19
  327. data/test/fixtures/polymorphic_prices.yml +0 -19
  328. data/test/fixtures/posts.yml +0 -52
  329. data/test/fixtures/price_estimates.yml +0 -7
  330. data/test/fixtures/projects.yml +0 -7
  331. data/test/fixtures/readers.yml +0 -9
  332. data/test/fixtures/references.yml +0 -17
  333. data/test/fixtures/reserved_words/distinct.yml +0 -5
  334. data/test/fixtures/reserved_words/distincts_selects.yml +0 -11
  335. data/test/fixtures/reserved_words/group.yml +0 -14
  336. data/test/fixtures/reserved_words/select.yml +0 -8
  337. data/test/fixtures/reserved_words/values.yml +0 -7
  338. data/test/fixtures/ships.yml +0 -5
  339. data/test/fixtures/sponsors.yml +0 -9
  340. data/test/fixtures/subscribers.yml +0 -7
  341. data/test/fixtures/subscriptions.yml +0 -12
  342. data/test/fixtures/taggings.yml +0 -28
  343. data/test/fixtures/tags.yml +0 -7
  344. data/test/fixtures/tasks.yml +0 -7
  345. data/test/fixtures/tees.yml +0 -4
  346. data/test/fixtures/ties.yml +0 -4
  347. data/test/fixtures/topics.yml +0 -42
  348. data/test/fixtures/toys.yml +0 -4
  349. data/test/fixtures/treasures.yml +0 -10
  350. data/test/fixtures/vertices.yml +0 -4
  351. data/test/fixtures/warehouse-things.yml +0 -3
  352. data/test/fixtures/zines.yml +0 -5
  353. data/test/migrations/broken/100_migration_that_raises_exception.rb +0 -10
  354. data/test/migrations/decimal/1_give_me_big_numbers.rb +0 -15
  355. data/test/migrations/duplicate/1_people_have_last_names.rb +0 -9
  356. data/test/migrations/duplicate/2_we_need_reminders.rb +0 -12
  357. data/test/migrations/duplicate/3_foo.rb +0 -7
  358. data/test/migrations/duplicate/3_innocent_jointable.rb +0 -12
  359. data/test/migrations/duplicate_names/20080507052938_chunky.rb +0 -7
  360. data/test/migrations/duplicate_names/20080507053028_chunky.rb +0 -7
  361. data/test/migrations/interleaved/pass_1/3_innocent_jointable.rb +0 -12
  362. data/test/migrations/interleaved/pass_2/1_people_have_last_names.rb +0 -9
  363. data/test/migrations/interleaved/pass_2/3_innocent_jointable.rb +0 -12
  364. data/test/migrations/interleaved/pass_3/1_people_have_last_names.rb +0 -9
  365. data/test/migrations/interleaved/pass_3/2_i_raise_on_down.rb +0 -8
  366. data/test/migrations/interleaved/pass_3/3_innocent_jointable.rb +0 -12
  367. data/test/migrations/missing/1000_people_have_middle_names.rb +0 -9
  368. data/test/migrations/missing/1_people_have_last_names.rb +0 -9
  369. data/test/migrations/missing/3_we_need_reminders.rb +0 -12
  370. data/test/migrations/missing/4_innocent_jointable.rb +0 -12
  371. data/test/migrations/valid/1_people_have_last_names.rb +0 -9
  372. data/test/migrations/valid/2_we_need_reminders.rb +0 -12
  373. data/test/migrations/valid/3_innocent_jointable.rb +0 -12
  374. data/test/models/author.rb +0 -151
  375. data/test/models/auto_id.rb +0 -4
  376. data/test/models/binary.rb +0 -2
  377. data/test/models/bird.rb +0 -9
  378. data/test/models/book.rb +0 -4
  379. data/test/models/categorization.rb +0 -5
  380. data/test/models/category.rb +0 -34
  381. data/test/models/citation.rb +0 -6
  382. data/test/models/club.rb +0 -13
  383. data/test/models/column_name.rb +0 -3
  384. data/test/models/comment.rb +0 -29
  385. data/test/models/company.rb +0 -173
  386. data/test/models/company_in_module.rb +0 -78
  387. data/test/models/computer.rb +0 -3
  388. data/test/models/contact.rb +0 -16
  389. data/test/models/contract.rb +0 -5
  390. data/test/models/course.rb +0 -3
  391. data/test/models/customer.rb +0 -73
  392. data/test/models/default.rb +0 -2
  393. data/test/models/developer.rb +0 -101
  394. data/test/models/edge.rb +0 -5
  395. data/test/models/entrant.rb +0 -3
  396. data/test/models/essay.rb +0 -3
  397. data/test/models/event.rb +0 -3
  398. data/test/models/event_author.rb +0 -8
  399. data/test/models/face.rb +0 -7
  400. data/test/models/guid.rb +0 -2
  401. data/test/models/interest.rb +0 -5
  402. data/test/models/invoice.rb +0 -4
  403. data/test/models/item.rb +0 -7
  404. data/test/models/job.rb +0 -5
  405. data/test/models/joke.rb +0 -3
  406. data/test/models/keyboard.rb +0 -3
  407. data/test/models/legacy_thing.rb +0 -3
  408. data/test/models/line_item.rb +0 -3
  409. data/test/models/man.rb +0 -9
  410. data/test/models/matey.rb +0 -4
  411. data/test/models/member.rb +0 -12
  412. data/test/models/member_detail.rb +0 -5
  413. data/test/models/member_type.rb +0 -3
  414. data/test/models/membership.rb +0 -9
  415. data/test/models/minimalistic.rb +0 -2
  416. data/test/models/mixed_case_monkey.rb +0 -3
  417. data/test/models/movie.rb +0 -5
  418. data/test/models/order.rb +0 -4
  419. data/test/models/organization.rb +0 -6
  420. data/test/models/owner.rb +0 -5
  421. data/test/models/parrot.rb +0 -22
  422. data/test/models/person.rb +0 -16
  423. data/test/models/pet.rb +0 -5
  424. data/test/models/pirate.rb +0 -80
  425. data/test/models/polymorphic_design.rb +0 -3
  426. data/test/models/polymorphic_price.rb +0 -3
  427. data/test/models/post.rb +0 -102
  428. data/test/models/price_estimate.rb +0 -3
  429. data/test/models/project.rb +0 -30
  430. data/test/models/reader.rb +0 -4
  431. data/test/models/reference.rb +0 -4
  432. data/test/models/reply.rb +0 -46
  433. data/test/models/ship.rb +0 -19
  434. data/test/models/ship_part.rb +0 -7
  435. data/test/models/sponsor.rb +0 -4
  436. data/test/models/subject.rb +0 -4
  437. data/test/models/subscriber.rb +0 -8
  438. data/test/models/subscription.rb +0 -4
  439. data/test/models/tag.rb +0 -7
  440. data/test/models/tagging.rb +0 -10
  441. data/test/models/task.rb +0 -3
  442. data/test/models/tee.rb +0 -4
  443. data/test/models/tie.rb +0 -4
  444. data/test/models/topic.rb +0 -80
  445. data/test/models/toy.rb +0 -6
  446. data/test/models/treasure.rb +0 -8
  447. data/test/models/vertex.rb +0 -9
  448. data/test/models/warehouse_thing.rb +0 -5
  449. data/test/models/zine.rb +0 -3
  450. data/test/schema/mysql_specific_schema.rb +0 -31
  451. data/test/schema/postgresql_specific_schema.rb +0 -114
  452. data/test/schema/schema.rb +0 -550
  453. data/test/schema/schema2.rb +0 -6
  454. data/test/schema/sqlite_specific_schema.rb +0 -25
@@ -0,0 +1,200 @@
1
+ require 'active_support/core_ext/array'
2
+ require 'active_support/core_ext/hash/except'
3
+ require 'active_support/core_ext/kernel/singleton_class'
4
+ require 'active_support/core_ext/object/blank'
5
+ require 'active_support/core_ext/class/attribute'
6
+
7
+ module ActiveRecord
8
+ # = Active Record Named \Scopes
9
+ module Scoping
10
+ module Named
11
+ extend ActiveSupport::Concern
12
+
13
+ module ClassMethods
14
+ # Returns an anonymous \scope.
15
+ #
16
+ # posts = Post.scoped
17
+ # posts.size # Fires "select count(*) from posts" and returns the count
18
+ # posts.each {|p| puts p.name } # Fires "select * from posts" and loads post objects
19
+ #
20
+ # fruits = Fruit.scoped
21
+ # fruits = fruits.where(:color => 'red') if options[:red_only]
22
+ # fruits = fruits.limit(10) if limited?
23
+ #
24
+ # Anonymous \scopes tend to be useful when procedurally generating complex
25
+ # queries, where passing intermediate values (\scopes) around as first-class
26
+ # objects is convenient.
27
+ #
28
+ # You can define a \scope that applies to all finders using
29
+ # ActiveRecord::Base.default_scope.
30
+ def scoped(options = nil)
31
+ if options
32
+ scoped.apply_finder_options(options)
33
+ else
34
+ if current_scope
35
+ current_scope.clone
36
+ else
37
+ scope = relation
38
+ scope.default_scoped = true
39
+ scope
40
+ end
41
+ end
42
+ end
43
+
44
+ ##
45
+ # Collects attributes from scopes that should be applied when creating
46
+ # an AR instance for the particular class this is called on.
47
+ def scope_attributes # :nodoc:
48
+ if current_scope
49
+ current_scope.scope_for_create
50
+ else
51
+ scope = relation
52
+ scope.default_scoped = true
53
+ scope.scope_for_create
54
+ end
55
+ end
56
+
57
+ ##
58
+ # Are there default attributes associated with this scope?
59
+ def scope_attributes? # :nodoc:
60
+ current_scope || default_scopes.any?
61
+ end
62
+
63
+ # Adds a class method for retrieving and querying objects. A \scope represents a narrowing of a database query,
64
+ # such as <tt>where(:color => :red).select('shirts.*').includes(:washing_instructions)</tt>.
65
+ #
66
+ # class Shirt < ActiveRecord::Base
67
+ # scope :red, where(:color => 'red')
68
+ # scope :dry_clean_only, joins(:washing_instructions).where('washing_instructions.dry_clean_only = ?', true)
69
+ # end
70
+ #
71
+ # The above calls to <tt>scope</tt> define class methods Shirt.red and Shirt.dry_clean_only. Shirt.red,
72
+ # in effect, represents the query <tt>Shirt.where(:color => 'red')</tt>.
73
+ #
74
+ # Note that this is simply 'syntactic sugar' for defining an actual class method:
75
+ #
76
+ # class Shirt < ActiveRecord::Base
77
+ # def self.red
78
+ # where(:color => 'red')
79
+ # end
80
+ # end
81
+ #
82
+ # Unlike <tt>Shirt.find(...)</tt>, however, the object returned by Shirt.red is not an Array; it
83
+ # resembles the association object constructed by a <tt>has_many</tt> declaration. For instance,
84
+ # you can invoke <tt>Shirt.red.first</tt>, <tt>Shirt.red.count</tt>, <tt>Shirt.red.where(:size => 'small')</tt>.
85
+ # Also, just as with the association objects, named \scopes act like an Array, implementing Enumerable;
86
+ # <tt>Shirt.red.each(&block)</tt>, <tt>Shirt.red.first</tt>, and <tt>Shirt.red.inject(memo, &block)</tt>
87
+ # all behave as if Shirt.red really was an Array.
88
+ #
89
+ # These named \scopes are composable. For instance, <tt>Shirt.red.dry_clean_only</tt> will produce
90
+ # all shirts that are both red and dry clean only.
91
+ # Nested finds and calculations also work with these compositions: <tt>Shirt.red.dry_clean_only.count</tt>
92
+ # returns the number of garments for which these criteria obtain. Similarly with
93
+ # <tt>Shirt.red.dry_clean_only.average(:thread_count)</tt>.
94
+ #
95
+ # All \scopes are available as class methods on the ActiveRecord::Base descendant upon which
96
+ # the \scopes were defined. But they are also available to <tt>has_many</tt> associations. If,
97
+ #
98
+ # class Person < ActiveRecord::Base
99
+ # has_many :shirts
100
+ # end
101
+ #
102
+ # then <tt>elton.shirts.red.dry_clean_only</tt> will return all of Elton's red, dry clean
103
+ # only shirts.
104
+ #
105
+ # Named \scopes can also be procedural:
106
+ #
107
+ # class Shirt < ActiveRecord::Base
108
+ # scope :colored, lambda { |color| where(:color => color) }
109
+ # end
110
+ #
111
+ # In this example, <tt>Shirt.colored('puce')</tt> finds all puce shirts.
112
+ #
113
+ # On Ruby 1.9 you can use the 'stabby lambda' syntax:
114
+ #
115
+ # scope :colored, ->(color) { where(:color => color) }
116
+ #
117
+ # Note that scopes defined with \scope will be evaluated when they are defined, rather than
118
+ # when they are used. For example, the following would be incorrect:
119
+ #
120
+ # class Post < ActiveRecord::Base
121
+ # scope :recent, where('published_at >= ?', Time.current - 1.week)
122
+ # end
123
+ #
124
+ # The example above would be 'frozen' to the <tt>Time.current</tt> value when the <tt>Post</tt>
125
+ # class was defined, and so the resultant SQL query would always be the same. The correct
126
+ # way to do this would be via a lambda, which will re-evaluate the scope each time
127
+ # it is called:
128
+ #
129
+ # class Post < ActiveRecord::Base
130
+ # scope :recent, lambda { where('published_at >= ?', Time.current - 1.week) }
131
+ # end
132
+ #
133
+ # Named \scopes can also have extensions, just as with <tt>has_many</tt> declarations:
134
+ #
135
+ # class Shirt < ActiveRecord::Base
136
+ # scope :red, where(:color => 'red') do
137
+ # def dom_id
138
+ # 'red_shirts'
139
+ # end
140
+ # end
141
+ # end
142
+ #
143
+ # Scopes can also be used while creating/building a record.
144
+ #
145
+ # class Article < ActiveRecord::Base
146
+ # scope :published, where(:published => true)
147
+ # end
148
+ #
149
+ # Article.published.new.published # => true
150
+ # Article.published.create.published # => true
151
+ #
152
+ # Class methods on your model are automatically available
153
+ # on scopes. Assuming the following setup:
154
+ #
155
+ # class Article < ActiveRecord::Base
156
+ # scope :published, where(:published => true)
157
+ # scope :featured, where(:featured => true)
158
+ #
159
+ # def self.latest_article
160
+ # order('published_at desc').first
161
+ # end
162
+ #
163
+ # def self.titles
164
+ # pluck(:title)
165
+ # end
166
+ # end
167
+ #
168
+ # We are able to call the methods like this:
169
+ #
170
+ # Article.published.featured.latest_article
171
+ # Article.featured.titles
172
+ def scope(name, scope_options = {})
173
+ name = name.to_sym
174
+ valid_scope_name?(name)
175
+ extension = Module.new(&Proc.new) if block_given?
176
+
177
+ scope_proc = lambda do |*args|
178
+ options = scope_options.respond_to?(:call) ? unscoped { scope_options.call(*args) } : scope_options
179
+ options = scoped.apply_finder_options(options) if options.is_a?(Hash)
180
+
181
+ relation = scoped.merge(options)
182
+
183
+ extension ? relation.extending(extension) : relation
184
+ end
185
+
186
+ singleton_class.send(:redefine_method, name, &scope_proc)
187
+ end
188
+
189
+ protected
190
+
191
+ def valid_scope_name?(name)
192
+ if logger && respond_to?(name, true)
193
+ logger.warn "Creating scope :#{name}. " \
194
+ "Overwriting existing method #{self.name}.#{name}."
195
+ end
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,152 @@
1
+ require 'active_support/concern'
2
+
3
+ module ActiveRecord
4
+ module Scoping
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ include Default
9
+ include Named
10
+ end
11
+
12
+ module ClassMethods
13
+ # with_scope lets you apply options to inner block incrementally. It takes a hash and the keys must be
14
+ # <tt>:find</tt> or <tt>:create</tt>. <tt>:find</tt> parameter is <tt>Relation</tt> while
15
+ # <tt>:create</tt> parameters are an attributes hash.
16
+ #
17
+ # class Article < ActiveRecord::Base
18
+ # def self.create_with_scope
19
+ # with_scope(:find => where(:blog_id => 1), :create => { :blog_id => 1 }) do
20
+ # find(1) # => SELECT * from articles WHERE blog_id = 1 AND id = 1
21
+ # a = create(1)
22
+ # a.blog_id # => 1
23
+ # end
24
+ # end
25
+ # end
26
+ #
27
+ # In nested scopings, all previous parameters are overwritten by the innermost rule, with the exception of
28
+ # <tt>where</tt>, <tt>includes</tt>, and <tt>joins</tt> operations in <tt>Relation</tt>, which are merged.
29
+ #
30
+ # <tt>joins</tt> operations are uniqued so multiple scopes can join in the same table without table aliasing
31
+ # problems. If you need to join multiple tables, but still want one of the tables to be uniqued, use the
32
+ # array of strings format for your joins.
33
+ #
34
+ # class Article < ActiveRecord::Base
35
+ # def self.find_with_scope
36
+ # with_scope(:find => where(:blog_id => 1).limit(1), :create => { :blog_id => 1 }) do
37
+ # with_scope(:find => limit(10)) do
38
+ # all # => SELECT * from articles WHERE blog_id = 1 LIMIT 10
39
+ # end
40
+ # with_scope(:find => where(:author_id => 3)) do
41
+ # all # => SELECT * from articles WHERE blog_id = 1 AND author_id = 3 LIMIT 1
42
+ # end
43
+ # end
44
+ # end
45
+ # end
46
+ #
47
+ # You can ignore any previous scopings by using the <tt>with_exclusive_scope</tt> method.
48
+ #
49
+ # class Article < ActiveRecord::Base
50
+ # def self.find_with_exclusive_scope
51
+ # with_scope(:find => where(:blog_id => 1).limit(1)) do
52
+ # with_exclusive_scope(:find => limit(10)) do
53
+ # all # => SELECT * from articles LIMIT 10
54
+ # end
55
+ # end
56
+ # end
57
+ # end
58
+ #
59
+ # *Note*: the +:find+ scope also has effect on update and deletion methods, like +update_all+ and +delete_all+.
60
+ def with_scope(scope = {}, action = :merge, &block)
61
+ # If another Active Record class has been passed in, get its current scope
62
+ scope = scope.current_scope if !scope.is_a?(Relation) && scope.respond_to?(:current_scope)
63
+
64
+ previous_scope = self.current_scope
65
+
66
+ if scope.is_a?(Hash)
67
+ # Dup first and second level of hash (method and params).
68
+ scope = scope.dup
69
+ scope.each do |method, params|
70
+ scope[method] = params.dup unless params == true
71
+ end
72
+
73
+ scope.assert_valid_keys([ :find, :create ])
74
+ relation = construct_finder_arel(scope[:find] || {})
75
+ relation.default_scoped = true unless action == :overwrite
76
+
77
+ if previous_scope && previous_scope.create_with_value && scope[:create]
78
+ scope_for_create = if action == :merge
79
+ previous_scope.create_with_value.merge(scope[:create])
80
+ else
81
+ scope[:create]
82
+ end
83
+
84
+ relation = relation.create_with(scope_for_create)
85
+ else
86
+ scope_for_create = scope[:create]
87
+ scope_for_create ||= previous_scope.create_with_value if previous_scope
88
+ relation = relation.create_with(scope_for_create) if scope_for_create
89
+ end
90
+
91
+ scope = relation
92
+ end
93
+
94
+ scope = previous_scope.merge(scope) if previous_scope && action == :merge
95
+
96
+ self.current_scope = scope
97
+ begin
98
+ yield
99
+ ensure
100
+ self.current_scope = previous_scope
101
+ end
102
+ end
103
+
104
+ protected
105
+
106
+ # Works like with_scope, but discards any nested properties.
107
+ def with_exclusive_scope(method_scoping = {}, &block)
108
+ if method_scoping.values.any? { |e| e.is_a?(ActiveRecord::Relation) }
109
+ raise ArgumentError, <<-MSG
110
+ New finder API can not be used with_exclusive_scope. You can either call unscoped to get an anonymous scope not bound to the default_scope:
111
+
112
+ User.unscoped.where(:active => true)
113
+
114
+ Or call unscoped with a block:
115
+
116
+ User.unscoped do
117
+ User.where(:active => true).all
118
+ end
119
+
120
+ MSG
121
+ end
122
+ with_scope(method_scoping, :overwrite, &block)
123
+ end
124
+
125
+ def current_scope #:nodoc:
126
+ Thread.current["#{self}_current_scope"]
127
+ end
128
+
129
+ def current_scope=(scope) #:nodoc:
130
+ Thread.current["#{self}_current_scope"] = scope
131
+ end
132
+
133
+ private
134
+
135
+ def construct_finder_arel(options = {}, scope = nil)
136
+ relation = options.is_a?(Hash) ? unscoped.apply_finder_options(options) : options
137
+ relation = scope.merge(relation) if scope
138
+ relation
139
+ end
140
+
141
+ end
142
+
143
+ def populate_with_current_scope_attributes
144
+ return unless self.class.scope_attributes?
145
+
146
+ self.class.scope_attributes.each do |att,value|
147
+ send("#{att}=", value) if respond_to?("#{att}=")
148
+ end
149
+ end
150
+
151
+ end
152
+ end
@@ -1,101 +1,18 @@
1
- require 'active_support/json'
2
-
3
1
  module ActiveRecord #:nodoc:
2
+ # = Active Record Serialization
4
3
  module Serialization
5
- class Serializer #:nodoc:
6
- attr_reader :options
7
-
8
- def initialize(record, options = nil)
9
- @record = record
10
- @options = options ? options.dup : {}
11
- end
12
-
13
- # To replicate the behavior in ActiveRecord#attributes,
14
- # <tt>:except</tt> takes precedence over <tt>:only</tt>. If <tt>:only</tt> is not set
15
- # for a N level model but is set for the N+1 level models,
16
- # then because <tt>:except</tt> is set to a default value, the second
17
- # level model can have both <tt>:except</tt> and <tt>:only</tt> set. So if
18
- # <tt>:only</tt> is set, always delete <tt>:except</tt>.
19
- def serializable_attribute_names
20
- attribute_names = @record.attribute_names
21
-
22
- if options[:only]
23
- options.delete(:except)
24
- attribute_names = attribute_names & Array(options[:only]).collect { |n| n.to_s }
25
- else
26
- options[:except] = Array(options[:except]) | Array(@record.class.inheritance_column)
27
- attribute_names = attribute_names - options[:except].collect { |n| n.to_s }
28
- end
29
-
30
- attribute_names
31
- end
32
-
33
- def serializable_method_names
34
- Array(options[:methods]).inject([]) do |method_attributes, name|
35
- method_attributes << name if @record.respond_to?(name.to_s)
36
- method_attributes
37
- end
38
- end
39
-
40
- def serializable_names
41
- serializable_attribute_names + serializable_method_names
42
- end
43
-
44
- # Add associations specified via the <tt>:includes</tt> option.
45
- # Expects a block that takes as arguments:
46
- # +association+ - name of the association
47
- # +records+ - the association record(s) to be serialized
48
- # +opts+ - options for the association records
49
- def add_includes(&block)
50
- if include_associations = options.delete(:include)
51
- base_only_or_except = { :except => options[:except],
52
- :only => options[:only] }
53
-
54
- include_has_options = include_associations.is_a?(Hash)
55
- associations = include_has_options ? include_associations.keys : Array(include_associations)
56
-
57
- for association in associations
58
- records = case @record.class.reflect_on_association(association).macro
59
- when :has_many, :has_and_belongs_to_many
60
- @record.send(association).to_a
61
- when :has_one, :belongs_to
62
- @record.send(association)
63
- end
64
-
65
- unless records.nil?
66
- association_options = include_has_options ? include_associations[association] : base_only_or_except
67
- opts = options.merge(association_options)
68
- yield(association, records, opts)
69
- end
70
- end
71
-
72
- options[:include] = include_associations
73
- end
74
- end
4
+ extend ActiveSupport::Concern
5
+ include ActiveModel::Serializers::JSON
75
6
 
76
- def serializable_record
77
- {}.tap do |serializable_record|
78
- serializable_names.each { |name| serializable_record[name] = @record.send(name) }
79
- add_includes do |association, records, opts|
80
- if records.is_a?(Enumerable)
81
- serializable_record[association] = records.collect { |r| self.class.new(r, opts).serializable_record }
82
- else
83
- serializable_record[association] = self.class.new(records, opts).serializable_record
84
- end
85
- end
86
- end
87
- end
7
+ def serializable_hash(options = nil)
8
+ options = options.try(:clone) || {}
88
9
 
89
- def serialize
90
- # overwrite to implement
91
- end
10
+ options[:except] = Array.wrap(options[:except]).map { |n| n.to_s }
11
+ options[:except] |= Array.wrap(self.class.inheritance_column)
92
12
 
93
- def to_s(&block)
94
- serialize(&block)
95
- end
13
+ super(options)
96
14
  end
97
15
  end
98
16
  end
99
17
 
100
18
  require 'active_record/serializers/xml_serializer'
101
- require 'active_record/serializers/json_serializer'