activerecord 5.0.7.2 → 6.0.6.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 (359) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +844 -1944
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +9 -7
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record/advisory_lock_base.rb +18 -0
  8. data/lib/active_record/aggregations.rb +249 -247
  9. data/lib/active_record/association_relation.rb +18 -14
  10. data/lib/active_record/associations/alias_tracker.rb +24 -34
  11. data/lib/active_record/associations/association.rb +113 -55
  12. data/lib/active_record/associations/association_scope.rb +102 -96
  13. data/lib/active_record/associations/belongs_to_association.rb +58 -42
  14. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  15. data/lib/active_record/associations/builder/association.rb +18 -25
  16. data/lib/active_record/associations/builder/belongs_to.rb +43 -54
  17. data/lib/active_record/associations/builder/collection_association.rb +7 -18
  18. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +41 -62
  19. data/lib/active_record/associations/builder/has_many.rb +4 -0
  20. data/lib/active_record/associations/builder/has_one.rb +37 -1
  21. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  22. data/lib/active_record/associations/collection_association.rb +93 -254
  23. data/lib/active_record/associations/collection_proxy.rb +159 -122
  24. data/lib/active_record/associations/foreign_association.rb +9 -0
  25. data/lib/active_record/associations/has_many_association.rb +23 -30
  26. data/lib/active_record/associations/has_many_through_association.rb +58 -44
  27. data/lib/active_record/associations/has_one_association.rb +59 -54
  28. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  29. data/lib/active_record/associations/join_dependency/join_association.rb +43 -85
  30. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  31. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  32. data/lib/active_record/associations/join_dependency.rb +152 -177
  33. data/lib/active_record/associations/preloader/association.rb +101 -97
  34. data/lib/active_record/associations/preloader/through_association.rb +77 -76
  35. data/lib/active_record/associations/preloader.rb +94 -103
  36. data/lib/active_record/associations/singular_association.rb +12 -45
  37. data/lib/active_record/associations/through_association.rb +27 -15
  38. data/lib/active_record/associations.rb +1603 -1592
  39. data/lib/active_record/attribute_assignment.rb +54 -61
  40. data/lib/active_record/attribute_decorators.rb +38 -17
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +12 -8
  42. data/lib/active_record/attribute_methods/dirty.rb +179 -109
  43. data/lib/active_record/attribute_methods/primary_key.rb +85 -92
  44. data/lib/active_record/attribute_methods/query.rb +4 -3
  45. data/lib/active_record/attribute_methods/read.rb +20 -49
  46. data/lib/active_record/attribute_methods/serialization.rb +29 -7
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -66
  48. data/lib/active_record/attribute_methods/write.rb +34 -33
  49. data/lib/active_record/attribute_methods.rb +66 -106
  50. data/lib/active_record/attributes.rb +38 -25
  51. data/lib/active_record/autosave_association.rb +58 -39
  52. data/lib/active_record/base.rb +27 -24
  53. data/lib/active_record/callbacks.rb +64 -35
  54. data/lib/active_record/coders/json.rb +2 -0
  55. data/lib/active_record/coders/yaml_column.rb +34 -13
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +558 -323
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +215 -94
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -35
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +128 -75
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -28
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +233 -147
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +400 -213
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -79
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +373 -202
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +401 -562
  69. data/lib/active_record/connection_adapters/column.rb +41 -13
  70. data/lib/active_record/connection_adapters/connection_specification.rb +172 -139
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
  72. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +137 -49
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -23
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +48 -30
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +19 -31
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -54
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  85. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -11
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +12 -2
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -18
  95. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  97. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  99. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  100. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +30 -9
  101. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -30
  102. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  103. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  104. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +8 -4
  105. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  107. data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +20 -26
  110. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  112. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +34 -32
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +378 -308
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +383 -275
  117. data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
  118. data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
  119. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
  123. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  126. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +261 -267
  127. data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
  128. data/lib/active_record/connection_handling.rb +143 -40
  129. data/lib/active_record/core.rb +207 -160
  130. data/lib/active_record/counter_cache.rb +60 -28
  131. data/lib/active_record/database_configurations/database_config.rb +37 -0
  132. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  133. data/lib/active_record/database_configurations/url_config.rb +78 -0
  134. data/lib/active_record/database_configurations.rb +233 -0
  135. data/lib/active_record/define_callbacks.rb +22 -0
  136. data/lib/active_record/dynamic_matchers.rb +87 -87
  137. data/lib/active_record/enum.rb +67 -23
  138. data/lib/active_record/errors.rb +114 -18
  139. data/lib/active_record/explain.rb +4 -4
  140. data/lib/active_record/explain_registry.rb +3 -1
  141. data/lib/active_record/explain_subscriber.rb +9 -4
  142. data/lib/active_record/fixture_set/file.rb +13 -8
  143. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  144. data/lib/active_record/fixture_set/render_context.rb +17 -0
  145. data/lib/active_record/fixture_set/table_row.rb +152 -0
  146. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  147. data/lib/active_record/fixtures.rb +194 -504
  148. data/lib/active_record/gem_version.rb +5 -3
  149. data/lib/active_record/inheritance.rb +150 -99
  150. data/lib/active_record/insert_all.rb +179 -0
  151. data/lib/active_record/integration.rb +116 -25
  152. data/lib/active_record/internal_metadata.rb +16 -19
  153. data/lib/active_record/legacy_yaml_adapter.rb +4 -2
  154. data/lib/active_record/locking/optimistic.rb +85 -86
  155. data/lib/active_record/locking/pessimistic.rb +18 -6
  156. data/lib/active_record/log_subscriber.rb +48 -29
  157. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  158. data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
  159. data/lib/active_record/middleware/database_selector.rb +74 -0
  160. data/lib/active_record/migration/command_recorder.rb +134 -100
  161. data/lib/active_record/migration/compatibility.rb +174 -56
  162. data/lib/active_record/migration/join_table.rb +8 -7
  163. data/lib/active_record/migration.rb +369 -302
  164. data/lib/active_record/model_schema.rb +160 -127
  165. data/lib/active_record/nested_attributes.rb +213 -202
  166. data/lib/active_record/no_touching.rb +12 -3
  167. data/lib/active_record/null_relation.rb +12 -34
  168. data/lib/active_record/persistence.rb +446 -77
  169. data/lib/active_record/query_cache.rb +13 -12
  170. data/lib/active_record/querying.rb +37 -24
  171. data/lib/active_record/railtie.rb +128 -36
  172. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  173. data/lib/active_record/railties/console_sandbox.rb +2 -0
  174. data/lib/active_record/railties/controller_runtime.rb +34 -33
  175. data/lib/active_record/railties/databases.rake +312 -177
  176. data/lib/active_record/readonly_attributes.rb +5 -4
  177. data/lib/active_record/reflection.rb +214 -254
  178. data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
  179. data/lib/active_record/relation/batches.rb +98 -52
  180. data/lib/active_record/relation/calculations.rb +212 -173
  181. data/lib/active_record/relation/delegation.rb +73 -69
  182. data/lib/active_record/relation/finder_methods.rb +207 -247
  183. data/lib/active_record/relation/from_clause.rb +6 -8
  184. data/lib/active_record/relation/merger.rb +82 -61
  185. data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
  186. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  187. data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
  188. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  189. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  190. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  191. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  192. data/lib/active_record/relation/predicate_builder.rb +83 -105
  193. data/lib/active_record/relation/query_attribute.rb +33 -2
  194. data/lib/active_record/relation/query_methods.rb +488 -332
  195. data/lib/active_record/relation/record_fetch_warning.rb +5 -3
  196. data/lib/active_record/relation/spawn_methods.rb +8 -8
  197. data/lib/active_record/relation/where_clause.rb +111 -96
  198. data/lib/active_record/relation/where_clause_factory.rb +6 -11
  199. data/lib/active_record/relation.rb +443 -318
  200. data/lib/active_record/result.rb +69 -40
  201. data/lib/active_record/runtime_registry.rb +5 -3
  202. data/lib/active_record/sanitization.rb +83 -99
  203. data/lib/active_record/schema.rb +7 -14
  204. data/lib/active_record/schema_dumper.rb +71 -69
  205. data/lib/active_record/schema_migration.rb +16 -6
  206. data/lib/active_record/scoping/default.rb +92 -95
  207. data/lib/active_record/scoping/named.rb +51 -26
  208. data/lib/active_record/scoping.rb +20 -20
  209. data/lib/active_record/secure_token.rb +4 -2
  210. data/lib/active_record/serialization.rb +2 -0
  211. data/lib/active_record/statement_cache.rb +63 -28
  212. data/lib/active_record/store.rb +121 -41
  213. data/lib/active_record/suppressor.rb +6 -3
  214. data/lib/active_record/table_metadata.rb +39 -18
  215. data/lib/active_record/tasks/database_tasks.rb +271 -81
  216. data/lib/active_record/tasks/mysql_database_tasks.rb +54 -91
  217. data/lib/active_record/tasks/postgresql_database_tasks.rb +77 -47
  218. data/lib/active_record/tasks/sqlite_database_tasks.rb +33 -16
  219. data/lib/active_record/test_databases.rb +23 -0
  220. data/lib/active_record/test_fixtures.rb +243 -0
  221. data/lib/active_record/timestamp.rb +70 -36
  222. data/lib/active_record/touch_later.rb +8 -6
  223. data/lib/active_record/transactions.rb +141 -157
  224. data/lib/active_record/translation.rb +3 -1
  225. data/lib/active_record/type/adapter_specific_registry.rb +44 -48
  226. data/lib/active_record/type/date.rb +2 -0
  227. data/lib/active_record/type/date_time.rb +2 -0
  228. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  229. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  230. data/lib/active_record/type/internal/timezone.rb +2 -0
  231. data/lib/active_record/type/json.rb +30 -0
  232. data/lib/active_record/type/serialized.rb +16 -9
  233. data/lib/active_record/type/text.rb +11 -0
  234. data/lib/active_record/type/time.rb +12 -1
  235. data/lib/active_record/type/type_map.rb +14 -17
  236. data/lib/active_record/type/unsigned_integer.rb +16 -0
  237. data/lib/active_record/type.rb +23 -18
  238. data/lib/active_record/type_caster/connection.rb +17 -12
  239. data/lib/active_record/type_caster/map.rb +5 -4
  240. data/lib/active_record/type_caster.rb +4 -2
  241. data/lib/active_record/validations/absence.rb +2 -0
  242. data/lib/active_record/validations/associated.rb +3 -2
  243. data/lib/active_record/validations/length.rb +2 -0
  244. data/lib/active_record/validations/presence.rb +4 -2
  245. data/lib/active_record/validations/uniqueness.rb +29 -42
  246. data/lib/active_record/validations.rb +7 -5
  247. data/lib/active_record/version.rb +3 -1
  248. data/lib/active_record.rb +37 -22
  249. data/lib/arel/alias_predication.rb +9 -0
  250. data/lib/arel/attributes/attribute.rb +37 -0
  251. data/lib/arel/attributes.rb +22 -0
  252. data/lib/arel/collectors/bind.rb +24 -0
  253. data/lib/arel/collectors/composite.rb +31 -0
  254. data/lib/arel/collectors/plain_string.rb +20 -0
  255. data/lib/arel/collectors/sql_string.rb +20 -0
  256. data/lib/arel/collectors/substitute_binds.rb +28 -0
  257. data/lib/arel/crud.rb +42 -0
  258. data/lib/arel/delete_manager.rb +18 -0
  259. data/lib/arel/errors.rb +9 -0
  260. data/lib/arel/expressions.rb +29 -0
  261. data/lib/arel/factory_methods.rb +49 -0
  262. data/lib/arel/insert_manager.rb +49 -0
  263. data/lib/arel/math.rb +45 -0
  264. data/lib/arel/nodes/and.rb +32 -0
  265. data/lib/arel/nodes/ascending.rb +23 -0
  266. data/lib/arel/nodes/binary.rb +52 -0
  267. data/lib/arel/nodes/bind_param.rb +36 -0
  268. data/lib/arel/nodes/case.rb +55 -0
  269. data/lib/arel/nodes/casted.rb +50 -0
  270. data/lib/arel/nodes/comment.rb +29 -0
  271. data/lib/arel/nodes/count.rb +12 -0
  272. data/lib/arel/nodes/delete_statement.rb +45 -0
  273. data/lib/arel/nodes/descending.rb +23 -0
  274. data/lib/arel/nodes/equality.rb +18 -0
  275. data/lib/arel/nodes/extract.rb +24 -0
  276. data/lib/arel/nodes/false.rb +16 -0
  277. data/lib/arel/nodes/full_outer_join.rb +8 -0
  278. data/lib/arel/nodes/function.rb +44 -0
  279. data/lib/arel/nodes/grouping.rb +8 -0
  280. data/lib/arel/nodes/in.rb +8 -0
  281. data/lib/arel/nodes/infix_operation.rb +80 -0
  282. data/lib/arel/nodes/inner_join.rb +8 -0
  283. data/lib/arel/nodes/insert_statement.rb +37 -0
  284. data/lib/arel/nodes/join_source.rb +20 -0
  285. data/lib/arel/nodes/matches.rb +18 -0
  286. data/lib/arel/nodes/named_function.rb +23 -0
  287. data/lib/arel/nodes/node.rb +50 -0
  288. data/lib/arel/nodes/node_expression.rb +13 -0
  289. data/lib/arel/nodes/outer_join.rb +8 -0
  290. data/lib/arel/nodes/over.rb +15 -0
  291. data/lib/arel/nodes/regexp.rb +16 -0
  292. data/lib/arel/nodes/right_outer_join.rb +8 -0
  293. data/lib/arel/nodes/select_core.rb +67 -0
  294. data/lib/arel/nodes/select_statement.rb +41 -0
  295. data/lib/arel/nodes/sql_literal.rb +16 -0
  296. data/lib/arel/nodes/string_join.rb +11 -0
  297. data/lib/arel/nodes/table_alias.rb +27 -0
  298. data/lib/arel/nodes/terminal.rb +16 -0
  299. data/lib/arel/nodes/true.rb +16 -0
  300. data/lib/arel/nodes/unary.rb +45 -0
  301. data/lib/arel/nodes/unary_operation.rb +20 -0
  302. data/lib/arel/nodes/unqualified_column.rb +22 -0
  303. data/lib/arel/nodes/update_statement.rb +41 -0
  304. data/lib/arel/nodes/values_list.rb +9 -0
  305. data/lib/arel/nodes/window.rb +126 -0
  306. data/lib/arel/nodes/with.rb +11 -0
  307. data/lib/arel/nodes.rb +68 -0
  308. data/lib/arel/order_predications.rb +13 -0
  309. data/lib/arel/predications.rb +256 -0
  310. data/lib/arel/select_manager.rb +271 -0
  311. data/lib/arel/table.rb +110 -0
  312. data/lib/arel/tree_manager.rb +72 -0
  313. data/lib/arel/update_manager.rb +34 -0
  314. data/lib/arel/visitors/depth_first.rb +203 -0
  315. data/lib/arel/visitors/dot.rb +296 -0
  316. data/lib/arel/visitors/ibm_db.rb +34 -0
  317. data/lib/arel/visitors/informix.rb +62 -0
  318. data/lib/arel/visitors/mssql.rb +156 -0
  319. data/lib/arel/visitors/mysql.rb +83 -0
  320. data/lib/arel/visitors/oracle.rb +158 -0
  321. data/lib/arel/visitors/oracle12.rb +65 -0
  322. data/lib/arel/visitors/postgresql.rb +109 -0
  323. data/lib/arel/visitors/sqlite.rb +38 -0
  324. data/lib/arel/visitors/to_sql.rb +888 -0
  325. data/lib/arel/visitors/visitor.rb +45 -0
  326. data/lib/arel/visitors/where_sql.rb +22 -0
  327. data/lib/arel/visitors.rb +20 -0
  328. data/lib/arel/window_predications.rb +9 -0
  329. data/lib/arel.rb +62 -0
  330. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -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 -3
  335. data/lib/rails/generators/active_record/model/model_generator.rb +9 -30
  336. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  337. data/lib/rails/generators/active_record.rb +7 -5
  338. metadata +138 -52
  339. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  340. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  341. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  342. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  343. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  344. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  345. data/lib/active_record/associations/preloader/singular_association.rb +0 -20
  346. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  347. data/lib/active_record/attribute.rb +0 -213
  348. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  349. data/lib/active_record/attribute_set/builder.rb +0 -132
  350. data/lib/active_record/attribute_set.rb +0 -110
  351. data/lib/active_record/collection_cache_key.rb +0 -50
  352. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  353. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  354. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  355. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  356. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  357. data/lib/active_record/type/internal/abstract_json.rb +0 -33
  358. /data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  359. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -1,6 +1,9 @@
1
- require 'active_support/core_ext/hash/except'
2
- require 'active_support/core_ext/object/try'
3
- require 'active_support/core_ext/hash/indifferent_access'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/except"
4
+ require "active_support/core_ext/module/redefine_method"
5
+ require "active_support/core_ext/object/try"
6
+ require "active_support/core_ext/hash/indifferent_access"
4
7
 
5
8
  module ActiveRecord
6
9
  module NestedAttributes #:nodoc:
@@ -10,8 +13,7 @@ module ActiveRecord
10
13
  extend ActiveSupport::Concern
11
14
 
12
15
  included do
13
- class_attribute :nested_attributes_options, instance_writer: false
14
- self.nested_attributes_options = {}
16
+ class_attribute :nested_attributes_options, instance_writer: false, default: {}
15
17
  end
16
18
 
17
19
  # = Active Record Nested Attributes
@@ -61,6 +63,18 @@ module ActiveRecord
61
63
  # member.update params[:member]
62
64
  # member.avatar.icon # => 'sad'
63
65
  #
66
+ # If you want to update the current avatar without providing the id, you must add <tt>:update_only</tt> option.
67
+ #
68
+ # class Member < ActiveRecord::Base
69
+ # has_one :avatar
70
+ # accepts_nested_attributes_for :avatar, update_only: true
71
+ # end
72
+ #
73
+ # params = { member: { avatar_attributes: { icon: 'sad' } } }
74
+ # member.update params[:member]
75
+ # member.avatar.id # => 2
76
+ # member.avatar.icon # => 'sad'
77
+ #
64
78
  # By default you will only be able to set and update attributes on the
65
79
  # associated model. If you want to destroy the associated model through the
66
80
  # attributes hash, you have to enable it first using the
@@ -267,7 +281,7 @@ module ActiveRecord
267
281
  # member.avatar_attributes = {icon: 'sad'}
268
282
  # member.avatar.width # => 200
269
283
  module ClassMethods
270
- REJECT_ALL_BLANK_PROC = proc { |attributes| attributes.all? { |key, value| key == '_destroy' || value.blank? } }
284
+ REJECT_ALL_BLANK_PROC = proc { |attributes| attributes.all? { |key, value| key == "_destroy" || value.blank? } }
271
285
 
272
286
  # Defines an attributes writer for the specified association(s).
273
287
  #
@@ -317,7 +331,7 @@ module ActiveRecord
317
331
  # # creates avatar_attributes= and posts_attributes=
318
332
  # accepts_nested_attributes_for :avatar, :posts, allow_destroy: true
319
333
  def accepts_nested_attributes_for(*attr_names)
320
- options = { :allow_destroy => false, :update_only => false }
334
+ options = { allow_destroy: false, update_only: false }
321
335
  options.update(attr_names.extract_options!)
322
336
  options.assert_valid_keys(:allow_destroy, :reject_if, :limit, :update_only)
323
337
  options[:reject_if] = REJECT_ALL_BLANK_PROC if options[:reject_if] == :all_blank
@@ -340,28 +354,25 @@ module ActiveRecord
340
354
  end
341
355
 
342
356
  private
343
-
344
- # Generates a writer method for this association. Serves as a point for
345
- # accessing the objects in the association. For example, this method
346
- # could generate the following:
347
- #
348
- # def pirate_attributes=(attributes)
349
- # assign_nested_attributes_for_one_to_one_association(:pirate, attributes)
350
- # end
351
- #
352
- # This redirects the attempts to write objects in an association through
353
- # the helper methods defined below. Makes it seem like the nested
354
- # associations are just regular associations.
355
- def generate_association_writer(association_name, type)
356
- generated_association_methods.module_eval <<-eoruby, __FILE__, __LINE__ + 1
357
- if method_defined?(:#{association_name}_attributes=)
358
- remove_method(:#{association_name}_attributes=)
359
- end
360
- def #{association_name}_attributes=(attributes)
361
- assign_nested_attributes_for_#{type}_association(:#{association_name}, attributes)
362
- end
363
- eoruby
364
- end
357
+ # Generates a writer method for this association. Serves as a point for
358
+ # accessing the objects in the association. For example, this method
359
+ # could generate the following:
360
+ #
361
+ # def pirate_attributes=(attributes)
362
+ # assign_nested_attributes_for_one_to_one_association(:pirate, attributes)
363
+ # end
364
+ #
365
+ # This redirects the attempts to write objects in an association through
366
+ # the helper methods defined below. Makes it seem like the nested
367
+ # associations are just regular associations.
368
+ def generate_association_writer(association_name, type)
369
+ generated_association_methods.module_eval <<-eoruby, __FILE__, __LINE__ + 1
370
+ silence_redefinition_of_method :#{association_name}_attributes=
371
+ def #{association_name}_attributes=(attributes)
372
+ assign_nested_attributes_for_#{type}_association(:#{association_name}, attributes)
373
+ end
374
+ eoruby
375
+ end
365
376
  end
366
377
 
367
378
  # Returns ActiveRecord::AutosaveAssociation::marked_for_destruction? It's
@@ -374,214 +385,214 @@ module ActiveRecord
374
385
  end
375
386
 
376
387
  private
388
+ # Attribute hash keys that should not be assigned as normal attributes.
389
+ # These hash keys are nested attributes implementation details.
390
+ UNASSIGNABLE_KEYS = %w( id _destroy )
377
391
 
378
- # Attribute hash keys that should not be assigned as normal attributes.
379
- # These hash keys are nested attributes implementation details.
380
- UNASSIGNABLE_KEYS = %w( id _destroy )
381
-
382
- # Assigns the given attributes to the association.
383
- #
384
- # If an associated record does not yet exist, one will be instantiated. If
385
- # an associated record already exists, the method's behavior depends on
386
- # the value of the update_only option. If update_only is +false+ and the
387
- # given attributes include an <tt>:id</tt> that matches the existing record's
388
- # id, then the existing record will be modified. If no <tt>:id</tt> is provided
389
- # it will be replaced with a new record. If update_only is +true+ the existing
390
- # record will be modified regardless of whether an <tt>:id</tt> is provided.
391
- #
392
- # If the given attributes include a matching <tt>:id</tt> attribute, or
393
- # update_only is true, and a <tt>:_destroy</tt> key set to a truthy value,
394
- # then the existing record will be marked for destruction.
395
- def assign_nested_attributes_for_one_to_one_association(association_name, attributes)
396
- options = self.nested_attributes_options[association_name]
397
- if attributes.respond_to?(:permitted?)
398
- attributes = attributes.to_h
399
- end
400
- attributes = attributes.with_indifferent_access
401
- existing_record = send(association_name)
392
+ # Assigns the given attributes to the association.
393
+ #
394
+ # If an associated record does not yet exist, one will be instantiated. If
395
+ # an associated record already exists, the method's behavior depends on
396
+ # the value of the update_only option. If update_only is +false+ and the
397
+ # given attributes include an <tt>:id</tt> that matches the existing record's
398
+ # id, then the existing record will be modified. If no <tt>:id</tt> is provided
399
+ # it will be replaced with a new record. If update_only is +true+ the existing
400
+ # record will be modified regardless of whether an <tt>:id</tt> is provided.
401
+ #
402
+ # If the given attributes include a matching <tt>:id</tt> attribute, or
403
+ # update_only is true, and a <tt>:_destroy</tt> key set to a truthy value,
404
+ # then the existing record will be marked for destruction.
405
+ def assign_nested_attributes_for_one_to_one_association(association_name, attributes)
406
+ options = nested_attributes_options[association_name]
407
+ if attributes.respond_to?(:permitted?)
408
+ attributes = attributes.to_h
409
+ end
410
+ attributes = attributes.with_indifferent_access
411
+ existing_record = send(association_name)
402
412
 
403
- if (options[:update_only] || !attributes['id'].blank?) && existing_record &&
404
- (options[:update_only] || existing_record.id.to_s == attributes['id'].to_s)
405
- assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy]) unless call_reject_if(association_name, attributes)
413
+ if (options[:update_only] || !attributes["id"].blank?) && existing_record &&
414
+ (options[:update_only] || existing_record.id.to_s == attributes["id"].to_s)
415
+ assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy]) unless call_reject_if(association_name, attributes)
406
416
 
407
- elsif attributes['id'].present?
408
- raise_nested_attributes_record_not_found!(association_name, attributes['id'])
417
+ elsif attributes["id"].present?
418
+ raise_nested_attributes_record_not_found!(association_name, attributes["id"])
409
419
 
410
- elsif !reject_new_record?(association_name, attributes)
411
- assignable_attributes = attributes.except(*UNASSIGNABLE_KEYS)
420
+ elsif !reject_new_record?(association_name, attributes)
421
+ assignable_attributes = attributes.except(*UNASSIGNABLE_KEYS)
412
422
 
413
- if existing_record && existing_record.new_record?
414
- existing_record.assign_attributes(assignable_attributes)
415
- association(association_name).initialize_attributes(existing_record)
416
- else
417
- method = "build_#{association_name}"
418
- if respond_to?(method)
419
- send(method, assignable_attributes)
423
+ if existing_record && existing_record.new_record?
424
+ existing_record.assign_attributes(assignable_attributes)
425
+ association(association_name).initialize_attributes(existing_record)
420
426
  else
421
- raise ArgumentError, "Cannot build association `#{association_name}'. Are you trying to build a polymorphic one-to-one association?"
427
+ method = :"build_#{association_name}"
428
+ if respond_to?(method)
429
+ send(method, assignable_attributes)
430
+ else
431
+ raise ArgumentError, "Cannot build association `#{association_name}'. Are you trying to build a polymorphic one-to-one association?"
432
+ end
422
433
  end
423
434
  end
424
435
  end
425
- end
426
436
 
427
- # Assigns the given attributes to the collection association.
428
- #
429
- # Hashes with an <tt>:id</tt> value matching an existing associated record
430
- # will update that record. Hashes without an <tt>:id</tt> value will build
431
- # a new record for the association. Hashes with a matching <tt>:id</tt>
432
- # value and a <tt>:_destroy</tt> key set to a truthy value will mark the
433
- # matched record for destruction.
434
- #
435
- # For example:
436
- #
437
- # assign_nested_attributes_for_collection_association(:people, {
438
- # '1' => { id: '1', name: 'Peter' },
439
- # '2' => { name: 'John' },
440
- # '3' => { id: '2', _destroy: true }
441
- # })
442
- #
443
- # Will update the name of the Person with ID 1, build a new associated
444
- # person with the name 'John', and mark the associated Person with ID 2
445
- # for destruction.
446
- #
447
- # Also accepts an Array of attribute hashes:
448
- #
449
- # assign_nested_attributes_for_collection_association(:people, [
450
- # { id: '1', name: 'Peter' },
451
- # { name: 'John' },
452
- # { id: '2', _destroy: true }
453
- # ])
454
- def assign_nested_attributes_for_collection_association(association_name, attributes_collection)
455
- options = self.nested_attributes_options[association_name]
456
- if attributes_collection.respond_to?(:permitted?)
457
- attributes_collection = attributes_collection.to_h
458
- end
437
+ # Assigns the given attributes to the collection association.
438
+ #
439
+ # Hashes with an <tt>:id</tt> value matching an existing associated record
440
+ # will update that record. Hashes without an <tt>:id</tt> value will build
441
+ # a new record for the association. Hashes with a matching <tt>:id</tt>
442
+ # value and a <tt>:_destroy</tt> key set to a truthy value will mark the
443
+ # matched record for destruction.
444
+ #
445
+ # For example:
446
+ #
447
+ # assign_nested_attributes_for_collection_association(:people, {
448
+ # '1' => { id: '1', name: 'Peter' },
449
+ # '2' => { name: 'John' },
450
+ # '3' => { id: '2', _destroy: true }
451
+ # })
452
+ #
453
+ # Will update the name of the Person with ID 1, build a new associated
454
+ # person with the name 'John', and mark the associated Person with ID 2
455
+ # for destruction.
456
+ #
457
+ # Also accepts an Array of attribute hashes:
458
+ #
459
+ # assign_nested_attributes_for_collection_association(:people, [
460
+ # { id: '1', name: 'Peter' },
461
+ # { name: 'John' },
462
+ # { id: '2', _destroy: true }
463
+ # ])
464
+ def assign_nested_attributes_for_collection_association(association_name, attributes_collection)
465
+ options = nested_attributes_options[association_name]
466
+ if attributes_collection.respond_to?(:permitted?)
467
+ attributes_collection = attributes_collection.to_h
468
+ end
459
469
 
460
- unless attributes_collection.is_a?(Hash) || attributes_collection.is_a?(Array)
461
- raise ArgumentError, "Hash or Array expected, got #{attributes_collection.class.name} (#{attributes_collection.inspect})"
462
- end
470
+ unless attributes_collection.is_a?(Hash) || attributes_collection.is_a?(Array)
471
+ raise ArgumentError, "Hash or Array expected for attribute `#{association_name}`, got #{attributes_collection.class.name} (#{attributes_collection.inspect})"
472
+ end
463
473
 
464
- check_record_limit!(options[:limit], attributes_collection)
474
+ check_record_limit!(options[:limit], attributes_collection)
465
475
 
466
- if attributes_collection.is_a? Hash
467
- keys = attributes_collection.keys
468
- attributes_collection = if keys.include?('id') || keys.include?(:id)
469
- [attributes_collection]
470
- else
471
- attributes_collection.values
476
+ if attributes_collection.is_a? Hash
477
+ keys = attributes_collection.keys
478
+ attributes_collection = if keys.include?("id") || keys.include?(:id)
479
+ [attributes_collection]
480
+ else
481
+ attributes_collection.values
482
+ end
472
483
  end
473
- end
474
-
475
- association = association(association_name)
476
484
 
477
- existing_records = if association.loaded?
478
- association.target
479
- else
480
- attribute_ids = attributes_collection.map {|a| a['id'] || a[:id] }.compact
481
- attribute_ids.empty? ? [] : association.scope.where(association.klass.primary_key => attribute_ids)
482
- end
485
+ association = association(association_name)
483
486
 
484
- attributes_collection.each do |attributes|
485
- if attributes.respond_to?(:permitted?)
486
- attributes = attributes.to_h
487
+ existing_records = if association.loaded?
488
+ association.target
489
+ else
490
+ attribute_ids = attributes_collection.map { |a| a["id"] || a[:id] }.compact
491
+ attribute_ids.empty? ? [] : association.scope.where(association.klass.primary_key => attribute_ids)
487
492
  end
488
- attributes = attributes.with_indifferent_access
489
493
 
490
- if attributes['id'].blank?
491
- unless reject_new_record?(association_name, attributes)
492
- association.build(attributes.except(*UNASSIGNABLE_KEYS))
494
+ attributes_collection.each do |attributes|
495
+ if attributes.respond_to?(:permitted?)
496
+ attributes = attributes.to_h
493
497
  end
494
- elsif existing_record = existing_records.detect { |record| record.id.to_s == attributes['id'].to_s }
495
- unless call_reject_if(association_name, attributes)
496
- # Make sure we are operating on the actual object which is in the association's
497
- # proxy_target array (either by finding it, or adding it if not found)
498
- # Take into account that the proxy_target may have changed due to callbacks
499
- target_record = association.target.detect { |record| record.id.to_s == attributes['id'].to_s }
500
- if target_record
501
- existing_record = target_record
502
- else
503
- association.add_to_target(existing_record, :skip_callbacks)
504
- end
498
+ attributes = attributes.with_indifferent_access
505
499
 
506
- assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
500
+ if attributes["id"].blank?
501
+ unless reject_new_record?(association_name, attributes)
502
+ association.reader.build(attributes.except(*UNASSIGNABLE_KEYS))
503
+ end
504
+ elsif existing_record = existing_records.detect { |record| record.id.to_s == attributes["id"].to_s }
505
+ unless call_reject_if(association_name, attributes)
506
+ # Make sure we are operating on the actual object which is in the association's
507
+ # proxy_target array (either by finding it, or adding it if not found)
508
+ # Take into account that the proxy_target may have changed due to callbacks
509
+ target_record = association.target.detect { |record| record.id.to_s == attributes["id"].to_s }
510
+ if target_record
511
+ existing_record = target_record
512
+ else
513
+ association.add_to_target(existing_record, :skip_callbacks)
514
+ end
515
+
516
+ assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
517
+ end
518
+ else
519
+ raise_nested_attributes_record_not_found!(association_name, attributes["id"])
507
520
  end
508
- else
509
- raise_nested_attributes_record_not_found!(association_name, attributes['id'])
510
521
  end
511
522
  end
512
- end
513
523
 
514
- # Takes in a limit and checks if the attributes_collection has too many
515
- # records. It accepts limit in the form of symbol, proc, or
516
- # number-like object (anything that can be compared with an integer).
517
- #
518
- # Raises TooManyRecords error if the attributes_collection is
519
- # larger than the limit.
520
- def check_record_limit!(limit, attributes_collection)
521
- if limit
522
- limit = case limit
523
- when Symbol
524
- send(limit)
525
- when Proc
526
- limit.call
527
- else
528
- limit
529
- end
524
+ # Takes in a limit and checks if the attributes_collection has too many
525
+ # records. It accepts limit in the form of symbol, proc, or
526
+ # number-like object (anything that can be compared with an integer).
527
+ #
528
+ # Raises TooManyRecords error if the attributes_collection is
529
+ # larger than the limit.
530
+ def check_record_limit!(limit, attributes_collection)
531
+ if limit
532
+ limit = \
533
+ case limit
534
+ when Symbol
535
+ send(limit)
536
+ when Proc
537
+ limit.call
538
+ else
539
+ limit
540
+ end
530
541
 
531
- if limit && attributes_collection.size > limit
532
- raise TooManyRecords, "Maximum #{limit} records are allowed. Got #{attributes_collection.size} records instead."
542
+ if limit && attributes_collection.size > limit
543
+ raise TooManyRecords, "Maximum #{limit} records are allowed. Got #{attributes_collection.size} records instead."
544
+ end
533
545
  end
534
546
  end
535
- end
536
547
 
537
- # Updates a record with the +attributes+ or marks it for destruction if
538
- # +allow_destroy+ is +true+ and has_destroy_flag? returns +true+.
539
- def assign_to_or_mark_for_destruction(record, attributes, allow_destroy)
540
- record.assign_attributes(attributes.except(*UNASSIGNABLE_KEYS))
541
- record.mark_for_destruction if has_destroy_flag?(attributes) && allow_destroy
542
- end
548
+ # Updates a record with the +attributes+ or marks it for destruction if
549
+ # +allow_destroy+ is +true+ and has_destroy_flag? returns +true+.
550
+ def assign_to_or_mark_for_destruction(record, attributes, allow_destroy)
551
+ record.assign_attributes(attributes.except(*UNASSIGNABLE_KEYS))
552
+ record.mark_for_destruction if has_destroy_flag?(attributes) && allow_destroy
553
+ end
543
554
 
544
- # Determines if a hash contains a truthy _destroy key.
545
- def has_destroy_flag?(hash)
546
- Type::Boolean.new.cast(hash['_destroy'])
547
- end
555
+ # Determines if a hash contains a truthy _destroy key.
556
+ def has_destroy_flag?(hash)
557
+ Type::Boolean.new.cast(hash["_destroy"])
558
+ end
548
559
 
549
- # Determines if a new record should be rejected by checking
550
- # has_destroy_flag? or if a <tt>:reject_if</tt> proc exists for this
551
- # association and evaluates to +true+.
552
- def reject_new_record?(association_name, attributes)
553
- will_be_destroyed?(association_name, attributes) || call_reject_if(association_name, attributes)
554
- end
560
+ # Determines if a new record should be rejected by checking
561
+ # has_destroy_flag? or if a <tt>:reject_if</tt> proc exists for this
562
+ # association and evaluates to +true+.
563
+ def reject_new_record?(association_name, attributes)
564
+ will_be_destroyed?(association_name, attributes) || call_reject_if(association_name, attributes)
565
+ end
555
566
 
556
- # Determines if a record with the particular +attributes+ should be
557
- # rejected by calling the reject_if Symbol or Proc (if defined).
558
- # The reject_if option is defined by +accepts_nested_attributes_for+.
559
- #
560
- # Returns false if there is a +destroy_flag+ on the attributes.
561
- def call_reject_if(association_name, attributes)
562
- return false if will_be_destroyed?(association_name, attributes)
567
+ # Determines if a record with the particular +attributes+ should be
568
+ # rejected by calling the reject_if Symbol or Proc (if defined).
569
+ # The reject_if option is defined by +accepts_nested_attributes_for+.
570
+ #
571
+ # Returns false if there is a +destroy_flag+ on the attributes.
572
+ def call_reject_if(association_name, attributes)
573
+ return false if will_be_destroyed?(association_name, attributes)
563
574
 
564
- case callback = self.nested_attributes_options[association_name][:reject_if]
565
- when Symbol
566
- method(callback).arity == 0 ? send(callback) : send(callback, attributes)
567
- when Proc
568
- callback.call(attributes)
575
+ case callback = nested_attributes_options[association_name][:reject_if]
576
+ when Symbol
577
+ method(callback).arity == 0 ? send(callback) : send(callback, attributes)
578
+ when Proc
579
+ callback.call(attributes)
580
+ end
569
581
  end
570
- end
571
582
 
572
- # Only take into account the destroy flag if <tt>:allow_destroy</tt> is true
573
- def will_be_destroyed?(association_name, attributes)
574
- allow_destroy?(association_name) && has_destroy_flag?(attributes)
575
- end
583
+ # Only take into account the destroy flag if <tt>:allow_destroy</tt> is true
584
+ def will_be_destroyed?(association_name, attributes)
585
+ allow_destroy?(association_name) && has_destroy_flag?(attributes)
586
+ end
576
587
 
577
- def allow_destroy?(association_name)
578
- self.nested_attributes_options[association_name][:allow_destroy]
579
- end
588
+ def allow_destroy?(association_name)
589
+ nested_attributes_options[association_name][:allow_destroy]
590
+ end
580
591
 
581
- def raise_nested_attributes_record_not_found!(association_name, record_id)
582
- model = self.class._reflect_on_association(association_name).klass.name
583
- raise RecordNotFound.new("Couldn't find #{model} with ID=#{record_id} for #{self.class.name} with ID=#{id}",
584
- model, 'id', record_id)
585
- end
592
+ def raise_nested_attributes_record_not_found!(association_name, record_id)
593
+ model = self.class._reflect_on_association(association_name).klass.name
594
+ raise RecordNotFound.new("Couldn't find #{model} with ID=#{record_id} for #{self.class.name} with ID=#{id}",
595
+ model, "id", record_id)
596
+ end
586
597
  end
587
598
  end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # = Active Record No Touching
3
5
  module NoTouching
4
6
  extend ActiveSupport::Concern
5
7
 
6
8
  module ClassMethods
7
- # Lets you selectively disable calls to `touch` for the
9
+ # Lets you selectively disable calls to +touch+ for the
8
10
  # duration of a block.
9
11
  #
10
12
  # ==== Examples
@@ -41,15 +43,22 @@ module ActiveRecord
41
43
  end
42
44
  end
43
45
 
46
+ # Returns +true+ if the class has +no_touching+ set, +false+ otherwise.
47
+ #
48
+ # Project.no_touching do
49
+ # Project.first.no_touching? # true
50
+ # Message.first.no_touching? # false
51
+ # end
52
+ #
44
53
  def no_touching?
45
54
  NoTouching.applied_to?(self.class)
46
55
  end
47
56
 
48
- def touch_later(*) # :nodoc:
57
+ def touch_later(*, **) # :nodoc:
49
58
  super unless no_touching?
50
59
  end
51
60
 
52
- def touch(*) # :nodoc:
61
+ def touch(*, **) # :nodoc:
53
62
  super unless no_touching?
54
63
  end
55
64
  end
@@ -1,14 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module NullRelation # :nodoc:
3
- def exec_queries
4
- @records = [].freeze
5
- end
6
-
7
5
  def pluck(*column_names)
8
6
  []
9
7
  end
10
8
 
11
- def delete_all(_conditions = nil)
9
+ def delete_all
12
10
  0
13
11
  end
14
12
 
@@ -20,10 +18,6 @@ module ActiveRecord
20
18
  0
21
19
  end
22
20
 
23
- def size
24
- calculate :size, nil
25
- end
26
-
27
21
  def empty?
28
22
  true
29
23
  end
@@ -48,33 +42,12 @@ module ActiveRecord
48
42
  ""
49
43
  end
50
44
 
51
- def count(*)
52
- calculate :count, nil
53
- end
54
-
55
- def sum(*)
56
- calculate :sum, nil
57
- end
58
-
59
- def average(*)
60
- calculate :average, nil
61
- end
62
-
63
- def minimum(*)
64
- calculate :minimum, nil
65
- end
66
-
67
- def maximum(*)
68
- calculate :maximum, nil
69
- end
70
-
71
45
  def calculate(operation, _column_name)
72
- if [:count, :sum, :size].include? operation
46
+ case operation
47
+ when :count, :sum
73
48
  group_values.any? ? Hash.new : 0
74
- elsif [:average, :minimum, :maximum].include?(operation) && group_values.any?
75
- Hash.new
76
- else
77
- nil
49
+ when :average, :minimum, :maximum
50
+ group_values.any? ? Hash.new : nil
78
51
  end
79
52
  end
80
53
 
@@ -85,5 +58,10 @@ module ActiveRecord
85
58
  def or(other)
86
59
  other.spawn
87
60
  end
61
+
62
+ private
63
+ def exec_queries
64
+ @records = [].freeze
65
+ end
88
66
  end
89
67
  end