activerecord 4.2.11.1 → 6.0.3.5

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 (373) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +721 -1522
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +14 -13
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/advisory_lock_base.rb +18 -0
  8. data/lib/active_record/aggregations.rb +266 -251
  9. data/lib/active_record/association_relation.rb +20 -13
  10. data/lib/active_record/associations/alias_tracker.rb +29 -36
  11. data/lib/active_record/associations/association.rb +128 -57
  12. data/lib/active_record/associations/association_scope.rb +103 -132
  13. data/lib/active_record/associations/belongs_to_association.rb +65 -60
  14. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  15. data/lib/active_record/associations/builder/association.rb +27 -40
  16. data/lib/active_record/associations/builder/belongs_to.rb +69 -55
  17. data/lib/active_record/associations/builder/collection_association.rb +10 -33
  18. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +50 -66
  19. data/lib/active_record/associations/builder/has_many.rb +8 -4
  20. data/lib/active_record/associations/builder/has_one.rb +46 -5
  21. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  22. data/lib/active_record/associations/collection_association.rb +136 -288
  23. data/lib/active_record/associations/collection_proxy.rb +241 -147
  24. data/lib/active_record/associations/foreign_association.rb +10 -1
  25. data/lib/active_record/associations/has_many_association.rb +34 -98
  26. data/lib/active_record/associations/has_many_through_association.rb +60 -87
  27. data/lib/active_record/associations/has_one_association.rb +61 -49
  28. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  29. data/lib/active_record/associations/join_dependency/join_association.rb +38 -86
  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 +149 -166
  33. data/lib/active_record/associations/preloader/association.rb +90 -123
  34. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  35. data/lib/active_record/associations/preloader.rb +90 -93
  36. data/lib/active_record/associations/singular_association.rb +18 -39
  37. data/lib/active_record/associations/through_association.rb +38 -18
  38. data/lib/active_record/associations.rb +1737 -1597
  39. data/lib/active_record/attribute_assignment.rb +57 -185
  40. data/lib/active_record/attribute_decorators.rb +39 -17
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -9
  42. data/lib/active_record/attribute_methods/dirty.rb +174 -144
  43. data/lib/active_record/attribute_methods/primary_key.rb +90 -84
  44. data/lib/active_record/attribute_methods/query.rb +6 -5
  45. data/lib/active_record/attribute_methods/read.rb +20 -77
  46. data/lib/active_record/attribute_methods/serialization.rb +40 -21
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +57 -37
  48. data/lib/active_record/attribute_methods/write.rb +32 -55
  49. data/lib/active_record/attribute_methods.rb +120 -135
  50. data/lib/active_record/attributes.rb +213 -82
  51. data/lib/active_record/autosave_association.rb +97 -41
  52. data/lib/active_record/base.rb +57 -45
  53. data/lib/active_record/callbacks.rb +101 -76
  54. data/lib/active_record/coders/json.rb +3 -1
  55. data/lib/active_record/coders/yaml_column.rb +23 -12
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +804 -297
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +240 -115
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +83 -24
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +170 -53
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -47
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +371 -242
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +694 -256
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +190 -83
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +473 -202
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +507 -639
  69. data/lib/active_record/connection_adapters/column.rb +56 -43
  70. data/lib/active_record/connection_adapters/connection_specification.rb +174 -153
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +196 -0
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +71 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +58 -181
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +70 -114
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +49 -58
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  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 +4 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -22
  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 +31 -20
  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 -9
  99. data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
  100. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
  101. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +51 -34
  102. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
  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 +9 -5
  105. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  106. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +144 -47
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  110. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  112. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +49 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +462 -296
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +558 -356
  117. data/lib/active_record/connection_adapters/schema_cache.rb +72 -25
  118. data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
  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 +21 -0
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
  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 +299 -349
  127. data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
  128. data/lib/active_record/connection_handling.rb +167 -41
  129. data/lib/active_record/core.rb +252 -230
  130. data/lib/active_record/counter_cache.rb +70 -49
  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 -106
  137. data/lib/active_record/enum.rb +163 -86
  138. data/lib/active_record/errors.rb +188 -53
  139. data/lib/active_record/explain.rb +22 -11
  140. data/lib/active_record/explain_registry.rb +4 -2
  141. data/lib/active_record/explain_subscriber.rb +10 -5
  142. data/lib/active_record/fixture_set/file.rb +35 -9
  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 +227 -501
  148. data/lib/active_record/gem_version.rb +6 -4
  149. data/lib/active_record/inheritance.rb +158 -115
  150. data/lib/active_record/insert_all.rb +179 -0
  151. data/lib/active_record/integration.rb +123 -29
  152. data/lib/active_record/internal_metadata.rb +53 -0
  153. data/lib/active_record/legacy_yaml_adapter.rb +21 -3
  154. data/lib/active_record/locale/en.yml +3 -2
  155. data/lib/active_record/locking/optimistic.rb +86 -96
  156. data/lib/active_record/locking/pessimistic.rb +18 -6
  157. data/lib/active_record/log_subscriber.rb +76 -33
  158. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  159. data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
  160. data/lib/active_record/middleware/database_selector.rb +74 -0
  161. data/lib/active_record/migration/command_recorder.rb +166 -91
  162. data/lib/active_record/migration/compatibility.rb +244 -0
  163. data/lib/active_record/migration/join_table.rb +8 -7
  164. data/lib/active_record/migration.rb +623 -305
  165. data/lib/active_record/model_schema.rb +313 -112
  166. data/lib/active_record/nested_attributes.rb +263 -223
  167. data/lib/active_record/no_touching.rb +15 -2
  168. data/lib/active_record/null_relation.rb +24 -38
  169. data/lib/active_record/persistence.rb +557 -126
  170. data/lib/active_record/query_cache.rb +19 -23
  171. data/lib/active_record/querying.rb +44 -30
  172. data/lib/active_record/railtie.rb +143 -44
  173. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  174. data/lib/active_record/railties/console_sandbox.rb +2 -0
  175. data/lib/active_record/railties/controller_runtime.rb +34 -33
  176. data/lib/active_record/railties/databases.rake +331 -185
  177. data/lib/active_record/readonly_attributes.rb +5 -4
  178. data/lib/active_record/reflection.rb +430 -281
  179. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  180. data/lib/active_record/relation/batches.rb +206 -55
  181. data/lib/active_record/relation/calculations.rb +268 -254
  182. data/lib/active_record/relation/delegation.rb +75 -84
  183. data/lib/active_record/relation/finder_methods.rb +285 -241
  184. data/lib/active_record/relation/from_clause.rb +30 -0
  185. data/lib/active_record/relation/merger.rb +78 -88
  186. data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -26
  187. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  188. data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
  189. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  190. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  191. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  192. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  193. data/lib/active_record/relation/predicate_builder.rb +110 -119
  194. data/lib/active_record/relation/query_attribute.rb +50 -0
  195. data/lib/active_record/relation/query_methods.rb +603 -397
  196. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  197. data/lib/active_record/relation/spawn_methods.rb +11 -14
  198. data/lib/active_record/relation/where_clause.rb +189 -0
  199. data/lib/active_record/relation/where_clause_factory.rb +33 -0
  200. data/lib/active_record/relation.rb +530 -341
  201. data/lib/active_record/result.rb +79 -43
  202. data/lib/active_record/runtime_registry.rb +6 -4
  203. data/lib/active_record/sanitization.rb +144 -121
  204. data/lib/active_record/schema.rb +21 -24
  205. data/lib/active_record/schema_dumper.rb +112 -93
  206. data/lib/active_record/schema_migration.rb +24 -17
  207. data/lib/active_record/scoping/default.rb +98 -83
  208. data/lib/active_record/scoping/named.rb +86 -33
  209. data/lib/active_record/scoping.rb +45 -27
  210. data/lib/active_record/secure_token.rb +40 -0
  211. data/lib/active_record/serialization.rb +5 -5
  212. data/lib/active_record/statement_cache.rb +73 -36
  213. data/lib/active_record/store.rb +127 -42
  214. data/lib/active_record/suppressor.rb +61 -0
  215. data/lib/active_record/table_metadata.rb +90 -0
  216. data/lib/active_record/tasks/database_tasks.rb +307 -100
  217. data/lib/active_record/tasks/mysql_database_tasks.rb +55 -100
  218. data/lib/active_record/tasks/postgresql_database_tasks.rb +80 -41
  219. data/lib/active_record/tasks/sqlite_database_tasks.rb +37 -16
  220. data/lib/active_record/test_databases.rb +23 -0
  221. data/lib/active_record/test_fixtures.rb +225 -0
  222. data/lib/active_record/timestamp.rb +86 -41
  223. data/lib/active_record/touch_later.rb +65 -0
  224. data/lib/active_record/transactions.rb +223 -157
  225. data/lib/active_record/translation.rb +3 -1
  226. data/lib/active_record/type/adapter_specific_registry.rb +126 -0
  227. data/lib/active_record/type/date.rb +4 -45
  228. data/lib/active_record/type/date_time.rb +4 -49
  229. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  230. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  231. data/lib/active_record/type/internal/timezone.rb +17 -0
  232. data/lib/active_record/type/json.rb +30 -0
  233. data/lib/active_record/type/serialized.rb +23 -15
  234. data/lib/active_record/type/text.rb +2 -2
  235. data/lib/active_record/type/time.rb +11 -16
  236. data/lib/active_record/type/type_map.rb +16 -19
  237. data/lib/active_record/type/unsigned_integer.rb +9 -8
  238. data/lib/active_record/type.rb +77 -23
  239. data/lib/active_record/type_caster/connection.rb +34 -0
  240. data/lib/active_record/type_caster/map.rb +20 -0
  241. data/lib/active_record/type_caster.rb +9 -0
  242. data/lib/active_record/validations/absence.rb +25 -0
  243. data/lib/active_record/validations/associated.rb +12 -4
  244. data/lib/active_record/validations/length.rb +26 -0
  245. data/lib/active_record/validations/presence.rb +14 -13
  246. data/lib/active_record/validations/uniqueness.rb +42 -55
  247. data/lib/active_record/validations.rb +38 -35
  248. data/lib/active_record/version.rb +3 -1
  249. data/lib/active_record.rb +42 -22
  250. data/lib/arel/alias_predication.rb +9 -0
  251. data/lib/arel/attributes/attribute.rb +37 -0
  252. data/lib/arel/attributes.rb +22 -0
  253. data/lib/arel/collectors/bind.rb +24 -0
  254. data/lib/arel/collectors/composite.rb +31 -0
  255. data/lib/arel/collectors/plain_string.rb +20 -0
  256. data/lib/arel/collectors/sql_string.rb +20 -0
  257. data/lib/arel/collectors/substitute_binds.rb +28 -0
  258. data/lib/arel/crud.rb +42 -0
  259. data/lib/arel/delete_manager.rb +18 -0
  260. data/lib/arel/errors.rb +9 -0
  261. data/lib/arel/expressions.rb +29 -0
  262. data/lib/arel/factory_methods.rb +49 -0
  263. data/lib/arel/insert_manager.rb +49 -0
  264. data/lib/arel/math.rb +45 -0
  265. data/lib/arel/nodes/and.rb +32 -0
  266. data/lib/arel/nodes/ascending.rb +23 -0
  267. data/lib/arel/nodes/binary.rb +52 -0
  268. data/lib/arel/nodes/bind_param.rb +36 -0
  269. data/lib/arel/nodes/case.rb +55 -0
  270. data/lib/arel/nodes/casted.rb +50 -0
  271. data/lib/arel/nodes/comment.rb +29 -0
  272. data/lib/arel/nodes/count.rb +12 -0
  273. data/lib/arel/nodes/delete_statement.rb +45 -0
  274. data/lib/arel/nodes/descending.rb +23 -0
  275. data/lib/arel/nodes/equality.rb +18 -0
  276. data/lib/arel/nodes/extract.rb +24 -0
  277. data/lib/arel/nodes/false.rb +16 -0
  278. data/lib/arel/nodes/full_outer_join.rb +8 -0
  279. data/lib/arel/nodes/function.rb +44 -0
  280. data/lib/arel/nodes/grouping.rb +8 -0
  281. data/lib/arel/nodes/in.rb +8 -0
  282. data/lib/arel/nodes/infix_operation.rb +80 -0
  283. data/lib/arel/nodes/inner_join.rb +8 -0
  284. data/lib/arel/nodes/insert_statement.rb +37 -0
  285. data/lib/arel/nodes/join_source.rb +20 -0
  286. data/lib/arel/nodes/matches.rb +18 -0
  287. data/lib/arel/nodes/named_function.rb +23 -0
  288. data/lib/arel/nodes/node.rb +50 -0
  289. data/lib/arel/nodes/node_expression.rb +13 -0
  290. data/lib/arel/nodes/outer_join.rb +8 -0
  291. data/lib/arel/nodes/over.rb +15 -0
  292. data/lib/arel/nodes/regexp.rb +16 -0
  293. data/lib/arel/nodes/right_outer_join.rb +8 -0
  294. data/lib/arel/nodes/select_core.rb +67 -0
  295. data/lib/arel/nodes/select_statement.rb +41 -0
  296. data/lib/arel/nodes/sql_literal.rb +16 -0
  297. data/lib/arel/nodes/string_join.rb +11 -0
  298. data/lib/arel/nodes/table_alias.rb +27 -0
  299. data/lib/arel/nodes/terminal.rb +16 -0
  300. data/lib/arel/nodes/true.rb +16 -0
  301. data/lib/arel/nodes/unary.rb +45 -0
  302. data/lib/arel/nodes/unary_operation.rb +20 -0
  303. data/lib/arel/nodes/unqualified_column.rb +22 -0
  304. data/lib/arel/nodes/update_statement.rb +41 -0
  305. data/lib/arel/nodes/values_list.rb +9 -0
  306. data/lib/arel/nodes/window.rb +126 -0
  307. data/lib/arel/nodes/with.rb +11 -0
  308. data/lib/arel/nodes.rb +68 -0
  309. data/lib/arel/order_predications.rb +13 -0
  310. data/lib/arel/predications.rb +256 -0
  311. data/lib/arel/select_manager.rb +271 -0
  312. data/lib/arel/table.rb +110 -0
  313. data/lib/arel/tree_manager.rb +72 -0
  314. data/lib/arel/update_manager.rb +34 -0
  315. data/lib/arel/visitors/depth_first.rb +203 -0
  316. data/lib/arel/visitors/dot.rb +296 -0
  317. data/lib/arel/visitors/ibm_db.rb +34 -0
  318. data/lib/arel/visitors/informix.rb +62 -0
  319. data/lib/arel/visitors/mssql.rb +156 -0
  320. data/lib/arel/visitors/mysql.rb +83 -0
  321. data/lib/arel/visitors/oracle.rb +158 -0
  322. data/lib/arel/visitors/oracle12.rb +65 -0
  323. data/lib/arel/visitors/postgresql.rb +109 -0
  324. data/lib/arel/visitors/sqlite.rb +38 -0
  325. data/lib/arel/visitors/to_sql.rb +888 -0
  326. data/lib/arel/visitors/visitor.rb +45 -0
  327. data/lib/arel/visitors/where_sql.rb +22 -0
  328. data/lib/arel/visitors.rb +20 -0
  329. data/lib/arel/window_predications.rb +9 -0
  330. data/lib/arel.rb +62 -0
  331. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  332. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  333. data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
  334. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  335. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -2
  336. data/lib/rails/generators/active_record/migration.rb +30 -1
  337. data/lib/rails/generators/active_record/model/model_generator.rb +18 -22
  338. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  339. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  340. data/lib/rails/generators/active_record.rb +7 -5
  341. metadata +168 -59
  342. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  343. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  344. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  345. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  346. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  347. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  348. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  349. data/lib/active_record/attribute.rb +0 -163
  350. data/lib/active_record/attribute_set/builder.rb +0 -106
  351. data/lib/active_record/attribute_set.rb +0 -81
  352. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
  353. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  354. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  355. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  356. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  357. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  358. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  359. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  360. data/lib/active_record/type/big_integer.rb +0 -13
  361. data/lib/active_record/type/binary.rb +0 -50
  362. data/lib/active_record/type/boolean.rb +0 -31
  363. data/lib/active_record/type/decimal.rb +0 -64
  364. data/lib/active_record/type/decorator.rb +0 -14
  365. data/lib/active_record/type/float.rb +0 -19
  366. data/lib/active_record/type/integer.rb +0 -59
  367. data/lib/active_record/type/mutable.rb +0 -16
  368. data/lib/active_record/type/numeric.rb +0 -36
  369. data/lib/active_record/type/string.rb +0 -40
  370. data/lib/active_record/type/time_value.rb +0 -38
  371. data/lib/active_record/type/value.rb +0 -110
  372. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
  373. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -1,7 +1,9 @@
1
- require 'thread'
2
- require 'active_support/core_ext/hash/indifferent_access'
3
- require 'active_support/core_ext/object/duplicable'
4
- require 'active_support/core_ext/string/filters'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/indifferent_access"
4
+ require "active_support/core_ext/string/filters"
5
+ require "active_support/parameter_filter"
6
+ require "concurrent/map"
5
7
 
6
8
  module ActiveRecord
7
9
  module Core
@@ -16,9 +18,16 @@ module ActiveRecord
16
18
  # retrieved on both a class and instance level by calling +logger+.
17
19
  mattr_accessor :logger, instance_writer: false
18
20
 
21
+ ##
22
+ # :singleton-method:
23
+ #
24
+ # Specifies if the methods calling database queries should be logged below
25
+ # their relevant queries. Defaults to false.
26
+ mattr_accessor :verbose_query_logs, instance_writer: false, default: false
27
+
19
28
  ##
20
29
  # Contains the database configuration - as is typically stored in config/database.yml -
21
- # as a Hash.
30
+ # as an ActiveRecord::DatabaseConfigurations object.
22
31
  #
23
32
  # For example, the following database.yml...
24
33
  #
@@ -32,22 +41,18 @@ module ActiveRecord
32
41
  #
33
42
  # ...would result in ActiveRecord::Base.configurations to look like this:
34
43
  #
35
- # {
36
- # 'development' => {
37
- # 'adapter' => 'sqlite3',
38
- # 'database' => 'db/development.sqlite3'
39
- # },
40
- # 'production' => {
41
- # 'adapter' => 'sqlite3',
42
- # 'database' => 'db/production.sqlite3'
43
- # }
44
- # }
44
+ # #<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[
45
+ # #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
46
+ # @spec_name="primary", @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>,
47
+ # #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90 @env_name="production",
48
+ # @spec_name="primary", @config={"adapter"=>"mysql2", "database"=>"db/production.sqlite3"}>
49
+ # ]>
45
50
  def self.configurations=(config)
46
- @@configurations = ActiveRecord::ConnectionHandling::MergeAndResolveDefaultUrlConfig.new(config).resolve
51
+ @@configurations = ActiveRecord::DatabaseConfigurations.new(config)
47
52
  end
48
53
  self.configurations = {}
49
54
 
50
- # Returns fully resolved configurations hash
55
+ # Returns fully resolved ActiveRecord::DatabaseConfigurations object
51
56
  def self.configurations
52
57
  @@configurations
53
58
  end
@@ -56,8 +61,7 @@ module ActiveRecord
56
61
  # :singleton-method:
57
62
  # Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling
58
63
  # dates and times from the database. This is set to :utc by default.
59
- mattr_accessor :default_timezone, instance_writer: false
60
- self.default_timezone = :utc
64
+ mattr_accessor :default_timezone, instance_writer: false, default: :utc
61
65
 
62
66
  ##
63
67
  # :singleton-method:
@@ -67,58 +71,85 @@ module ActiveRecord
67
71
  # ActiveRecord::Schema file which can be loaded into any database that
68
72
  # supports migrations. Use :ruby if you want to have different database
69
73
  # adapters for, e.g., your development and test environments.
70
- mattr_accessor :schema_format, instance_writer: false
71
- self.schema_format = :ruby
74
+ mattr_accessor :schema_format, instance_writer: false, default: :ruby
75
+
76
+ ##
77
+ # :singleton-method:
78
+ # Specifies if an error should be raised if the query has an order being
79
+ # ignored when doing batch queries. Useful in applications where the
80
+ # scope being ignored is error-worthy, rather than a warning.
81
+ mattr_accessor :error_on_ignored_order, instance_writer: false, default: false
82
+
83
+ # :singleton-method:
84
+ # Specify the behavior for unsafe raw query methods. Values are as follows
85
+ # deprecated - Warnings are logged when unsafe raw SQL is passed to
86
+ # query methods.
87
+ # disabled - Unsafe raw SQL passed to query methods results in
88
+ # UnknownAttributeReference exception.
89
+ mattr_accessor :allow_unsafe_raw_sql, instance_writer: false, default: :deprecated
72
90
 
73
91
  ##
74
92
  # :singleton-method:
75
93
  # Specify whether or not to use timestamps for migration versions
76
- mattr_accessor :timestamped_migrations, instance_writer: false
77
- self.timestamped_migrations = true
94
+ mattr_accessor :timestamped_migrations, instance_writer: false, default: true
78
95
 
79
96
  ##
80
97
  # :singleton-method:
81
98
  # Specify whether schema dump should happen at the end of the
82
- # db:migrate rake task. This is true by default, which is useful for the
99
+ # db:migrate rails command. This is true by default, which is useful for the
83
100
  # development environment. This should ideally be false in the production
84
101
  # environment where dumping schema is rarely needed.
85
- mattr_accessor :dump_schema_after_migration, instance_writer: false
86
- self.dump_schema_after_migration = true
102
+ mattr_accessor :dump_schema_after_migration, instance_writer: false, default: true
103
+
104
+ ##
105
+ # :singleton-method:
106
+ # Specifies which database schemas to dump when calling db:structure:dump.
107
+ # If the value is :schema_search_path (the default), any schemas listed in
108
+ # schema_search_path are dumped. Use :all to dump all schemas regardless
109
+ # of schema_search_path, or a string of comma separated schemas for a
110
+ # custom list.
111
+ mattr_accessor :dump_schemas, instance_writer: false, default: :schema_search_path
112
+
113
+ ##
114
+ # :singleton-method:
115
+ # Specify a threshold for the size of query result sets. If the number of
116
+ # records in the set exceeds the threshold, a warning is logged. This can
117
+ # be used to identify queries which load thousands of records and
118
+ # potentially cause memory bloat.
119
+ mattr_accessor :warn_on_records_fetched_greater_than, instance_writer: false
87
120
 
88
121
  mattr_accessor :maintain_test_schema, instance_accessor: false
89
122
 
90
- def self.disable_implicit_join_references=(value)
91
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
92
- Implicit join references were removed with Rails 4.1.
93
- Make sure to remove this configuration because it does nothing.
94
- MSG
95
- end
123
+ mattr_accessor :belongs_to_required_by_default, instance_accessor: false
124
+
125
+ mattr_accessor :connection_handlers, instance_accessor: false, default: {}
126
+
127
+ mattr_accessor :writing_role, instance_accessor: false, default: :writing
128
+
129
+ mattr_accessor :reading_role, instance_accessor: false, default: :reading
96
130
 
97
131
  class_attribute :default_connection_handler, instance_writer: false
98
- class_attribute :find_by_statement_cache
132
+
133
+ self.filter_attributes = []
99
134
 
100
135
  def self.connection_handler
101
- ActiveRecord::RuntimeRegistry.connection_handler || default_connection_handler
136
+ Thread.current.thread_variable_get("ar_connection_handler") || default_connection_handler
102
137
  end
103
138
 
104
139
  def self.connection_handler=(handler)
105
- ActiveRecord::RuntimeRegistry.connection_handler = handler
140
+ Thread.current.thread_variable_set("ar_connection_handler", handler)
106
141
  end
107
142
 
108
143
  self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
109
144
  end
110
145
 
111
146
  module ClassMethods
112
- def allocate
113
- define_attribute_methods
114
- super
115
- end
116
-
117
147
  def initialize_find_by_cache # :nodoc:
118
- self.find_by_statement_cache = {}.extend(Mutex_m)
148
+ @find_by_statement_cache = { true => Concurrent::Map.new, false => Concurrent::Map.new }
119
149
  end
120
150
 
121
151
  def inherited(child_class) # :nodoc:
152
+ # initialize cache at class definition for thread safety
122
153
  child_class.initialize_find_by_cache
123
154
  super
124
155
  end
@@ -126,90 +157,88 @@ module ActiveRecord
126
157
  def find(*ids) # :nodoc:
127
158
  # We don't have cache keys for this stuff yet
128
159
  return super unless ids.length == 1
129
- # Allow symbols to super to maintain compatibility for deprecated finders until Rails 5
130
- return super if ids.first.kind_of?(Symbol)
131
160
  return super if block_given? ||
132
161
  primary_key.nil? ||
133
- default_scopes.any? ||
134
- current_scope ||
135
- columns_hash.include?(inheritance_column) ||
136
- ids.first.kind_of?(Array)
137
-
138
- id = ids.first
139
- if ActiveRecord::Base === id
140
- id = id.id
141
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
142
- You are passing an instance of ActiveRecord::Base to `find`.
143
- Please pass the id of the object by calling `.id`
144
- MSG
145
- end
162
+ scope_attributes? ||
163
+ columns_hash.key?(inheritance_column) && !base_class?
164
+
165
+ id = ids.first
166
+
167
+ return super if StatementCache.unsupported_value?(id)
168
+
146
169
  key = primary_key
147
170
 
148
- s = find_by_statement_cache[key] || find_by_statement_cache.synchronize {
149
- find_by_statement_cache[key] ||= StatementCache.create(connection) { |params|
150
- where(key => params.bind).limit(1)
151
- }
171
+ statement = cached_find_by_statement(key) { |params|
172
+ where(key => params.bind).limit(1)
152
173
  }
153
- record = s.execute([id], self, connection).first
174
+
175
+ record = statement.execute([id], connection)&.first
154
176
  unless record
155
- raise RecordNotFound, "Couldn't find #{name} with '#{primary_key}'=#{id}"
177
+ raise RecordNotFound.new("Couldn't find #{name} with '#{key}'=#{id}", name, key, id)
156
178
  end
157
179
  record
158
- rescue RangeError
159
- raise RecordNotFound, "Couldn't find #{name} with an out of range value for '#{primary_key}'"
160
180
  end
161
181
 
162
182
  def find_by(*args) # :nodoc:
163
- return super if current_scope || !(Hash === args.first) || reflect_on_all_aggregations.any?
164
- return super if default_scopes.any?
183
+ return super if scope_attributes? || reflect_on_all_aggregations.any? ||
184
+ columns_hash.key?(inheritance_column) && !base_class?
165
185
 
166
186
  hash = args.first
167
187
 
168
- return super if hash.values.any? { |v|
169
- v.nil? || Array === v || Hash === v
188
+ return super if !(Hash === hash) || hash.values.any? { |v|
189
+ StatementCache.unsupported_value?(v)
170
190
  }
171
191
 
172
192
  # We can't cache Post.find_by(author: david) ...yet
173
193
  return super unless hash.keys.all? { |k| columns_hash.has_key?(k.to_s) }
174
194
 
175
- key = hash.keys
195
+ keys = hash.keys
176
196
 
177
- klass = self
178
- s = find_by_statement_cache[key] || find_by_statement_cache.synchronize {
179
- find_by_statement_cache[key] ||= StatementCache.create(connection) { |params|
180
- wheres = key.each_with_object({}) { |param,o|
181
- o[param] = params.bind
182
- }
183
- klass.where(wheres).limit(1)
197
+ statement = cached_find_by_statement(keys) { |params|
198
+ wheres = keys.each_with_object({}) { |param, o|
199
+ o[param] = params.bind
184
200
  }
201
+ where(wheres).limit(1)
185
202
  }
186
203
  begin
187
- s.execute(hash.values, self, connection).first
188
- rescue TypeError => e
189
- raise ActiveRecord::StatementInvalid.new(e.message, e)
190
- rescue RangeError
191
- nil
204
+ statement.execute(hash.values, connection)&.first
205
+ rescue TypeError
206
+ raise ActiveRecord::StatementInvalid
192
207
  end
193
208
  end
194
209
 
195
210
  def find_by!(*args) # :nodoc:
196
- find_by(*args) or raise RecordNotFound.new("Couldn't find #{name}")
211
+ find_by(*args) || raise(RecordNotFound.new("Couldn't find #{name}", name))
197
212
  end
198
213
 
199
214
  def initialize_generated_modules # :nodoc:
200
215
  generated_association_methods
201
216
  end
202
217
 
203
- def generated_association_methods
218
+ def generated_association_methods # :nodoc:
204
219
  @generated_association_methods ||= begin
205
220
  mod = const_set(:GeneratedAssociationMethods, Module.new)
221
+ private_constant :GeneratedAssociationMethods
206
222
  include mod
223
+
207
224
  mod
208
225
  end
209
226
  end
210
227
 
228
+ # Returns columns which shouldn't be exposed while calling +#inspect+.
229
+ def filter_attributes
230
+ if defined?(@filter_attributes)
231
+ @filter_attributes
232
+ else
233
+ superclass.filter_attributes
234
+ end
235
+ end
236
+
237
+ # Specifies columns which shouldn't be exposed while calling +#inspect+.
238
+ attr_writer :filter_attributes
239
+
211
240
  # Returns a string like 'Post(id:integer, title:string, body:text)'
212
- def inspect
241
+ def inspect # :nodoc:
213
242
  if self == Base
214
243
  super
215
244
  elsif abstract_class?
@@ -217,48 +246,65 @@ module ActiveRecord
217
246
  elsif !connected?
218
247
  "#{super} (call '#{super}.connection' to establish a connection)"
219
248
  elsif table_exists?
220
- attr_list = columns.map { |c| "#{c.name}: #{c.type}" } * ', '
249
+ attr_list = attribute_types.map { |name, type| "#{name}: #{type.type}" } * ", "
221
250
  "#{super}(#{attr_list})"
222
251
  else
223
252
  "#{super}(Table doesn't exist)"
224
253
  end
225
254
  end
226
255
 
227
- # Overwrite the default class equality method to provide support for association proxies.
228
- def ===(object)
256
+ # Overwrite the default class equality method to provide support for decorated models.
257
+ def ===(object) # :nodoc:
229
258
  object.is_a?(self)
230
259
  end
231
260
 
232
261
  # Returns an instance of <tt>Arel::Table</tt> loaded with the current table name.
233
262
  #
234
263
  # class Post < ActiveRecord::Base
235
- # scope :published_and_commented, -> { published.and(self.arel_table[:comments_count].gt(0)) }
264
+ # scope :published_and_commented, -> { published.and(arel_table[:comments_count].gt(0)) }
236
265
  # end
237
266
  def arel_table # :nodoc:
238
- @arel_table ||= Arel::Table.new(table_name, arel_engine)
267
+ @arel_table ||= Arel::Table.new(table_name, type_caster: type_caster)
239
268
  end
240
269
 
241
- # Returns the Arel engine.
242
- def arel_engine # :nodoc:
243
- @arel_engine ||=
244
- if Base == self || connection_handler.retrieve_connection_pool(self)
245
- self
246
- else
247
- superclass.arel_engine
248
- end
270
+ def arel_attribute(name, table = arel_table) # :nodoc:
271
+ name = name.to_s
272
+ name = attribute_aliases[name] || name
273
+ table[name]
274
+ end
275
+
276
+ def predicate_builder # :nodoc:
277
+ @predicate_builder ||= PredicateBuilder.new(table_metadata)
278
+ end
279
+
280
+ def type_caster # :nodoc:
281
+ TypeCaster::Map.new(self)
282
+ end
283
+
284
+ def _internal? # :nodoc:
285
+ false
249
286
  end
250
287
 
251
288
  private
289
+ def cached_find_by_statement(key, &block)
290
+ cache = @find_by_statement_cache[connection.prepared_statements]
291
+ cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
292
+ end
252
293
 
253
- def relation #:nodoc:
254
- relation = Relation.create(self, arel_table)
294
+ def relation
295
+ relation = Relation.create(self)
255
296
 
256
- if finder_needs_type_condition?
257
- relation.where(type_condition).create_with(inheritance_column.to_sym => sti_name)
258
- else
259
- relation
297
+ if finder_needs_type_condition? && !ignore_default_scope?
298
+ relation.where!(type_condition)
299
+ relation.create_with!(inheritance_column.to_s => sti_name)
300
+ else
301
+ relation
302
+ end
303
+ end
304
+
305
+ def table_metadata
306
+ TableMetadata.new(self, arel_table)
260
307
  end
261
- end
262
308
  end
263
309
 
264
310
  # New objects can be instantiated as either empty (pass no construction parameter) or pre-set with
@@ -269,16 +315,14 @@ module ActiveRecord
269
315
  # ==== Example:
270
316
  # # Instantiates a single new object
271
317
  # User.new(first_name: 'Jamie')
272
- def initialize(attributes = nil, options = {})
273
- @attributes = self.class._default_attributes.dup
274
- self.class.define_attribute_methods
318
+ def initialize(attributes = nil)
319
+ @new_record = true
320
+ @attributes = self.class._default_attributes.deep_dup
275
321
 
276
322
  init_internals
277
323
  initialize_internals_callback
278
324
 
279
- # +options+ argument is only needed to make protected_attributes gem easier to hook.
280
- # Remove it when we drop support to this gem.
281
- init_attributes(attributes, options) if attributes
325
+ assign_attributes(attributes) if attributes
282
326
 
283
327
  yield self if block_given?
284
328
  _run_initialize_callbacks
@@ -286,7 +330,7 @@ module ActiveRecord
286
330
 
287
331
  # Initialize an empty model object from +coder+. +coder+ should be
288
332
  # the result of previously encoding an Active Record model, using
289
- # `encode_with`
333
+ # #encode_with.
290
334
  #
291
335
  # class Post < ActiveRecord::Base
292
336
  # end
@@ -298,15 +342,23 @@ module ActiveRecord
298
342
  # post = Post.allocate
299
343
  # post.init_with(coder)
300
344
  # post.title # => 'hello world'
301
- def init_with(coder)
345
+ def init_with(coder, &block)
302
346
  coder = LegacyYamlAdapter.convert(self.class, coder)
303
- @attributes = coder['attributes']
347
+ attributes = self.class.yaml_encoder.decode(coder)
348
+ init_with_attributes(attributes, coder["new_record"], &block)
349
+ end
304
350
 
305
- init_internals
351
+ ##
352
+ # Initialize an empty model object from +attributes+.
353
+ # +attributes+ should be an attributes object, and unlike the
354
+ # `initialize` method, no assignment calls are made per attribute.
355
+ def init_with_attributes(attributes, new_record = false) # :nodoc:
356
+ @new_record = new_record
357
+ @attributes = attributes
306
358
 
307
- @new_record = coder['new_record']
359
+ init_internals
308
360
 
309
- self.class.define_attribute_methods
361
+ yield self if block_given?
310
362
 
311
363
  _run_find_callbacks
312
364
  _run_initialize_callbacks
@@ -342,23 +394,22 @@ module ActiveRecord
342
394
 
343
395
  ##
344
396
  def initialize_dup(other) # :nodoc:
345
- @attributes = @attributes.dup
346
- @attributes.reset(self.class.primary_key)
397
+ @attributes = @attributes.deep_dup
398
+ @attributes.reset(@primary_key)
347
399
 
348
400
  _run_initialize_callbacks
349
401
 
350
- @aggregation_cache = {}
351
- @association_cache = {}
352
-
353
- @new_record = true
354
- @destroyed = false
402
+ @new_record = true
403
+ @destroyed = false
404
+ @_start_transaction_state = nil
405
+ @transaction_state = nil
355
406
 
356
407
  super
357
408
  end
358
409
 
359
410
  # Populate +coder+ with attributes about this record that should be
360
411
  # serialized. The structure of +coder+ defined in this method is
361
- # guaranteed to match the structure of +coder+ passed to the +init_with+
412
+ # guaranteed to match the structure of +coder+ passed to the #init_with
362
413
  # method.
363
414
  #
364
415
  # Example:
@@ -369,11 +420,9 @@ module ActiveRecord
369
420
  # Post.new.encode_with(coder)
370
421
  # coder # => {"attributes" => {"id" => nil, ... }}
371
422
  def encode_with(coder)
372
- # FIXME: Remove this when we better serialize attributes
373
- coder['raw_attributes'] = attributes_before_type_cast
374
- coder['attributes'] = @attributes
375
- coder['new_record'] = new_record?
376
- coder['active_record_yaml_version'] = 0
423
+ self.class.yaml_encoder.encode(@attributes, coder)
424
+ coder["new_record"] = new_record?
425
+ coder["active_record_yaml_version"] = 2
377
426
  end
378
427
 
379
428
  # Returns true if +comparison_object+ is the same exact object, or +comparison_object+
@@ -397,7 +446,7 @@ module ActiveRecord
397
446
  # [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
398
447
  def hash
399
448
  if id
400
- id.hash
449
+ self.class.hash ^ id.hash
401
450
  else
402
451
  super
403
452
  end
@@ -413,18 +462,27 @@ module ActiveRecord
413
462
 
414
463
  # Returns +true+ if the attributes hash has been frozen.
415
464
  def frozen?
465
+ sync_with_transaction_state if @transaction_state&.finalized?
416
466
  @attributes.frozen?
417
467
  end
418
468
 
419
469
  # Allows sort on objects
420
470
  def <=>(other_object)
421
471
  if other_object.is_a?(self.class)
422
- self.to_key <=> other_object.to_key
472
+ to_key <=> other_object.to_key
423
473
  else
424
474
  super
425
475
  end
426
476
  end
427
477
 
478
+ def present? # :nodoc:
479
+ true
480
+ end
481
+
482
+ def blank? # :nodoc:
483
+ false
484
+ end
485
+
428
486
  # Returns +true+ if the record is read only. Records loaded through joins with piggy-back
429
487
  # attributes will be marked as read only since they cannot be saved.
430
488
  def readonly?
@@ -445,135 +503,99 @@ module ActiveRecord
445
503
  # We check defined?(@attributes) not to issue warnings if the object is
446
504
  # allocated but not initialized.
447
505
  inspection = if defined?(@attributes) && @attributes
448
- self.class.column_names.collect { |name|
449
- if has_attribute?(name)
450
- "#{name}: #{attribute_for_inspect(name)}"
451
- end
452
- }.compact.join(", ")
453
- else
454
- "not initialized"
455
- end
506
+ self.class.attribute_names.collect do |name|
507
+ if has_attribute?(name)
508
+ attr = _read_attribute(name)
509
+ value = if attr.nil?
510
+ attr.inspect
511
+ else
512
+ attr = format_for_inspect(attr)
513
+ inspection_filter.filter_param(name, attr)
514
+ end
515
+ "#{name}: #{value}"
516
+ end
517
+ end.compact.join(", ")
518
+ else
519
+ "not initialized"
520
+ end
521
+
456
522
  "#<#{self.class} #{inspection}>"
457
523
  end
458
524
 
459
- # Takes a PP and prettily prints this record to it, allowing you to get a nice result from `pp record`
525
+ # Takes a PP and prettily prints this record to it, allowing you to get a nice result from <tt>pp record</tt>
460
526
  # when pp is required.
461
527
  def pretty_print(pp)
462
528
  return super if custom_inspect_method_defined?
463
529
  pp.object_address_group(self) do
464
530
  if defined?(@attributes) && @attributes
465
- column_names = self.class.column_names.select { |name| has_attribute?(name) || new_record? }
466
- pp.seplist(column_names, proc { pp.text ',' }) do |column_name|
467
- column_value = read_attribute(column_name)
468
- pp.breakable ' '
531
+ attr_names = self.class.attribute_names.select { |name| has_attribute?(name) }
532
+ pp.seplist(attr_names, proc { pp.text "," }) do |attr_name|
533
+ pp.breakable " "
469
534
  pp.group(1) do
470
- pp.text column_name
471
- pp.text ':'
535
+ pp.text attr_name
536
+ pp.text ":"
472
537
  pp.breakable
473
- pp.pp column_value
538
+ value = _read_attribute(attr_name)
539
+ value = inspection_filter.filter_param(attr_name, value) unless value.nil?
540
+ pp.pp value
474
541
  end
475
542
  end
476
543
  else
477
- pp.breakable ' '
478
- pp.text 'not initialized'
544
+ pp.breakable " "
545
+ pp.text "not initialized"
479
546
  end
480
547
  end
481
548
  end
482
549
 
483
550
  # Returns a hash of the given methods with their names as keys and returned values as values.
484
551
  def slice(*methods)
485
- Hash[methods.map! { |method| [method, public_send(method)] }].with_indifferent_access
552
+ Hash[methods.flatten.map! { |method| [method, public_send(method)] }].with_indifferent_access
486
553
  end
487
554
 
488
555
  private
556
+ # +Array#flatten+ will call +#to_ary+ (recursively) on each of the elements of
557
+ # the array, and then rescues from the possible +NoMethodError+. If those elements are
558
+ # +ActiveRecord::Base+'s, then this triggers the various +method_missing+'s that we have,
559
+ # which significantly impacts upon performance.
560
+ #
561
+ # So we can avoid the +method_missing+ hit by explicitly defining +#to_ary+ as +nil+ here.
562
+ #
563
+ # See also https://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary.html
564
+ def to_ary
565
+ nil
566
+ end
489
567
 
490
- def set_transaction_state(state) # :nodoc:
491
- @transaction_state = state
492
- end
493
-
494
- def has_transactional_callbacks? # :nodoc:
495
- !_rollback_callbacks.empty? || !_commit_callbacks.empty?
496
- end
568
+ def init_internals
569
+ @primary_key = self.class.primary_key
570
+ @readonly = false
571
+ @destroyed = false
572
+ @marked_for_destruction = false
573
+ @destroyed_by_association = nil
574
+ @_start_transaction_state = nil
575
+ @transaction_state = nil
497
576
 
498
- # Updates the attributes on this particular ActiveRecord object so that
499
- # if it is associated with a transaction, then the state of the AR object
500
- # will be updated to reflect the current state of the transaction
501
- #
502
- # The @transaction_state variable stores the states of the associated
503
- # transaction. This relies on the fact that a transaction can only be in
504
- # one rollback or commit (otherwise a list of states would be required)
505
- # Each AR object inside of a transaction carries that transaction's
506
- # TransactionState.
507
- #
508
- # This method checks to see if the ActiveRecord object's state reflects
509
- # the TransactionState, and rolls back or commits the ActiveRecord object
510
- # as appropriate.
511
- #
512
- # Since ActiveRecord objects can be inside multiple transactions, this
513
- # method recursively goes through the parent of the TransactionState and
514
- # checks if the ActiveRecord object reflects the state of the object.
515
- def sync_with_transaction_state
516
- update_attributes_from_transaction_state(@transaction_state, 0)
517
- end
577
+ self.class.define_attribute_methods
578
+ end
518
579
 
519
- def update_attributes_from_transaction_state(transaction_state, depth)
520
- @reflects_state = [false] if depth == 0
580
+ def initialize_internals_callback
581
+ end
521
582
 
522
- if transaction_state && transaction_state.finalized? && !has_transactional_callbacks?
523
- unless @reflects_state[depth]
524
- restore_transaction_record_state if transaction_state.rolledback?
525
- clear_transaction_record_state
526
- @reflects_state[depth] = true
527
- end
583
+ def custom_inspect_method_defined?
584
+ self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner
585
+ end
528
586
 
529
- if transaction_state.parent && !@reflects_state[depth+1]
530
- update_attributes_from_transaction_state(transaction_state.parent, depth+1)
587
+ class InspectionMask < DelegateClass(::String)
588
+ def pretty_print(pp)
589
+ pp.text __getobj__
531
590
  end
532
591
  end
533
- end
534
-
535
- # Under Ruby 1.9, Array#flatten will call #to_ary (recursively) on each of the elements
536
- # of the array, and then rescues from the possible NoMethodError. If those elements are
537
- # ActiveRecord::Base's, then this triggers the various method_missing's that we have,
538
- # which significantly impacts upon performance.
539
- #
540
- # So we can avoid the method_missing hit by explicitly defining #to_ary as nil here.
541
- #
542
- # See also http://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary.html
543
- def to_ary # :nodoc:
544
- nil
545
- end
592
+ private_constant :InspectionMask
546
593
 
547
- def init_internals
548
- @aggregation_cache = {}
549
- @association_cache = {}
550
- @readonly = false
551
- @destroyed = false
552
- @marked_for_destruction = false
553
- @destroyed_by_association = nil
554
- @new_record = true
555
- @txn = nil
556
- @_start_transaction_state = {}
557
- @transaction_state = nil
558
- end
559
-
560
- def initialize_internals_callback
561
- end
562
-
563
- # This method is needed to make protected_attributes gem easier to hook.
564
- # Remove it when we drop support to this gem.
565
- def init_attributes(attributes, options)
566
- assign_attributes(attributes)
567
- end
568
-
569
- def thaw
570
- if frozen?
571
- @attributes = @attributes.dup
594
+ def inspection_filter
595
+ @inspection_filter ||= begin
596
+ mask = InspectionMask.new(ActiveSupport::ParameterFilter::FILTERED)
597
+ ActiveSupport::ParameterFilter.new(self.class.filter_attributes, mask: mask)
598
+ end
572
599
  end
573
- end
574
-
575
- def custom_inspect_method_defined?
576
- self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner
577
- end
578
600
  end
579
601
  end