activerecord 5.0.6 → 6.0.1

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 (358) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +638 -2023
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +8 -6
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record/aggregations.rb +249 -246
  8. data/lib/active_record/association_relation.rb +24 -13
  9. data/lib/active_record/associations/alias_tracker.rb +24 -33
  10. data/lib/active_record/associations/association.rb +119 -56
  11. data/lib/active_record/associations/association_scope.rb +94 -94
  12. data/lib/active_record/associations/belongs_to_association.rb +58 -42
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  14. data/lib/active_record/associations/builder/association.rb +18 -25
  15. data/lib/active_record/associations/builder/belongs_to.rb +43 -54
  16. data/lib/active_record/associations/builder/collection_association.rb +7 -18
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +42 -61
  18. data/lib/active_record/associations/builder/has_many.rb +4 -0
  19. data/lib/active_record/associations/builder/has_one.rb +37 -1
  20. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  21. data/lib/active_record/associations/collection_association.rb +80 -252
  22. data/lib/active_record/associations/collection_proxy.rb +158 -121
  23. data/lib/active_record/associations/foreign_association.rb +9 -0
  24. data/lib/active_record/associations/has_many_association.rb +23 -29
  25. data/lib/active_record/associations/has_many_through_association.rb +58 -44
  26. data/lib/active_record/associations/has_one_association.rb +59 -54
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +38 -90
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
  31. data/lib/active_record/associations/join_dependency.rb +134 -176
  32. data/lib/active_record/associations/preloader/association.rb +84 -125
  33. data/lib/active_record/associations/preloader/through_association.rb +82 -75
  34. data/lib/active_record/associations/preloader.rb +90 -102
  35. data/lib/active_record/associations/singular_association.rb +12 -45
  36. data/lib/active_record/associations/through_association.rb +26 -14
  37. data/lib/active_record/associations.rb +1603 -1592
  38. data/lib/active_record/attribute_assignment.rb +54 -60
  39. data/lib/active_record/attribute_decorators.rb +38 -15
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +12 -7
  41. data/lib/active_record/attribute_methods/dirty.rb +179 -109
  42. data/lib/active_record/attribute_methods/primary_key.rb +86 -91
  43. data/lib/active_record/attribute_methods/query.rb +4 -3
  44. data/lib/active_record/attribute_methods/read.rb +21 -49
  45. data/lib/active_record/attribute_methods/serialization.rb +30 -7
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -64
  47. data/lib/active_record/attribute_methods/write.rb +35 -33
  48. data/lib/active_record/attribute_methods.rb +66 -106
  49. data/lib/active_record/attributes.rb +38 -24
  50. data/lib/active_record/autosave_association.rb +53 -32
  51. data/lib/active_record/base.rb +27 -24
  52. data/lib/active_record/callbacks.rb +63 -33
  53. data/lib/active_record/coders/json.rb +2 -0
  54. data/lib/active_record/coders/yaml_column.rb +11 -11
  55. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +553 -321
  56. data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
  57. data/lib/active_record/connection_adapters/abstract/database_statements.rb +213 -94
  58. data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -28
  59. data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -75
  60. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  61. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -27
  62. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +207 -126
  63. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  64. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +369 -199
  65. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -78
  66. data/lib/active_record/connection_adapters/abstract_adapter.rb +363 -202
  67. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +405 -551
  68. data/lib/active_record/connection_adapters/column.rb +41 -13
  69. data/lib/active_record/connection_adapters/connection_specification.rb +172 -138
  70. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
  71. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  72. data/lib/active_record/connection_adapters/mysql/database_statements.rb +143 -49
  73. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -22
  74. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  75. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +50 -45
  76. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
  77. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  78. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  79. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
  80. data/lib/active_record/connection_adapters/mysql2_adapter.rb +49 -30
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +22 -7
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +60 -54
  83. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -10
  85. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +4 -2
  91. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -17
  94. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  98. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +31 -9
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +34 -30
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  102. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  103. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +9 -4
  104. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +35 -32
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +380 -300
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +10 -6
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +382 -275
  116. data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
  118. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +120 -0
  119. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  120. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +74 -19
  121. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
  122. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  125. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +254 -262
  126. data/lib/active_record/connection_adapters/statement_pool.rb +9 -7
  127. data/lib/active_record/connection_handling.rb +159 -40
  128. data/lib/active_record/core.rb +202 -162
  129. data/lib/active_record/counter_cache.rb +57 -28
  130. data/lib/active_record/database_configurations/database_config.rb +37 -0
  131. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  132. data/lib/active_record/database_configurations/url_config.rb +79 -0
  133. data/lib/active_record/database_configurations.rb +233 -0
  134. data/lib/active_record/define_callbacks.rb +22 -0
  135. data/lib/active_record/dynamic_matchers.rb +87 -86
  136. data/lib/active_record/enum.rb +60 -23
  137. data/lib/active_record/errors.rb +114 -18
  138. data/lib/active_record/explain.rb +4 -3
  139. data/lib/active_record/explain_registry.rb +3 -1
  140. data/lib/active_record/explain_subscriber.rb +9 -4
  141. data/lib/active_record/fixture_set/file.rb +13 -8
  142. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  143. data/lib/active_record/fixture_set/render_context.rb +17 -0
  144. data/lib/active_record/fixture_set/table_row.rb +153 -0
  145. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  146. data/lib/active_record/fixtures.rb +195 -502
  147. data/lib/active_record/gem_version.rb +4 -2
  148. data/lib/active_record/inheritance.rb +151 -97
  149. data/lib/active_record/insert_all.rb +179 -0
  150. data/lib/active_record/integration.rb +116 -25
  151. data/lib/active_record/internal_metadata.rb +15 -18
  152. data/lib/active_record/legacy_yaml_adapter.rb +4 -2
  153. data/lib/active_record/locking/optimistic.rb +78 -87
  154. data/lib/active_record/locking/pessimistic.rb +18 -6
  155. data/lib/active_record/log_subscriber.rb +48 -29
  156. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  157. data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
  158. data/lib/active_record/middleware/database_selector.rb +75 -0
  159. data/lib/active_record/migration/command_recorder.rb +143 -97
  160. data/lib/active_record/migration/compatibility.rb +174 -56
  161. data/lib/active_record/migration/join_table.rb +8 -6
  162. data/lib/active_record/migration.rb +367 -300
  163. data/lib/active_record/model_schema.rb +145 -139
  164. data/lib/active_record/nested_attributes.rb +214 -201
  165. data/lib/active_record/no_touching.rb +10 -1
  166. data/lib/active_record/null_relation.rb +13 -34
  167. data/lib/active_record/persistence.rb +442 -72
  168. data/lib/active_record/query_cache.rb +15 -14
  169. data/lib/active_record/querying.rb +36 -23
  170. data/lib/active_record/railtie.rb +128 -36
  171. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  172. data/lib/active_record/railties/console_sandbox.rb +2 -0
  173. data/lib/active_record/railties/controller_runtime.rb +34 -33
  174. data/lib/active_record/railties/databases.rake +309 -177
  175. data/lib/active_record/readonly_attributes.rb +5 -4
  176. data/lib/active_record/reflection.rb +211 -249
  177. data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
  178. data/lib/active_record/relation/batches.rb +99 -52
  179. data/lib/active_record/relation/calculations.rb +211 -172
  180. data/lib/active_record/relation/delegation.rb +67 -65
  181. data/lib/active_record/relation/finder_methods.rb +208 -247
  182. data/lib/active_record/relation/from_clause.rb +2 -8
  183. data/lib/active_record/relation/merger.rb +78 -61
  184. data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
  185. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  186. data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
  187. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  188. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  189. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  190. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  191. data/lib/active_record/relation/predicate_builder.rb +86 -104
  192. data/lib/active_record/relation/query_attribute.rb +33 -2
  193. data/lib/active_record/relation/query_methods.rb +458 -329
  194. data/lib/active_record/relation/record_fetch_warning.rb +5 -3
  195. data/lib/active_record/relation/spawn_methods.rb +8 -7
  196. data/lib/active_record/relation/where_clause.rb +111 -95
  197. data/lib/active_record/relation/where_clause_factory.rb +6 -11
  198. data/lib/active_record/relation.rb +429 -318
  199. data/lib/active_record/result.rb +69 -39
  200. data/lib/active_record/runtime_registry.rb +5 -3
  201. data/lib/active_record/sanitization.rb +83 -99
  202. data/lib/active_record/schema.rb +7 -14
  203. data/lib/active_record/schema_dumper.rb +71 -69
  204. data/lib/active_record/schema_migration.rb +15 -5
  205. data/lib/active_record/scoping/default.rb +93 -95
  206. data/lib/active_record/scoping/named.rb +45 -25
  207. data/lib/active_record/scoping.rb +20 -19
  208. data/lib/active_record/secure_token.rb +4 -2
  209. data/lib/active_record/serialization.rb +2 -0
  210. data/lib/active_record/statement_cache.rb +63 -28
  211. data/lib/active_record/store.rb +121 -41
  212. data/lib/active_record/suppressor.rb +4 -1
  213. data/lib/active_record/table_metadata.rb +26 -20
  214. data/lib/active_record/tasks/database_tasks.rb +276 -85
  215. data/lib/active_record/tasks/mysql_database_tasks.rb +54 -90
  216. data/lib/active_record/tasks/postgresql_database_tasks.rb +78 -47
  217. data/lib/active_record/tasks/sqlite_database_tasks.rb +34 -16
  218. data/lib/active_record/test_databases.rb +23 -0
  219. data/lib/active_record/test_fixtures.rb +224 -0
  220. data/lib/active_record/timestamp.rb +70 -35
  221. data/lib/active_record/touch_later.rb +7 -4
  222. data/lib/active_record/transactions.rb +133 -149
  223. data/lib/active_record/translation.rb +3 -1
  224. data/lib/active_record/type/adapter_specific_registry.rb +44 -45
  225. data/lib/active_record/type/date.rb +2 -0
  226. data/lib/active_record/type/date_time.rb +2 -0
  227. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  228. data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
  229. data/lib/active_record/type/internal/timezone.rb +2 -0
  230. data/lib/active_record/type/json.rb +30 -0
  231. data/lib/active_record/type/serialized.rb +16 -8
  232. data/lib/active_record/type/text.rb +11 -0
  233. data/lib/active_record/type/time.rb +2 -1
  234. data/lib/active_record/type/type_map.rb +13 -15
  235. data/lib/active_record/type/unsigned_integer.rb +17 -0
  236. data/lib/active_record/type.rb +23 -17
  237. data/lib/active_record/type_caster/connection.rb +17 -12
  238. data/lib/active_record/type_caster/map.rb +5 -4
  239. data/lib/active_record/type_caster.rb +4 -2
  240. data/lib/active_record/validations/absence.rb +2 -0
  241. data/lib/active_record/validations/associated.rb +3 -1
  242. data/lib/active_record/validations/length.rb +2 -0
  243. data/lib/active_record/validations/presence.rb +4 -2
  244. data/lib/active_record/validations/uniqueness.rb +29 -42
  245. data/lib/active_record/validations.rb +7 -4
  246. data/lib/active_record/version.rb +3 -1
  247. data/lib/active_record.rb +36 -22
  248. data/lib/arel/alias_predication.rb +9 -0
  249. data/lib/arel/attributes/attribute.rb +37 -0
  250. data/lib/arel/attributes.rb +22 -0
  251. data/lib/arel/collectors/bind.rb +24 -0
  252. data/lib/arel/collectors/composite.rb +31 -0
  253. data/lib/arel/collectors/plain_string.rb +20 -0
  254. data/lib/arel/collectors/sql_string.rb +20 -0
  255. data/lib/arel/collectors/substitute_binds.rb +28 -0
  256. data/lib/arel/crud.rb +42 -0
  257. data/lib/arel/delete_manager.rb +18 -0
  258. data/lib/arel/errors.rb +9 -0
  259. data/lib/arel/expressions.rb +29 -0
  260. data/lib/arel/factory_methods.rb +49 -0
  261. data/lib/arel/insert_manager.rb +49 -0
  262. data/lib/arel/math.rb +45 -0
  263. data/lib/arel/nodes/and.rb +32 -0
  264. data/lib/arel/nodes/ascending.rb +23 -0
  265. data/lib/arel/nodes/binary.rb +52 -0
  266. data/lib/arel/nodes/bind_param.rb +36 -0
  267. data/lib/arel/nodes/case.rb +55 -0
  268. data/lib/arel/nodes/casted.rb +50 -0
  269. data/lib/arel/nodes/comment.rb +29 -0
  270. data/lib/arel/nodes/count.rb +12 -0
  271. data/lib/arel/nodes/delete_statement.rb +45 -0
  272. data/lib/arel/nodes/descending.rb +23 -0
  273. data/lib/arel/nodes/equality.rb +18 -0
  274. data/lib/arel/nodes/extract.rb +24 -0
  275. data/lib/arel/nodes/false.rb +16 -0
  276. data/lib/arel/nodes/full_outer_join.rb +8 -0
  277. data/lib/arel/nodes/function.rb +44 -0
  278. data/lib/arel/nodes/grouping.rb +8 -0
  279. data/lib/arel/nodes/in.rb +8 -0
  280. data/lib/arel/nodes/infix_operation.rb +80 -0
  281. data/lib/arel/nodes/inner_join.rb +8 -0
  282. data/lib/arel/nodes/insert_statement.rb +37 -0
  283. data/lib/arel/nodes/join_source.rb +20 -0
  284. data/lib/arel/nodes/matches.rb +18 -0
  285. data/lib/arel/nodes/named_function.rb +23 -0
  286. data/lib/arel/nodes/node.rb +50 -0
  287. data/lib/arel/nodes/node_expression.rb +13 -0
  288. data/lib/arel/nodes/outer_join.rb +8 -0
  289. data/lib/arel/nodes/over.rb +15 -0
  290. data/lib/arel/nodes/regexp.rb +16 -0
  291. data/lib/arel/nodes/right_outer_join.rb +8 -0
  292. data/lib/arel/nodes/select_core.rb +67 -0
  293. data/lib/arel/nodes/select_statement.rb +41 -0
  294. data/lib/arel/nodes/sql_literal.rb +16 -0
  295. data/lib/arel/nodes/string_join.rb +11 -0
  296. data/lib/arel/nodes/table_alias.rb +27 -0
  297. data/lib/arel/nodes/terminal.rb +16 -0
  298. data/lib/arel/nodes/true.rb +16 -0
  299. data/lib/arel/nodes/unary.rb +45 -0
  300. data/lib/arel/nodes/unary_operation.rb +20 -0
  301. data/lib/arel/nodes/unqualified_column.rb +22 -0
  302. data/lib/arel/nodes/update_statement.rb +41 -0
  303. data/lib/arel/nodes/values_list.rb +9 -0
  304. data/lib/arel/nodes/window.rb +126 -0
  305. data/lib/arel/nodes/with.rb +11 -0
  306. data/lib/arel/nodes.rb +68 -0
  307. data/lib/arel/order_predications.rb +13 -0
  308. data/lib/arel/predications.rb +257 -0
  309. data/lib/arel/select_manager.rb +271 -0
  310. data/lib/arel/table.rb +110 -0
  311. data/lib/arel/tree_manager.rb +72 -0
  312. data/lib/arel/update_manager.rb +34 -0
  313. data/lib/arel/visitors/depth_first.rb +204 -0
  314. data/lib/arel/visitors/dot.rb +297 -0
  315. data/lib/arel/visitors/ibm_db.rb +34 -0
  316. data/lib/arel/visitors/informix.rb +62 -0
  317. data/lib/arel/visitors/mssql.rb +157 -0
  318. data/lib/arel/visitors/mysql.rb +83 -0
  319. data/lib/arel/visitors/oracle.rb +159 -0
  320. data/lib/arel/visitors/oracle12.rb +66 -0
  321. data/lib/arel/visitors/postgresql.rb +110 -0
  322. data/lib/arel/visitors/sqlite.rb +39 -0
  323. data/lib/arel/visitors/to_sql.rb +889 -0
  324. data/lib/arel/visitors/visitor.rb +46 -0
  325. data/lib/arel/visitors/where_sql.rb +23 -0
  326. data/lib/arel/visitors.rb +20 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/arel.rb +58 -0
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  330. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  331. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -35
  332. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +1 -1
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +4 -2
  334. data/lib/rails/generators/active_record/migration.rb +17 -2
  335. data/lib/rails/generators/active_record/model/model_generator.rb +9 -29
  336. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  337. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  338. data/lib/rails/generators/active_record.rb +7 -5
  339. metadata +133 -50
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  342. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  343. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  344. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -20
  347. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  348. data/lib/active_record/attribute.rb +0 -213
  349. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  350. data/lib/active_record/attribute_set/builder.rb +0 -130
  351. data/lib/active_record/attribute_set.rb +0 -110
  352. data/lib/active_record/collection_cache_key.rb +0 -50
  353. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  354. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  355. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  356. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  357. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  358. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,4 +1,6 @@
1
- require 'stringio'
1
+ # frozen_string_literal: true
2
+
3
+ require "stringio"
2
4
 
3
5
  module ActiveRecord
4
6
  # = Active Record Schema Dumper
@@ -11,14 +13,19 @@ module ActiveRecord
11
13
  ##
12
14
  # :singleton-method:
13
15
  # A list of tables which should not be dumped to the schema.
14
- # Acceptable values are strings as well as regexp.
15
- # This setting is only used if ActiveRecord::Base.schema_format == :ruby
16
- cattr_accessor :ignore_tables
17
- @@ignore_tables = []
16
+ # Acceptable values are strings as well as regexp if ActiveRecord::Base.schema_format == :ruby.
17
+ # Only strings are accepted if ActiveRecord::Base.schema_format == :sql.
18
+ cattr_accessor :ignore_tables, default: []
19
+
20
+ ##
21
+ # :singleton-method:
22
+ # Specify a custom regular expression matching foreign keys which name
23
+ # should not be dumped to db/schema.rb.
24
+ cattr_accessor :fk_ignore_pattern, default: /^fk_rails_[0-9a-f]{10}$/
18
25
 
19
26
  class << self
20
- def dump(connection=ActiveRecord::Base.connection, stream=STDOUT, config = ActiveRecord::Base)
21
- new(connection, generate_options(config)).dump(stream)
27
+ def dump(connection = ActiveRecord::Base.connection, stream = STDOUT, config = ActiveRecord::Base)
28
+ connection.create_schema_dumper(generate_options(config)).dump(stream)
22
29
  stream
23
30
  end
24
31
 
@@ -40,26 +47,36 @@ module ActiveRecord
40
47
  end
41
48
 
42
49
  private
50
+ attr_accessor :table_name
43
51
 
44
52
  def initialize(connection, options = {})
45
53
  @connection = connection
46
- @version = Migrator::current_version rescue nil
54
+ @version = connection.migration_context.current_version rescue nil
47
55
  @options = options
48
56
  end
49
57
 
50
- def header(stream)
51
- define_params = @version ? "version: #{@version}" : ""
58
+ # turns 20170404131909 into "2017_04_04_131909"
59
+ def formatted_version
60
+ stringified = @version.to_s
61
+ return stringified unless stringified.length == 14
62
+ stringified.insert(4, "_").insert(7, "_").insert(10, "_")
63
+ end
64
+
65
+ def define_params
66
+ @version ? "version: #{formatted_version}" : ""
67
+ end
52
68
 
69
+ def header(stream)
53
70
  stream.puts <<HEADER
54
71
  # This file is auto-generated from the current state of the database. Instead
55
72
  # of editing this file, please use the migrations feature of Active Record to
56
73
  # incrementally modify your database, and then regenerate this schema definition.
57
74
  #
58
- # Note that this schema.rb definition is the authoritative source for your
59
- # database schema. If you need to create the application database on another
60
- # system, you should be using db:schema:load, not running all the migrations
61
- # from scratch. The latter is a flawed and unsustainable approach (the more migrations
62
- # you'll amass, the slower it'll run and the greater likelihood for issues).
75
+ # This file is the source Rails uses to define your schema when running `rails
76
+ # db:schema:load`. When creating a new database, `rails db:schema:load` tends to
77
+ # be faster and is potentially less error prone than running all of your
78
+ # migrations from scratch. Old migrations may fail to apply correctly if those
79
+ # migrations use external dependencies or application code.
63
80
  #
64
81
  # It's strongly recommended that you check this file into your version control system.
65
82
 
@@ -72,20 +89,12 @@ HEADER
72
89
  stream.puts "end"
73
90
  end
74
91
 
92
+ # extensions are only supported by PostgreSQL
75
93
  def extensions(stream)
76
- return unless @connection.supports_extensions?
77
- extensions = @connection.extensions
78
- if extensions.any?
79
- stream.puts " # These are extensions that must be enabled in order to support this database"
80
- extensions.each do |extension|
81
- stream.puts " enable_extension #{extension.inspect}"
82
- end
83
- stream.puts
84
- end
85
94
  end
86
95
 
87
96
  def tables(stream)
88
- sorted_tables = @connection.data_sources.sort - @connection.views
97
+ sorted_tables = @connection.tables.sort
89
98
 
90
99
  sorted_tables.each do |table_name|
91
100
  table(table_name, stream) unless ignored?(table_name)
@@ -102,6 +111,8 @@ HEADER
102
111
  def table(table, stream)
103
112
  columns = @connection.columns(table)
104
113
  begin
114
+ self.table_name = table
115
+
105
116
  tbl = StringIO.new
106
117
 
107
118
  # first dump primary key column
@@ -111,60 +122,36 @@ HEADER
111
122
 
112
123
  case pk
113
124
  when String
114
- tbl.print ", primary_key: #{pk.inspect}" unless pk == 'id'
125
+ tbl.print ", primary_key: #{pk.inspect}" unless pk == "id"
115
126
  pkcol = columns.detect { |c| c.name == pk }
116
- pkcolspec = @connection.column_spec_for_primary_key(pkcol)
127
+ pkcolspec = column_spec_for_primary_key(pkcol)
117
128
  if pkcolspec.present?
118
- pkcolspec.each do |key, value|
119
- tbl.print ", #{key}: #{value}"
120
- end
129
+ tbl.print ", #{format_colspec(pkcolspec)}"
121
130
  end
122
131
  when Array
123
132
  tbl.print ", primary_key: #{pk.inspect}"
124
133
  else
125
134
  tbl.print ", id: false"
126
135
  end
127
- tbl.print ", force: :cascade"
128
136
 
129
137
  table_options = @connection.table_options(table)
130
138
  if table_options.present?
131
139
  tbl.print ", #{format_options(table_options)}"
132
140
  end
133
141
 
134
- tbl.puts " do |t|"
142
+ tbl.puts ", force: :cascade do |t|"
135
143
 
136
144
  # then dump all non-primary key columns
137
- column_specs = columns.map do |column|
145
+ columns.each do |column|
138
146
  raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" unless @connection.valid_type?(column.type)
139
147
  next if column.name == pk
140
- @connection.column_spec(column)
141
- end.compact
142
-
143
- # find all migration keys used in this table
144
- keys = @connection.migration_keys
145
-
146
- # figure out the lengths for each column based on above keys
147
- lengths = keys.map { |key|
148
- column_specs.map { |spec|
149
- spec[key] ? spec[key].length + 2 : 0
150
- }.max
151
- }
152
-
153
- # the string we're going to sprintf our values against, with standardized column widths
154
- format_string = lengths.map{ |len| "%-#{len}s" }
155
-
156
- # find the max length for the 'type' column, which is special
157
- type_length = column_specs.map{ |column| column[:type].length }.max
158
-
159
- # add column type definition to our format string
160
- format_string.unshift " t.%-#{type_length}s "
161
-
162
- format_string *= ''
163
-
164
- column_specs.each do |colspec|
165
- values = keys.zip(lengths).map{ |key, len| colspec.key?(key) ? colspec[key] + ", " : " " * len }
166
- values.unshift colspec[:type]
167
- tbl.print((format_string % values).gsub(/,\s*$/, ''))
148
+ type, colspec = column_spec(column)
149
+ if type.is_a?(Symbol)
150
+ tbl.print " t.#{type} #{column.name.inspect}"
151
+ else
152
+ tbl.print " t.column #{column.name.inspect}, #{type.inspect}"
153
+ end
154
+ tbl.print ", #{format_colspec(colspec)}" if colspec.present?
168
155
  tbl.puts
169
156
  end
170
157
 
@@ -179,9 +166,9 @@ HEADER
179
166
  stream.puts "# Could not dump table #{table.inspect} because of following #{e.class}"
180
167
  stream.puts "# #{e.message}"
181
168
  stream.puts
169
+ ensure
170
+ self.table_name = nil
182
171
  end
183
-
184
- stream
185
172
  end
186
173
 
187
174
  # Keep it for indexing materialized views
@@ -189,7 +176,7 @@ HEADER
189
176
  if (indexes = @connection.indexes(table)).any?
190
177
  add_index_statements = indexes.map do |index|
191
178
  table_name = remove_prefix_and_suffix(index.table).inspect
192
- " add_index #{([table_name]+index_parts(index)).join(', ')}"
179
+ " add_index #{([table_name] + index_parts(index)).join(', ')}"
193
180
  end
194
181
 
195
182
  stream.puts add_index_statements.sort.join("\n")
@@ -212,10 +199,11 @@ HEADER
212
199
  "name: #{index.name.inspect}",
213
200
  ]
214
201
  index_parts << "unique: true" if index.unique
215
- index_parts << "length: { #{format_options(index.lengths)} }" if index.lengths.present?
216
- index_parts << "order: { #{format_options(index.orders)} }" if index.orders.present?
202
+ index_parts << "length: #{format_index_parts(index.lengths)}" if index.lengths.present?
203
+ index_parts << "order: #{format_index_parts(index.orders)}" if index.orders.present?
204
+ index_parts << "opclass: #{format_index_parts(index.opclasses)}" if index.opclasses.present?
217
205
  index_parts << "where: #{index.where.inspect}" if index.where
218
- index_parts << "using: #{index.using.inspect}" if index.using
206
+ index_parts << "using: #{index.using.inspect}" if !@connection.default_index_type?(index)
219
207
  index_parts << "type: #{index.type.inspect}" if index.type
220
208
  index_parts << "comment: #{index.comment.inspect}" if index.comment
221
209
  index_parts
@@ -237,7 +225,7 @@ HEADER
237
225
  parts << "primary_key: #{foreign_key.primary_key.inspect}"
238
226
  end
239
227
 
240
- if foreign_key.name !~ /^fk_rails_[0-9a-f]{10}$/
228
+ if foreign_key.export_name_on_schema_dump?
241
229
  parts << "name: #{foreign_key.name.inspect}"
242
230
  end
243
231
 
@@ -251,12 +239,26 @@ HEADER
251
239
  end
252
240
  end
253
241
 
242
+ def format_colspec(colspec)
243
+ colspec.map { |key, value| "#{key}: #{value}" }.join(", ")
244
+ end
245
+
254
246
  def format_options(options)
255
247
  options.map { |key, value| "#{key}: #{value.inspect}" }.join(", ")
256
248
  end
257
249
 
250
+ def format_index_parts(options)
251
+ if options.is_a?(Hash)
252
+ "{ #{format_options(options)} }"
253
+ else
254
+ options.inspect
255
+ end
256
+ end
257
+
258
258
  def remove_prefix_and_suffix(table)
259
- table.gsub(/^(#{@options[:table_name_prefix]})(.+)(#{@options[:table_name_suffix]})$/, "\\2")
259
+ prefix = Regexp.escape(@options[:table_name_prefix].to_s)
260
+ suffix = Regexp.escape(@options[:table_name_suffix].to_s)
261
+ table.sub(/\A#{prefix}(.+)#{suffix}\z/, "\\1")
260
262
  end
261
263
 
262
264
  def ignored?(table_name)
@@ -1,5 +1,7 @@
1
- require 'active_record/scoping/default'
2
- require 'active_record/scoping/named'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/scoping/default"
4
+ require "active_record/scoping/named"
3
5
 
4
6
  module ActiveRecord
5
7
  # This class is used to create a table that keeps track of which migrations
@@ -8,16 +10,20 @@ module ActiveRecord
8
10
  # to be executed the next time.
9
11
  class SchemaMigration < ActiveRecord::Base # :nodoc:
10
12
  class << self
13
+ def _internal?
14
+ true
15
+ end
16
+
11
17
  def primary_key
12
18
  "version"
13
19
  end
14
20
 
15
21
  def table_name
16
- "#{table_name_prefix}#{ActiveRecord::Base.schema_migrations_table_name}#{table_name_suffix}"
22
+ "#{table_name_prefix}#{schema_migrations_table_name}#{table_name_suffix}"
17
23
  end
18
24
 
19
25
  def table_exists?
20
- ActiveSupport::Deprecation.silence { connection.table_exists?(table_name) }
26
+ connection.table_exists?(table_name)
21
27
  end
22
28
 
23
29
  def create_table
@@ -39,7 +45,11 @@ module ActiveRecord
39
45
  end
40
46
 
41
47
  def normalized_versions
42
- pluck(:version).map { |v| normalize_migration_number v }
48
+ all_versions.map { |v| normalize_migration_number v }
49
+ end
50
+
51
+ def all_versions
52
+ order(:version).pluck(:version)
43
53
  end
44
54
  end
45
55
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Scoping
3
5
  module Default
@@ -5,11 +7,8 @@ module ActiveRecord
5
7
 
6
8
  included do
7
9
  # Stores the default scope for the class.
8
- class_attribute :default_scopes, instance_writer: false, instance_predicate: false
9
- class_attribute :default_scope_override, instance_writer: false, instance_predicate: false
10
-
11
- self.default_scopes = []
12
- self.default_scope_override = nil
10
+ class_attribute :default_scopes, instance_writer: false, instance_predicate: false, default: []
11
+ class_attribute :default_scope_override, instance_writer: false, instance_predicate: false, default: nil
13
12
  end
14
13
 
15
14
  module ClassMethods
@@ -44,109 +43,108 @@ module ActiveRecord
44
43
  self.current_scope = nil
45
44
  end
46
45
 
47
- protected
46
+ private
47
+
48
+ # Use this macro in your model to set a default scope for all operations on
49
+ # the model.
50
+ #
51
+ # class Article < ActiveRecord::Base
52
+ # default_scope { where(published: true) }
53
+ # end
54
+ #
55
+ # Article.all # => SELECT * FROM articles WHERE published = true
56
+ #
57
+ # The #default_scope is also applied while creating/building a record.
58
+ # It is not applied while updating a record.
59
+ #
60
+ # Article.new.published # => true
61
+ # Article.create.published # => true
62
+ #
63
+ # (You can also pass any object which responds to +call+ to the
64
+ # +default_scope+ macro, and it will be called when building the
65
+ # default scope.)
66
+ #
67
+ # If you use multiple #default_scope declarations in your model then
68
+ # they will be merged together:
69
+ #
70
+ # class Article < ActiveRecord::Base
71
+ # default_scope { where(published: true) }
72
+ # default_scope { where(rating: 'G') }
73
+ # end
74
+ #
75
+ # Article.all # => SELECT * FROM articles WHERE published = true AND rating = 'G'
76
+ #
77
+ # This is also the case with inheritance and module includes where the
78
+ # parent or module defines a #default_scope and the child or including
79
+ # class defines a second one.
80
+ #
81
+ # If you need to do more complex things with a default scope, you can
82
+ # alternatively define it as a class method:
83
+ #
84
+ # class Article < ActiveRecord::Base
85
+ # def self.default_scope
86
+ # # Should return a scope, you can call 'super' here etc.
87
+ # end
88
+ # end
89
+ def default_scope(scope = nil, &block) # :doc:
90
+ scope = block if block_given?
91
+
92
+ if scope.is_a?(Relation) || !scope.respond_to?(:call)
93
+ raise ArgumentError,
94
+ "Support for calling #default_scope without a block is removed. For example instead " \
95
+ "of `default_scope where(color: 'red')`, please use " \
96
+ "`default_scope { where(color: 'red') }`. (Alternatively you can just redefine " \
97
+ "self.default_scope.)"
98
+ end
48
99
 
49
- # Use this macro in your model to set a default scope for all operations on
50
- # the model.
51
- #
52
- # class Article < ActiveRecord::Base
53
- # default_scope { where(published: true) }
54
- # end
55
- #
56
- # Article.all # => SELECT * FROM articles WHERE published = true
57
- #
58
- # The #default_scope is also applied while creating/building a record.
59
- # It is not applied while updating a record.
60
- #
61
- # Article.new.published # => true
62
- # Article.create.published # => true
63
- #
64
- # (You can also pass any object which responds to +call+ to the
65
- # +default_scope+ macro, and it will be called when building the
66
- # default scope.)
67
- #
68
- # If you use multiple #default_scope declarations in your model then
69
- # they will be merged together:
70
- #
71
- # class Article < ActiveRecord::Base
72
- # default_scope { where(published: true) }
73
- # default_scope { where(rating: 'G') }
74
- # end
75
- #
76
- # Article.all # => SELECT * FROM articles WHERE published = true AND rating = 'G'
77
- #
78
- # This is also the case with inheritance and module includes where the
79
- # parent or module defines a #default_scope and the child or including
80
- # class defines a second one.
81
- #
82
- # If you need to do more complex things with a default scope, you can
83
- # alternatively define it as a class method:
84
- #
85
- # class Article < ActiveRecord::Base
86
- # def self.default_scope
87
- # # Should return a scope, you can call 'super' here etc.
88
- # end
89
- # end
90
- def default_scope(scope = nil)
91
- scope = Proc.new if block_given?
92
-
93
- if scope.is_a?(Relation) || !scope.respond_to?(:call)
94
- raise ArgumentError,
95
- "Support for calling #default_scope without a block is removed. For example instead " \
96
- "of `default_scope where(color: 'red')`, please use " \
97
- "`default_scope { where(color: 'red') }`. (Alternatively you can just redefine " \
98
- "self.default_scope.)"
100
+ self.default_scopes += [scope]
99
101
  end
100
102
 
101
- self.default_scopes += [scope]
102
- end
103
-
104
- def build_default_scope(base_rel = nil) # :nodoc:
105
- return if abstract_class?
103
+ def build_default_scope(relation = relation())
104
+ return if abstract_class?
106
105
 
107
- if self.default_scope_override.nil?
108
- self.default_scope_override = !Base.is_a?(method(:default_scope).owner)
109
- end
106
+ if default_scope_override.nil?
107
+ self.default_scope_override = !Base.is_a?(method(:default_scope).owner)
108
+ end
110
109
 
111
- if self.default_scope_override
112
- # The user has defined their own default scope method, so call that
113
- evaluate_default_scope do
114
- if scope = default_scope
115
- (base_rel ||= relation).merge(scope)
110
+ if default_scope_override
111
+ # The user has defined their own default scope method, so call that
112
+ evaluate_default_scope do
113
+ if scope = default_scope
114
+ relation.merge!(scope)
115
+ end
116
116
  end
117
- end
118
- elsif default_scopes.any?
119
- base_rel ||= relation
120
- evaluate_default_scope do
121
- default_scopes.inject(base_rel) do |default_scope, scope|
122
- scope = scope.respond_to?(:to_proc) ? scope : scope.method(:call)
123
- default_scope.merge(base_rel.instance_exec(&scope))
117
+ elsif default_scopes.any?
118
+ evaluate_default_scope do
119
+ default_scopes.inject(relation) do |default_scope, scope|
120
+ scope = scope.respond_to?(:to_proc) ? scope : scope.method(:call)
121
+ default_scope.instance_exec(&scope) || default_scope
122
+ end
124
123
  end
125
124
  end
126
125
  end
127
- end
128
126
 
129
- def ignore_default_scope? # :nodoc:
130
- ScopeRegistry.value_for(:ignore_default_scope, base_class)
131
- end
127
+ def ignore_default_scope?
128
+ ScopeRegistry.value_for(:ignore_default_scope, base_class)
129
+ end
132
130
 
133
- def ignore_default_scope=(ignore) # :nodoc:
134
- ScopeRegistry.set_value_for(:ignore_default_scope, base_class, ignore)
135
- end
131
+ def ignore_default_scope=(ignore)
132
+ ScopeRegistry.set_value_for(:ignore_default_scope, base_class, ignore)
133
+ end
136
134
 
137
- # The ignore_default_scope flag is used to prevent an infinite recursion
138
- # situation where a default scope references a scope which has a default
139
- # scope which references a scope...
140
- def evaluate_default_scope # :nodoc:
141
- return if ignore_default_scope?
142
-
143
- begin
144
- self.ignore_default_scope = true
145
- yield
146
- ensure
147
- self.ignore_default_scope = false
135
+ # The ignore_default_scope flag is used to prevent an infinite recursion
136
+ # situation where a default scope references a scope which has a default
137
+ # scope which references a scope...
138
+ def evaluate_default_scope
139
+ return if ignore_default_scope?
140
+
141
+ begin
142
+ self.ignore_default_scope = true
143
+ yield
144
+ ensure
145
+ self.ignore_default_scope = false
146
+ end
148
147
  end
149
- end
150
148
  end
151
149
  end
152
150
  end
@@ -1,6 +1,8 @@
1
- require 'active_support/core_ext/array'
2
- require 'active_support/core_ext/hash/except'
3
- require 'active_support/core_ext/kernel/singleton_class'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/array"
4
+ require "active_support/core_ext/hash/except"
5
+ require "active_support/core_ext/kernel/singleton_class"
4
6
 
5
7
  module ActiveRecord
6
8
  # = Active Record \Named \Scopes
@@ -22,17 +24,29 @@ module ActiveRecord
22
24
  # You can define a scope that applies to all finders using
23
25
  # {default_scope}[rdoc-ref:Scoping::Default::ClassMethods#default_scope].
24
26
  def all
25
- if current_scope
26
- current_scope.clone
27
+ scope = current_scope
28
+
29
+ if scope
30
+ if scope._deprecated_scope_source
31
+ ActiveSupport::Deprecation.warn(<<~MSG.squish)
32
+ Class level methods will no longer inherit scoping from `#{scope._deprecated_scope_source}`
33
+ in Rails 6.1. To continue using the scoped relation, pass it into the block directly.
34
+ To instead access the full set of models, as Rails 6.1 will, use `#{name}.unscoped`.
35
+ MSG
36
+ end
37
+
38
+ if self == scope.klass
39
+ scope.clone
40
+ else
41
+ relation.merge!(scope)
42
+ end
27
43
  else
28
44
  default_scoped
29
45
  end
30
46
  end
31
47
 
32
48
  def scope_for_association(scope = relation) # :nodoc:
33
- current_scope = self.current_scope
34
-
35
- if current_scope && current_scope.empty_scope?
49
+ if current_scope&.empty_scope?
36
50
  scope
37
51
  else
38
52
  default_scoped(scope)
@@ -44,7 +58,7 @@ module ActiveRecord
44
58
  end
45
59
 
46
60
  def default_extensions # :nodoc:
47
- if scope = current_scope || build_default_scope
61
+ if scope = scope_for_association || build_default_scope
48
62
  scope.extensions
49
63
  else
50
64
  []
@@ -54,7 +68,7 @@ module ActiveRecord
54
68
  # Adds a class method for retrieving and querying objects.
55
69
  # The method is intended to return an ActiveRecord::Relation
56
70
  # object, which is composable with other scopes.
57
- # If it returns nil or false, an
71
+ # If it returns +nil+ or +false+, an
58
72
  # {all}[rdoc-ref:Scoping::Named::ClassMethods#all] scope is returned instead.
59
73
  #
60
74
  # A \scope represents a narrowing of a database query, such as
@@ -154,7 +168,7 @@ module ActiveRecord
154
168
  # Article.featured.titles
155
169
  def scope(name, body, &block)
156
170
  unless body.respond_to?(:call)
157
- raise ArgumentError, 'The scope body needs to be callable.'
171
+ raise ArgumentError, "The scope body needs to be callable."
158
172
  end
159
173
 
160
174
  if dangerous_class_method?(name)
@@ -163,34 +177,40 @@ module ActiveRecord
163
177
  "a class method with the same name."
164
178
  end
165
179
 
180
+ if method_defined_within?(name, Relation)
181
+ raise ArgumentError, "You tried to define a scope named \"#{name}\" " \
182
+ "on the model \"#{self.name}\", but ActiveRecord::Relation already defined " \
183
+ "an instance method with the same name."
184
+ end
185
+
166
186
  valid_scope_name?(name)
167
187
  extension = Module.new(&block) if block
168
188
 
169
189
  if body.respond_to?(:to_proc)
170
- singleton_class.send(:define_method, name) do |*args|
171
- scope = all.scoping { instance_exec(*args, &body) }
190
+ singleton_class.define_method(name) do |*args|
191
+ scope = all._exec_scope(name, *args, &body)
172
192
  scope = scope.extending(extension) if extension
173
-
174
- scope || all
193
+ scope
175
194
  end
176
195
  else
177
- singleton_class.send(:define_method, name) do |*args|
178
- scope = all.scoping { body.call(*args) }
196
+ singleton_class.define_method(name) do |*args|
197
+ scope = body.call(*args) || all
179
198
  scope = scope.extending(extension) if extension
180
-
181
- scope || all
199
+ scope
182
200
  end
183
201
  end
202
+
203
+ generate_relation_method(name)
184
204
  end
185
205
 
186
- protected
206
+ private
187
207
 
188
- def valid_scope_name?(name)
189
- if respond_to?(name, true) && logger
190
- logger.warn "Creating scope :#{name}. " \
191
- "Overwriting existing method #{self.name}.#{name}."
208
+ def valid_scope_name?(name)
209
+ if respond_to?(name, true) && logger
210
+ logger.warn "Creating scope :#{name}. " \
211
+ "Overwriting existing method #{self.name}.#{name}."
212
+ end
192
213
  end
193
- end
194
214
  end
195
215
  end
196
216
  end