activerecord 3.2.6 → 6.0.0

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 (371) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +611 -6417
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +44 -47
  5. data/examples/performance.rb +79 -71
  6. data/examples/simple.rb +6 -5
  7. data/lib/active_record/aggregations.rb +268 -238
  8. data/lib/active_record/association_relation.rb +40 -0
  9. data/lib/active_record/associations/alias_tracker.rb +47 -42
  10. data/lib/active_record/associations/association.rb +173 -81
  11. data/lib/active_record/associations/association_scope.rb +124 -92
  12. data/lib/active_record/associations/belongs_to_association.rb +83 -38
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +11 -9
  14. data/lib/active_record/associations/builder/association.rb +113 -32
  15. data/lib/active_record/associations/builder/belongs_to.rb +105 -60
  16. data/lib/active_record/associations/builder/collection_association.rb +53 -56
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +98 -41
  18. data/lib/active_record/associations/builder/has_many.rb +11 -63
  19. data/lib/active_record/associations/builder/has_one.rb +47 -45
  20. data/lib/active_record/associations/builder/singular_association.rb +30 -18
  21. data/lib/active_record/associations/collection_association.rb +217 -295
  22. data/lib/active_record/associations/collection_proxy.rb +1074 -77
  23. data/lib/active_record/associations/foreign_association.rb +20 -0
  24. data/lib/active_record/associations/has_many_association.rb +78 -50
  25. data/lib/active_record/associations/has_many_through_association.rb +99 -61
  26. data/lib/active_record/associations/has_one_association.rb +75 -30
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +45 -119
  29. data/lib/active_record/associations/join_dependency/join_base.rb +11 -12
  30. data/lib/active_record/associations/join_dependency/join_part.rb +35 -42
  31. data/lib/active_record/associations/join_dependency.rb +208 -164
  32. data/lib/active_record/associations/preloader/association.rb +93 -87
  33. data/lib/active_record/associations/preloader/through_association.rb +87 -38
  34. data/lib/active_record/associations/preloader.rb +134 -110
  35. data/lib/active_record/associations/singular_association.rb +19 -24
  36. data/lib/active_record/associations/through_association.rb +61 -27
  37. data/lib/active_record/associations.rb +1766 -1505
  38. data/lib/active_record/attribute_assignment.rb +57 -193
  39. data/lib/active_record/attribute_decorators.rb +90 -0
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +58 -8
  41. data/lib/active_record/attribute_methods/dirty.rb +187 -67
  42. data/lib/active_record/attribute_methods/primary_key.rb +100 -78
  43. data/lib/active_record/attribute_methods/query.rb +10 -8
  44. data/lib/active_record/attribute_methods/read.rb +29 -118
  45. data/lib/active_record/attribute_methods/serialization.rb +60 -72
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +69 -42
  47. data/lib/active_record/attribute_methods/write.rb +36 -44
  48. data/lib/active_record/attribute_methods.rb +306 -161
  49. data/lib/active_record/attributes.rb +279 -0
  50. data/lib/active_record/autosave_association.rb +324 -238
  51. data/lib/active_record/base.rb +114 -507
  52. data/lib/active_record/callbacks.rb +147 -83
  53. data/lib/active_record/coders/json.rb +15 -0
  54. data/lib/active_record/coders/yaml_column.rb +32 -23
  55. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +962 -279
  56. data/lib/active_record/connection_adapters/abstract/database_limits.rb +32 -5
  57. data/lib/active_record/connection_adapters/abstract/database_statements.rb +331 -209
  58. data/lib/active_record/connection_adapters/abstract/query_cache.rb +95 -23
  59. data/lib/active_record/connection_adapters/abstract/quoting.rb +201 -65
  60. data/lib/active_record/connection_adapters/abstract/savepoints.rb +23 -0
  61. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -0
  62. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +510 -289
  63. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +93 -0
  64. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +1182 -313
  65. data/lib/active_record/connection_adapters/abstract/transaction.rb +323 -0
  66. data/lib/active_record/connection_adapters/abstract_adapter.rb +585 -120
  67. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +610 -463
  68. data/lib/active_record/connection_adapters/column.rb +58 -233
  69. data/lib/active_record/connection_adapters/connection_specification.rb +297 -0
  70. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
  71. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  72. data/lib/active_record/connection_adapters/mysql/database_statements.rb +200 -0
  73. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
  74. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +72 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
  78. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  79. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  80. data/lib/active_record/connection_adapters/mysql2_adapter.rb +75 -207
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +30 -0
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +182 -0
  83. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +92 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +53 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +15 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +17 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +50 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +23 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +15 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +21 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +71 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +15 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +15 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +41 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +15 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +65 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +97 -0
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +18 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +113 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +26 -0
  104. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +28 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +30 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +34 -0
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +205 -0
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +43 -0
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +222 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +776 -0
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +81 -0
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +695 -1052
  116. data/lib/active_record/connection_adapters/schema_cache.rb +115 -24
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
  118. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
  119. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  120. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +103 -0
  121. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  125. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +528 -26
  126. data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
  127. data/lib/active_record/connection_handling.rb +267 -0
  128. data/lib/active_record/core.rb +599 -0
  129. data/lib/active_record/counter_cache.rb +177 -103
  130. data/lib/active_record/database_configurations/database_config.rb +37 -0
  131. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  132. data/lib/active_record/database_configurations/url_config.rb +79 -0
  133. data/lib/active_record/database_configurations.rb +233 -0
  134. data/lib/active_record/define_callbacks.rb +22 -0
  135. data/lib/active_record/dynamic_matchers.rb +107 -64
  136. data/lib/active_record/enum.rb +274 -0
  137. data/lib/active_record/errors.rb +254 -61
  138. data/lib/active_record/explain.rb +35 -70
  139. data/lib/active_record/explain_registry.rb +32 -0
  140. data/lib/active_record/explain_subscriber.rb +18 -8
  141. data/lib/active_record/fixture_set/file.rb +82 -0
  142. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  143. data/lib/active_record/fixture_set/render_context.rb +17 -0
  144. data/lib/active_record/fixture_set/table_row.rb +153 -0
  145. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  146. data/lib/active_record/fixtures.rb +291 -475
  147. data/lib/active_record/gem_version.rb +17 -0
  148. data/lib/active_record/inheritance.rb +219 -100
  149. data/lib/active_record/insert_all.rb +179 -0
  150. data/lib/active_record/integration.rb +175 -17
  151. data/lib/active_record/internal_metadata.rb +53 -0
  152. data/lib/active_record/legacy_yaml_adapter.rb +48 -0
  153. data/lib/active_record/locale/en.yml +9 -1
  154. data/lib/active_record/locking/optimistic.rb +106 -92
  155. data/lib/active_record/locking/pessimistic.rb +23 -11
  156. data/lib/active_record/log_subscriber.rb +80 -30
  157. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  158. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  159. data/lib/active_record/middleware/database_selector.rb +75 -0
  160. data/lib/active_record/migration/command_recorder.rb +235 -56
  161. data/lib/active_record/migration/compatibility.rb +244 -0
  162. data/lib/active_record/migration/join_table.rb +17 -0
  163. data/lib/active_record/migration.rb +917 -301
  164. data/lib/active_record/model_schema.rb +351 -175
  165. data/lib/active_record/nested_attributes.rb +366 -235
  166. data/lib/active_record/no_touching.rb +65 -0
  167. data/lib/active_record/null_relation.rb +68 -0
  168. data/lib/active_record/persistence.rb +761 -166
  169. data/lib/active_record/query_cache.rb +22 -44
  170. data/lib/active_record/querying.rb +55 -31
  171. data/lib/active_record/railtie.rb +185 -47
  172. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  173. data/lib/active_record/railties/console_sandbox.rb +5 -4
  174. data/lib/active_record/railties/controller_runtime.rb +35 -33
  175. data/lib/active_record/railties/databases.rake +366 -463
  176. data/lib/active_record/readonly_attributes.rb +4 -6
  177. data/lib/active_record/reflection.rb +736 -228
  178. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  179. data/lib/active_record/relation/batches.rb +252 -52
  180. data/lib/active_record/relation/calculations.rb +340 -270
  181. data/lib/active_record/relation/delegation.rb +117 -36
  182. data/lib/active_record/relation/finder_methods.rb +439 -286
  183. data/lib/active_record/relation/from_clause.rb +26 -0
  184. data/lib/active_record/relation/merger.rb +184 -0
  185. data/lib/active_record/relation/predicate_builder/array_handler.rb +49 -0
  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 +18 -0
  188. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  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 +22 -0
  191. data/lib/active_record/relation/predicate_builder/relation_handler.rb +19 -0
  192. data/lib/active_record/relation/predicate_builder.rb +131 -39
  193. data/lib/active_record/relation/query_attribute.rb +50 -0
  194. data/lib/active_record/relation/query_methods.rb +1163 -221
  195. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  196. data/lib/active_record/relation/spawn_methods.rb +49 -120
  197. data/lib/active_record/relation/where_clause.rb +190 -0
  198. data/lib/active_record/relation/where_clause_factory.rb +33 -0
  199. data/lib/active_record/relation.rb +671 -349
  200. data/lib/active_record/result.rb +149 -15
  201. data/lib/active_record/runtime_registry.rb +24 -0
  202. data/lib/active_record/sanitization.rb +153 -133
  203. data/lib/active_record/schema.rb +22 -19
  204. data/lib/active_record/schema_dumper.rb +178 -112
  205. data/lib/active_record/schema_migration.rb +60 -0
  206. data/lib/active_record/scoping/default.rb +107 -98
  207. data/lib/active_record/scoping/named.rb +130 -115
  208. data/lib/active_record/scoping.rb +77 -123
  209. data/lib/active_record/secure_token.rb +40 -0
  210. data/lib/active_record/serialization.rb +10 -6
  211. data/lib/active_record/statement_cache.rb +148 -0
  212. data/lib/active_record/store.rb +256 -16
  213. data/lib/active_record/suppressor.rb +61 -0
  214. data/lib/active_record/table_metadata.rb +75 -0
  215. data/lib/active_record/tasks/database_tasks.rb +506 -0
  216. data/lib/active_record/tasks/mysql_database_tasks.rb +115 -0
  217. data/lib/active_record/tasks/postgresql_database_tasks.rb +141 -0
  218. data/lib/active_record/tasks/sqlite_database_tasks.rb +77 -0
  219. data/lib/active_record/test_databases.rb +23 -0
  220. data/lib/active_record/test_fixtures.rb +224 -0
  221. data/lib/active_record/timestamp.rb +93 -39
  222. data/lib/active_record/touch_later.rb +66 -0
  223. data/lib/active_record/transactions.rb +260 -129
  224. data/lib/active_record/translation.rb +3 -1
  225. data/lib/active_record/type/adapter_specific_registry.rb +129 -0
  226. data/lib/active_record/type/date.rb +9 -0
  227. data/lib/active_record/type/date_time.rb +9 -0
  228. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  229. data/lib/active_record/type/hash_lookup_type_map.rb +25 -0
  230. data/lib/active_record/type/internal/timezone.rb +17 -0
  231. data/lib/active_record/type/json.rb +30 -0
  232. data/lib/active_record/type/serialized.rb +71 -0
  233. data/lib/active_record/type/text.rb +11 -0
  234. data/lib/active_record/type/time.rb +21 -0
  235. data/lib/active_record/type/type_map.rb +62 -0
  236. data/lib/active_record/type/unsigned_integer.rb +17 -0
  237. data/lib/active_record/type.rb +78 -0
  238. data/lib/active_record/type_caster/connection.rb +34 -0
  239. data/lib/active_record/type_caster/map.rb +20 -0
  240. data/lib/active_record/type_caster.rb +9 -0
  241. data/lib/active_record/validations/absence.rb +25 -0
  242. data/lib/active_record/validations/associated.rb +35 -18
  243. data/lib/active_record/validations/length.rb +26 -0
  244. data/lib/active_record/validations/presence.rb +68 -0
  245. data/lib/active_record/validations/uniqueness.rb +123 -77
  246. data/lib/active_record/validations.rb +54 -43
  247. data/lib/active_record/version.rb +7 -7
  248. data/lib/active_record.rb +97 -49
  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 +257 -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 +204 -0
  315. data/lib/arel/visitors/dot.rb +297 -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 +157 -0
  319. data/lib/arel/visitors/mysql.rb +83 -0
  320. data/lib/arel/visitors/oracle.rb +159 -0
  321. data/lib/arel/visitors/oracle12.rb +66 -0
  322. data/lib/arel/visitors/postgresql.rb +110 -0
  323. data/lib/arel/visitors/sqlite.rb +39 -0
  324. data/lib/arel/visitors/to_sql.rb +889 -0
  325. data/lib/arel/visitors/visitor.rb +46 -0
  326. data/lib/arel/visitors/where_sql.rb +23 -0
  327. data/lib/arel/visitors.rb +20 -0
  328. data/lib/arel/window_predications.rb +9 -0
  329. data/lib/arel.rb +51 -0
  330. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  331. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  332. data/lib/rails/generators/active_record/migration/migration_generator.rb +59 -9
  333. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  334. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +48 -0
  335. data/lib/rails/generators/active_record/migration.rb +41 -8
  336. data/lib/rails/generators/active_record/model/model_generator.rb +24 -22
  337. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  338. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +1 -1
  339. data/lib/rails/generators/active_record.rb +10 -16
  340. metadata +285 -149
  341. data/examples/associations.png +0 -0
  342. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -63
  343. data/lib/active_record/associations/join_helper.rb +0 -55
  344. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  345. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  346. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
  347. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  348. data/lib/active_record/associations/preloader/has_many_through.rb +0 -15
  349. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  350. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  351. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  352. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
  353. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -188
  354. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -426
  355. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -579
  356. data/lib/active_record/dynamic_finder_match.rb +0 -68
  357. data/lib/active_record/dynamic_scope_match.rb +0 -23
  358. data/lib/active_record/fixtures/file.rb +0 -65
  359. data/lib/active_record/identity_map.rb +0 -162
  360. data/lib/active_record/observer.rb +0 -121
  361. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  362. data/lib/active_record/serializers/xml_serializer.rb +0 -203
  363. data/lib/active_record/session_store.rb +0 -358
  364. data/lib/active_record/test_case.rb +0 -73
  365. data/lib/rails/generators/active_record/migration/templates/migration.rb +0 -34
  366. data/lib/rails/generators/active_record/model/templates/migration.rb +0 -15
  367. data/lib/rails/generators/active_record/model/templates/model.rb +0 -12
  368. data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
  369. data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
  370. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
  371. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -1,47 +1,150 @@
1
- require 'active_support/concern'
1
+ # frozen_string_literal: true
2
+
3
+ require "monitor"
2
4
 
3
5
  module ActiveRecord
4
6
  module ModelSchema
5
7
  extend ActiveSupport::Concern
6
8
 
9
+ ##
10
+ # :singleton-method: primary_key_prefix_type
11
+ # :call-seq: primary_key_prefix_type
12
+ #
13
+ # The prefix type that will be prepended to every primary key column name.
14
+ # The options are +:table_name+ and +:table_name_with_underscore+. If the first is specified,
15
+ # the Product class will look for "productid" instead of "id" as the primary column. If the
16
+ # latter is specified, the Product class will look for "product_id" instead of "id". Remember
17
+ # that this is a global setting for all Active Records.
18
+
19
+ ##
20
+ # :singleton-method: primary_key_prefix_type=
21
+ # :call-seq: primary_key_prefix_type=(prefix_type)
22
+ #
23
+ # Sets the prefix type that will be prepended to every primary key column name.
24
+ # The options are +:table_name+ and +:table_name_with_underscore+. If the first is specified,
25
+ # the Product class will look for "productid" instead of "id" as the primary column. If the
26
+ # latter is specified, the Product class will look for "product_id" instead of "id". Remember
27
+ # that this is a global setting for all Active Records.
28
+
29
+ ##
30
+ # :singleton-method: table_name_prefix
31
+ # :call-seq: table_name_prefix
32
+ #
33
+ # The prefix string to prepend to every table name.
34
+
35
+ ##
36
+ # :singleton-method: table_name_prefix=
37
+ # :call-seq: table_name_prefix=(prefix)
38
+ #
39
+ # Sets the prefix string to prepend to every table name. So if set to "basecamp_", all table
40
+ # names will be named like "basecamp_projects", "basecamp_people", etc. This is a convenient
41
+ # way of creating a namespace for tables in a shared database. By default, the prefix is the
42
+ # empty string.
43
+ #
44
+ # If you are organising your models within modules you can add a prefix to the models within
45
+ # a namespace by defining a singleton method in the parent module called table_name_prefix which
46
+ # returns your chosen prefix.
47
+
48
+ ##
49
+ # :singleton-method: table_name_suffix
50
+ # :call-seq: table_name_suffix
51
+ #
52
+ # The suffix string to append to every table name.
53
+
54
+ ##
55
+ # :singleton-method: table_name_suffix=
56
+ # :call-seq: table_name_suffix=(suffix)
57
+ #
58
+ # Works like +table_name_prefix=+, but appends instead of prepends (set to "_basecamp" gives "projects_basecamp",
59
+ # "people_basecamp"). By default, the suffix is the empty string.
60
+ #
61
+ # If you are organising your models within modules, you can add a suffix to the models within
62
+ # a namespace by defining a singleton method in the parent module called table_name_suffix which
63
+ # returns your chosen suffix.
64
+
65
+ ##
66
+ # :singleton-method: schema_migrations_table_name
67
+ # :call-seq: schema_migrations_table_name
68
+ #
69
+ # The name of the schema migrations table. By default, the value is <tt>"schema_migrations"</tt>.
70
+
71
+ ##
72
+ # :singleton-method: schema_migrations_table_name=
73
+ # :call-seq: schema_migrations_table_name=(table_name)
74
+ #
75
+ # Sets the name of the schema migrations table.
76
+
77
+ ##
78
+ # :singleton-method: internal_metadata_table_name
79
+ # :call-seq: internal_metadata_table_name
80
+ #
81
+ # The name of the internal metadata table. By default, the value is <tt>"ar_internal_metadata"</tt>.
82
+
83
+ ##
84
+ # :singleton-method: internal_metadata_table_name=
85
+ # :call-seq: internal_metadata_table_name=(table_name)
86
+ #
87
+ # Sets the name of the internal metadata table.
88
+
89
+ ##
90
+ # :singleton-method: pluralize_table_names
91
+ # :call-seq: pluralize_table_names
92
+ #
93
+ # Indicates whether table names should be the pluralized versions of the corresponding class names.
94
+ # If true, the default table name for a Product class will be "products". If false, it would just be "product".
95
+ # See table_name for the full rules on table/class naming. This is true, by default.
96
+
97
+ ##
98
+ # :singleton-method: pluralize_table_names=
99
+ # :call-seq: pluralize_table_names=(value)
100
+ #
101
+ # Set whether table names should be the pluralized versions of the corresponding class names.
102
+ # If true, the default table name for a Product class will be "products". If false, it would just be "product".
103
+ # See table_name for the full rules on table/class naming. This is true, by default.
104
+
105
+ ##
106
+ # :singleton-method: implicit_order_column
107
+ # :call-seq: implicit_order_column
108
+ #
109
+ # The name of the column records are ordered by if no explicit order clause
110
+ # is used during an ordered finder call. If not set the primary key is used.
111
+
112
+ ##
113
+ # :singleton-method: implicit_order_column=
114
+ # :call-seq: implicit_order_column=(column_name)
115
+ #
116
+ # Sets the column to sort records by when no explicit order clause is used
117
+ # during an ordered finder call. Useful when the primary key is not an
118
+ # auto-incrementing integer, for example when it's a UUID. Note that using
119
+ # a non-unique column can result in non-deterministic results.
7
120
  included do
8
- ##
9
- # :singleton-method:
10
- # Accessor for the prefix type that will be prepended to every primary key column name.
11
- # The options are :table_name and :table_name_with_underscore. If the first is specified,
12
- # the Product class will look for "productid" instead of "id" as the primary column. If the
13
- # latter is specified, the Product class will look for "product_id" instead of "id". Remember
14
- # that this is a global setting for all Active Records.
15
- cattr_accessor :primary_key_prefix_type, :instance_writer => false
16
- self.primary_key_prefix_type = nil
17
-
18
- ##
19
- # :singleton-method:
20
- # Accessor for the name of the prefix string to prepend to every table name. So if set
21
- # to "basecamp_", all table names will be named like "basecamp_projects", "basecamp_people",
22
- # etc. This is a convenient way of creating a namespace for tables in a shared database.
23
- # By default, the prefix is the empty string.
24
- #
25
- # If you are organising your models within modules you can add a prefix to the models within
26
- # a namespace by defining a singleton method in the parent module called table_name_prefix which
27
- # returns your chosen prefix.
28
- class_attribute :table_name_prefix, :instance_writer => false
29
- self.table_name_prefix = ""
30
-
31
- ##
32
- # :singleton-method:
33
- # Works like +table_name_prefix+, but appends instead of prepends (set to "_basecamp" gives "projects_basecamp",
34
- # "people_basecamp"). By default, the suffix is the empty string.
35
- class_attribute :table_name_suffix, :instance_writer => false
36
- self.table_name_suffix = ""
37
-
38
- ##
39
- # :singleton-method:
40
- # Indicates whether table names should be the pluralized versions of the corresponding class names.
41
- # If true, the default table name for a Product class will be +products+. If false, it would just be +product+.
42
- # See table_name for the full rules on table/class naming. This is true, by default.
43
- class_attribute :pluralize_table_names, :instance_writer => false
44
- self.pluralize_table_names = true
121
+ mattr_accessor :primary_key_prefix_type, instance_writer: false
122
+
123
+ class_attribute :table_name_prefix, instance_writer: false, default: ""
124
+ class_attribute :table_name_suffix, instance_writer: false, default: ""
125
+ class_attribute :schema_migrations_table_name, instance_accessor: false, default: "schema_migrations"
126
+ class_attribute :internal_metadata_table_name, instance_accessor: false, default: "ar_internal_metadata"
127
+ class_attribute :pluralize_table_names, instance_writer: false, default: true
128
+ class_attribute :implicit_order_column, instance_accessor: false
129
+
130
+ self.protected_environments = ["production"]
131
+ self.inheritance_column = "type"
132
+ self.ignored_columns = [].freeze
133
+
134
+ delegate :type_for_attribute, to: :class
135
+
136
+ initialize_load_schema_monitor
137
+ end
138
+
139
+ # Derives the join table name for +first_table+ and +second_table+. The
140
+ # table names appear in alphabetical order. A common prefix is removed
141
+ # (useful for namespaced models like Music::Artist and Music::Record):
142
+ #
143
+ # artists, records => artists_records
144
+ # records, artists => artists_records
145
+ # music_artists, music_records => music_artists_records
146
+ def self.derive_join_table_name(first_table, second_table) # :nodoc:
147
+ [first_table.to_s, second_table.to_s].sort.join("\0").gsub(/^(.*_)(.+)\0\1(.+)/, '\1\2_\3').tr("\0", "_")
45
148
  end
46
149
 
47
150
  module ClassMethods
@@ -89,47 +192,29 @@ module ActiveRecord
89
192
  # class Mouse < ActiveRecord::Base
90
193
  # self.table_name = "mice"
91
194
  # end
92
- #
93
- # Alternatively, you can override the table_name method to define your
94
- # own computation. (Possibly using <tt>super</tt> to manipulate the default
95
- # table name.) Example:
96
- #
97
- # class Post < ActiveRecord::Base
98
- # def self.table_name
99
- # "special_" + super
100
- # end
101
- # end
102
- # Post.table_name # => "special_posts"
103
195
  def table_name
104
196
  reset_table_name unless defined?(@table_name)
105
197
  @table_name
106
198
  end
107
199
 
108
- def original_table_name #:nodoc:
109
- deprecated_original_property_getter :table_name
110
- end
111
-
112
200
  # Sets the table name explicitly. Example:
113
201
  #
114
202
  # class Project < ActiveRecord::Base
115
203
  # self.table_name = "project"
116
204
  # end
117
- #
118
- # You can also just define your own <tt>self.table_name</tt> method; see
119
- # the documentation for ActiveRecord::Base#table_name.
120
205
  def table_name=(value)
121
- @original_table_name = @table_name if defined?(@table_name)
122
- @table_name = value && value.to_s
123
- @quoted_table_name = nil
124
- @arel_table = nil
125
- @relation = Relation.new(self, arel_table)
126
- end
206
+ value = value && value.to_s
207
+
208
+ if defined?(@table_name)
209
+ return if value == @table_name
210
+ reset_column_information if connected?
211
+ end
127
212
 
128
- def set_table_name(value = nil, &block) #:nodoc:
129
- deprecated_property_setter :table_name, value, block
213
+ @table_name = value
130
214
  @quoted_table_name = nil
131
215
  @arel_table = nil
132
- @relation = Relation.new(self, arel_table)
216
+ @sequence_name = nil unless defined?(@explicit_sequence_name) && @explicit_sequence_name
217
+ @predicate_builder = nil
133
218
  end
134
219
 
135
220
  # Returns a quoted version of the table name, used to construct SQL statements.
@@ -139,68 +224,92 @@ module ActiveRecord
139
224
 
140
225
  # Computes the table name, (re)sets it internally, and returns it.
141
226
  def reset_table_name #:nodoc:
142
- if abstract_class?
143
- self.table_name = if superclass == Base || superclass.abstract_class?
144
- nil
145
- else
146
- superclass.table_name
147
- end
227
+ self.table_name = if abstract_class?
228
+ superclass == Base ? nil : superclass.table_name
148
229
  elsif superclass.abstract_class?
149
- self.table_name = superclass.table_name || compute_table_name
230
+ superclass.table_name || compute_table_name
150
231
  else
151
- self.table_name = compute_table_name
232
+ compute_table_name
152
233
  end
153
234
  end
154
235
 
155
236
  def full_table_name_prefix #:nodoc:
156
- (parents.detect{ |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix
237
+ (module_parents.detect { |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix
157
238
  end
158
239
 
159
- # The name of the column containing the object's class when Single Table Inheritance is used
160
- def inheritance_column
161
- if self == Base
162
- 'type'
240
+ def full_table_name_suffix #:nodoc:
241
+ (module_parents.detect { |p| p.respond_to?(:table_name_suffix) } || self).table_name_suffix
242
+ end
243
+
244
+ # The array of names of environments where destructive actions should be prohibited. By default,
245
+ # the value is <tt>["production"]</tt>.
246
+ def protected_environments
247
+ if defined?(@protected_environments)
248
+ @protected_environments
163
249
  else
164
- (@inheritance_column ||= nil) || superclass.inheritance_column
250
+ superclass.protected_environments
165
251
  end
166
252
  end
167
253
 
168
- def original_inheritance_column #:nodoc:
169
- deprecated_original_property_getter :inheritance_column
254
+ # Sets an array of names of environments where destructive actions should be prohibited.
255
+ def protected_environments=(environments)
256
+ @protected_environments = environments.map(&:to_s)
257
+ end
258
+
259
+ # Defines the name of the table column which will store the class name on single-table
260
+ # inheritance situations.
261
+ #
262
+ # The default inheritance column name is +type+, which means it's a
263
+ # reserved word inside Active Record. To be able to use single-table
264
+ # inheritance with another column name, or to use the column +type+ in
265
+ # your own model for something else, you can set +inheritance_column+:
266
+ #
267
+ # self.inheritance_column = 'zoink'
268
+ def inheritance_column
269
+ (@inheritance_column ||= nil) || superclass.inheritance_column
170
270
  end
171
271
 
172
272
  # Sets the value of inheritance_column
173
273
  def inheritance_column=(value)
174
- @original_inheritance_column = inheritance_column
175
- @inheritance_column = value.to_s
274
+ @inheritance_column = value.to_s
275
+ @explicit_inheritance_column = true
276
+ end
277
+
278
+ # The list of columns names the model should ignore. Ignored columns won't have attribute
279
+ # accessors defined, and won't be referenced in SQL queries.
280
+ def ignored_columns
281
+ if defined?(@ignored_columns)
282
+ @ignored_columns
283
+ else
284
+ superclass.ignored_columns
285
+ end
176
286
  end
177
287
 
178
- def set_inheritance_column(value = nil, &block) #:nodoc:
179
- deprecated_property_setter :inheritance_column, value, block
288
+ # Sets the columns names the model should ignore. Ignored columns won't have attribute
289
+ # accessors defined, and won't be referenced in SQL queries.
290
+ def ignored_columns=(columns)
291
+ @ignored_columns = columns.map(&:to_s)
180
292
  end
181
293
 
182
294
  def sequence_name
183
- if base_class == self
295
+ if base_class?
184
296
  @sequence_name ||= reset_sequence_name
185
297
  else
186
298
  (@sequence_name ||= nil) || base_class.sequence_name
187
299
  end
188
300
  end
189
301
 
190
- def original_sequence_name #:nodoc:
191
- deprecated_original_property_getter :sequence_name
192
- end
193
-
194
302
  def reset_sequence_name #:nodoc:
195
- self.sequence_name = connection.default_sequence_name(table_name, primary_key)
303
+ @explicit_sequence_name = false
304
+ @sequence_name = connection.default_sequence_name(table_name, primary_key)
196
305
  end
197
306
 
198
307
  # Sets the name of the sequence to use when generating ids to the given
199
- # value, or (if the value is nil or false) to the value returned by the
308
+ # value, or (if the value is +nil+ or +false+) to the value returned by the
200
309
  # given block. This is required for Oracle and is useful for any
201
310
  # database which relies on sequences for primary key generation.
202
311
  #
203
- # If a sequence name is not explicitly set when using Oracle or Firebird,
312
+ # If a sequence name is not explicitly set when using Oracle,
204
313
  # it will default to the commonly used pattern of: #{table_name}_seq
205
314
  #
206
315
  # If a sequence name is not explicitly set when using PostgreSQL, it
@@ -210,61 +319,104 @@ module ActiveRecord
210
319
  # self.sequence_name = "projectseq" # default would have been "project_seq"
211
320
  # end
212
321
  def sequence_name=(value)
213
- @original_sequence_name = @sequence_name if defined?(@sequence_name)
214
322
  @sequence_name = value.to_s
323
+ @explicit_sequence_name = true
215
324
  end
216
325
 
217
- def set_sequence_name(value = nil, &block) #:nodoc:
218
- deprecated_property_setter :sequence_name, value, block
326
+ # Determines if the primary key values should be selected from their
327
+ # corresponding sequence before the insert statement.
328
+ def prefetch_primary_key?
329
+ connection.prefetch_primary_key?(table_name)
330
+ end
331
+
332
+ # Returns the next value that will be used as the primary key on
333
+ # an insert statement.
334
+ def next_sequence_value
335
+ connection.next_sequence_value(sequence_name)
219
336
  end
220
337
 
221
338
  # Indicates whether the table associated with this class exists
222
339
  def table_exists?
223
- connection.schema_cache.table_exists?(table_name)
340
+ connection.schema_cache.data_source_exists?(table_name)
224
341
  end
225
342
 
226
- # Returns an array of column objects for the table associated with this class.
227
- def columns
228
- @columns ||= connection.schema_cache.columns[table_name].map do |col|
229
- col = col.dup
230
- col.primary = (col.name == primary_key)
231
- col
343
+ def attributes_builder # :nodoc:
344
+ unless defined?(@attributes_builder) && @attributes_builder
345
+ defaults = _default_attributes.except(*(column_names - [primary_key]))
346
+ @attributes_builder = ActiveModel::AttributeSet::Builder.new(attribute_types, defaults)
232
347
  end
348
+ @attributes_builder
233
349
  end
234
350
 
235
- # Returns a hash of column objects for the table associated with this class.
236
- def columns_hash
237
- @columns_hash ||= Hash[columns.map { |c| [c.name, c] }]
351
+ def columns_hash # :nodoc:
352
+ load_schema
353
+ @columns_hash
354
+ end
355
+
356
+ def columns
357
+ load_schema
358
+ @columns ||= columns_hash.values
359
+ end
360
+
361
+ def attribute_types # :nodoc:
362
+ load_schema
363
+ @attribute_types ||= Hash.new(Type.default_value)
364
+ end
365
+
366
+ def yaml_encoder # :nodoc:
367
+ @yaml_encoder ||= ActiveModel::AttributeSet::YAMLEncoder.new(attribute_types)
368
+ end
369
+
370
+ # Returns the type of the attribute with the given name, after applying
371
+ # all modifiers. This method is the only valid source of information for
372
+ # anything related to the types of a model's attributes. This method will
373
+ # access the database and load the model's schema if it is required.
374
+ #
375
+ # The return value of this method will implement the interface described
376
+ # by ActiveModel::Type::Value (though the object itself may not subclass
377
+ # it).
378
+ #
379
+ # +attr_name+ The name of the attribute to retrieve the type for. Must be
380
+ # a string or a symbol.
381
+ def type_for_attribute(attr_name, &block)
382
+ attr_name = attr_name.to_s
383
+ if block
384
+ attribute_types.fetch(attr_name, &block)
385
+ else
386
+ attribute_types[attr_name]
387
+ end
238
388
  end
239
389
 
240
390
  # Returns a hash where the keys are column names and the values are
241
- # default values when instantiating the AR object for this table.
391
+ # default values when instantiating the Active Record object for this table.
242
392
  def column_defaults
243
- @column_defaults ||= Hash[columns.map { |c| [c.name, c.default] }]
393
+ load_schema
394
+ @column_defaults ||= _default_attributes.deep_dup.to_hash
395
+ end
396
+
397
+ def _default_attributes # :nodoc:
398
+ load_schema
399
+ @default_attributes ||= ActiveModel::AttributeSet.new({})
244
400
  end
245
401
 
246
402
  # Returns an array of column names as strings.
247
403
  def column_names
248
- @column_names ||= columns.map { |column| column.name }
404
+ @column_names ||= columns.map(&:name)
405
+ end
406
+
407
+ def symbol_column_to_string(name_symbol) # :nodoc:
408
+ @symbol_column_to_string_name_hash ||= column_names.index_by(&:to_sym)
409
+ @symbol_column_to_string_name_hash[name_symbol]
249
410
  end
250
411
 
251
412
  # Returns an array of column objects where the primary id, all columns ending in "_id" or "_count",
252
413
  # and columns used for single table inheritance have been removed.
253
414
  def content_columns
254
- @content_columns ||= columns.reject { |c| c.primary || c.name =~ /(_id|_count)$/ || c.name == inheritance_column }
255
- end
256
-
257
- # Returns a hash of all the methods added to query each of the columns in the table with the name of the method as the key
258
- # and true as the value. This makes it possible to do O(1) lookups in respond_to? to check if a given method for attribute
259
- # is available.
260
- def column_methods_hash #:nodoc:
261
- @dynamic_methods_hash ||= column_names.inject(Hash.new(false)) do |methods, attr|
262
- attr_name = attr.to_s
263
- methods[attr.to_sym] = attr_name
264
- methods["#{attr}=".to_sym] = attr_name
265
- methods["#{attr}?".to_sym] = attr_name
266
- methods["#{attr}_before_type_cast".to_sym] = attr_name
267
- methods
415
+ @content_columns ||= columns.reject do |c|
416
+ c.name == primary_key ||
417
+ c.name == inheritance_column ||
418
+ c.name.end_with?("_id") ||
419
+ c.name.end_with?("_count")
268
420
  end
269
421
  end
270
422
 
@@ -275,7 +427,7 @@ module ActiveRecord
275
427
  # when just after creating a table you want to populate it with some default
276
428
  # values, eg:
277
429
  #
278
- # class CreateJobLevels < ActiveRecord::Migration
430
+ # class CreateJobLevels < ActiveRecord::Migration[5.0]
279
431
  # def up
280
432
  # create_table :job_levels do |t|
281
433
  # t.integer :id
@@ -286,7 +438,7 @@ module ActiveRecord
286
438
  #
287
439
  # JobLevel.reset_column_information
288
440
  # %w{assistant executive manager director}.each do |type|
289
- # JobLevel.create(:name => type)
441
+ # JobLevel.create(name: type)
290
442
  # end
291
443
  # end
292
444
  #
@@ -296,71 +448,95 @@ module ActiveRecord
296
448
  # end
297
449
  def reset_column_information
298
450
  connection.clear_cache!
299
- undefine_attribute_methods
300
- connection.schema_cache.clear_table_cache!(table_name) if table_exists?
451
+ ([self] + descendants).each(&:undefine_attribute_methods)
452
+ connection.schema_cache.clear_data_source_cache!(table_name)
301
453
 
302
- @column_names = @content_columns = @column_defaults = @columns = @columns_hash = nil
303
- @dynamic_methods_hash = @inheritance_column = nil
304
- @arel_engine = @relation = nil
454
+ reload_schema_from_cache
455
+ initialize_find_by_cache
305
456
  end
306
457
 
307
- def clear_cache! # :nodoc:
308
- connection.schema_cache.clear!
309
- end
458
+ protected
459
+
460
+ def initialize_load_schema_monitor
461
+ @load_schema_monitor = Monitor.new
462
+ end
310
463
 
311
464
  private
312
465
 
313
- # Guesses the table name, but does not decorate it with prefix and suffix information.
314
- def undecorated_table_name(class_name = base_class.name)
315
- table_name = class_name.to_s.demodulize.underscore
316
- table_name = table_name.pluralize if pluralize_table_names
317
- table_name
318
- end
466
+ def inherited(child_class)
467
+ super
468
+ child_class.initialize_load_schema_monitor
469
+ end
319
470
 
320
- # Computes and returns a table name according to default conventions.
321
- def compute_table_name
322
- base = base_class
323
- if self == base
324
- # Nested classes are prefixed with singular parent table name.
325
- if parent < ActiveRecord::Base && !parent.abstract_class?
326
- contained = parent.table_name
327
- contained = contained.singularize if parent.pluralize_table_names
328
- contained += '_'
329
- end
330
- "#{full_table_name_prefix}#{contained}#{undecorated_table_name(name)}#{table_name_suffix}"
331
- else
332
- # STI subclasses always use their superclass' table.
333
- base.table_name
471
+ def schema_loaded?
472
+ defined?(@schema_loaded) && @schema_loaded
334
473
  end
335
- end
336
474
 
337
- def deprecated_property_setter(property, value, block)
338
- if block
339
- ActiveSupport::Deprecation.warn(
340
- "Calling set_#{property} is deprecated. If you need to lazily evaluate " \
341
- "the #{property}, define your own `self.#{property}` class method. You can use `super` " \
342
- "to get the default #{property} where you would have called `original_#{property}`."
343
- )
475
+ def load_schema
476
+ return if schema_loaded?
477
+ @load_schema_monitor.synchronize do
478
+ return if defined?(@columns_hash) && @columns_hash
344
479
 
345
- define_attr_method property, value, false, &block
346
- else
347
- ActiveSupport::Deprecation.warn(
348
- "Calling set_#{property} is deprecated. Please use `self.#{property} = 'the_name'` instead."
349
- )
480
+ load_schema!
350
481
 
351
- define_attr_method property, value, false
482
+ @schema_loaded = true
483
+ end
352
484
  end
353
- end
354
485
 
355
- def deprecated_original_property_getter(property)
356
- ActiveSupport::Deprecation.warn("original_#{property} is deprecated. Define self.#{property} and call super instead.")
486
+ def load_schema!
487
+ @columns_hash = connection.schema_cache.columns_hash(table_name).except(*ignored_columns)
488
+ @columns_hash.each do |name, column|
489
+ define_attribute(
490
+ name,
491
+ connection.lookup_cast_type_from_column(column),
492
+ default: column.default,
493
+ user_provided_default: false
494
+ )
495
+ end
496
+ end
357
497
 
358
- if !instance_variable_defined?("@original_#{property}") && respond_to?("reset_#{property}")
359
- send("reset_#{property}")
360
- else
361
- instance_variable_get("@original_#{property}")
498
+ def reload_schema_from_cache
499
+ @arel_table = nil
500
+ @column_names = nil
501
+ @symbol_column_to_string_name_hash = nil
502
+ @attribute_types = nil
503
+ @content_columns = nil
504
+ @default_attributes = nil
505
+ @column_defaults = nil
506
+ @inheritance_column = nil unless defined?(@explicit_inheritance_column) && @explicit_inheritance_column
507
+ @attributes_builder = nil
508
+ @columns = nil
509
+ @columns_hash = nil
510
+ @schema_loaded = false
511
+ @attribute_names = nil
512
+ @yaml_encoder = nil
513
+ direct_descendants.each do |descendant|
514
+ descendant.send(:reload_schema_from_cache)
515
+ end
516
+ end
517
+
518
+ # Guesses the table name, but does not decorate it with prefix and suffix information.
519
+ def undecorated_table_name(class_name = base_class.name)
520
+ table_name = class_name.to_s.demodulize.underscore
521
+ pluralize_table_names ? table_name.pluralize : table_name
522
+ end
523
+
524
+ # Computes and returns a table name according to default conventions.
525
+ def compute_table_name
526
+ if base_class?
527
+ # Nested classes are prefixed with singular parent table name.
528
+ if module_parent < Base && !module_parent.abstract_class?
529
+ contained = module_parent.table_name
530
+ contained = contained.singularize if module_parent.pluralize_table_names
531
+ contained += "_"
532
+ end
533
+
534
+ "#{full_table_name_prefix}#{contained}#{undecorated_table_name(name)}#{full_table_name_suffix}"
535
+ else
536
+ # STI subclasses always use their superclass' table.
537
+ base_class.table_name
538
+ end
362
539
  end
363
- end
364
540
  end
365
541
  end
366
542
  end