activerecord 5.1.0 → 5.2.3

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 (261) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +596 -450
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -5
  5. data/examples/performance.rb +2 -0
  6. data/examples/simple.rb +2 -0
  7. data/lib/active_record.rb +11 -4
  8. data/lib/active_record/aggregations.rb +6 -5
  9. data/lib/active_record/association_relation.rb +7 -5
  10. data/lib/active_record/associations.rb +77 -85
  11. data/lib/active_record/associations/alias_tracker.rb +23 -32
  12. data/lib/active_record/associations/association.rb +49 -35
  13. data/lib/active_record/associations/association_scope.rb +55 -55
  14. data/lib/active_record/associations/belongs_to_association.rb +30 -11
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
  16. data/lib/active_record/associations/builder/association.rb +4 -7
  17. data/lib/active_record/associations/builder/belongs_to.rb +21 -8
  18. data/lib/active_record/associations/builder/collection_association.rb +1 -1
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
  20. data/lib/active_record/associations/builder/has_many.rb +2 -0
  21. data/lib/active_record/associations/builder/has_one.rb +2 -0
  22. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  23. data/lib/active_record/associations/collection_association.rb +66 -53
  24. data/lib/active_record/associations/collection_proxy.rb +30 -73
  25. data/lib/active_record/associations/foreign_association.rb +2 -0
  26. data/lib/active_record/associations/has_many_association.rb +13 -2
  27. data/lib/active_record/associations/has_many_through_association.rb +37 -19
  28. data/lib/active_record/associations/has_one_association.rb +14 -1
  29. data/lib/active_record/associations/has_one_through_association.rb +13 -8
  30. data/lib/active_record/associations/join_dependency.rb +52 -96
  31. data/lib/active_record/associations/join_dependency/join_association.rb +22 -75
  32. data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
  33. data/lib/active_record/associations/join_dependency/join_part.rb +9 -9
  34. data/lib/active_record/associations/preloader.rb +17 -37
  35. data/lib/active_record/associations/preloader/association.rb +53 -92
  36. data/lib/active_record/associations/preloader/through_association.rb +72 -73
  37. data/lib/active_record/associations/singular_association.rb +14 -16
  38. data/lib/active_record/associations/through_association.rb +27 -12
  39. data/lib/active_record/attribute_assignment.rb +2 -5
  40. data/lib/active_record/attribute_decorators.rb +3 -2
  41. data/lib/active_record/attribute_methods.rb +65 -24
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
  43. data/lib/active_record/attribute_methods/dirty.rb +33 -216
  44. data/lib/active_record/attribute_methods/primary_key.rb +10 -13
  45. data/lib/active_record/attribute_methods/query.rb +2 -0
  46. data/lib/active_record/attribute_methods/read.rb +9 -3
  47. data/lib/active_record/attribute_methods/serialization.rb +23 -0
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
  49. data/lib/active_record/attribute_methods/write.rb +22 -19
  50. data/lib/active_record/attributes.rb +7 -6
  51. data/lib/active_record/autosave_association.rb +15 -13
  52. data/lib/active_record/base.rb +2 -0
  53. data/lib/active_record/callbacks.rb +12 -6
  54. data/lib/active_record/coders/json.rb +2 -0
  55. data/lib/active_record/coders/yaml_column.rb +2 -0
  56. data/lib/active_record/collection_cache_key.rb +15 -11
  57. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +120 -39
  58. data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -0
  59. data/lib/active_record/connection_adapters/abstract/database_statements.rb +192 -37
  60. data/lib/active_record/connection_adapters/abstract/query_cache.rb +13 -2
  61. data/lib/active_record/connection_adapters/abstract/quoting.rb +15 -25
  62. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +15 -6
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +65 -7
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +158 -87
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -21
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +86 -98
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +126 -189
  70. data/lib/active_record/connection_adapters/column.rb +4 -2
  71. data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
  72. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +13 -2
  73. data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
  74. data/lib/active_record/connection_adapters/mysql/database_statements.rb +45 -15
  75. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
  76. data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
  77. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
  78. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -10
  79. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -23
  80. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +106 -1
  81. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
  82. data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
  83. data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
  84. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -32
  85. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid.rb +3 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +13 -1
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  95. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  99. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
  101. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +8 -2
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
  106. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  109. data/lib/active_record/connection_adapters/postgresql/quoting.rb +22 -1
  110. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  111. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +50 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
  113. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
  114. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +258 -129
  115. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
  116. data/lib/active_record/connection_adapters/postgresql/utils.rb +3 -1
  117. data/lib/active_record/connection_adapters/postgresql_adapter.rb +75 -87
  118. data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
  119. data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +24 -1
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
  124. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
  125. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +75 -1
  126. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +90 -96
  127. data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
  128. data/lib/active_record/connection_handling.rb +4 -2
  129. data/lib/active_record/core.rb +41 -61
  130. data/lib/active_record/counter_cache.rb +20 -15
  131. data/lib/active_record/define_callbacks.rb +5 -3
  132. data/lib/active_record/dynamic_matchers.rb +9 -9
  133. data/lib/active_record/enum.rb +18 -13
  134. data/lib/active_record/errors.rb +60 -15
  135. data/lib/active_record/explain.rb +3 -1
  136. data/lib/active_record/explain_registry.rb +2 -0
  137. data/lib/active_record/explain_subscriber.rb +2 -0
  138. data/lib/active_record/fixture_set/file.rb +2 -0
  139. data/lib/active_record/fixtures.rb +67 -60
  140. data/lib/active_record/gem_version.rb +4 -2
  141. data/lib/active_record/inheritance.rb +49 -19
  142. data/lib/active_record/integration.rb +58 -19
  143. data/lib/active_record/internal_metadata.rb +2 -0
  144. data/lib/active_record/legacy_yaml_adapter.rb +3 -1
  145. data/lib/active_record/locking/optimistic.rb +30 -42
  146. data/lib/active_record/locking/pessimistic.rb +10 -7
  147. data/lib/active_record/log_subscriber.rb +46 -4
  148. data/lib/active_record/migration.rb +189 -139
  149. data/lib/active_record/migration/command_recorder.rb +11 -9
  150. data/lib/active_record/migration/compatibility.rb +81 -29
  151. data/lib/active_record/migration/join_table.rb +2 -0
  152. data/lib/active_record/model_schema.rb +74 -58
  153. data/lib/active_record/nested_attributes.rb +18 -6
  154. data/lib/active_record/no_touching.rb +3 -1
  155. data/lib/active_record/null_relation.rb +2 -0
  156. data/lib/active_record/persistence.rb +199 -54
  157. data/lib/active_record/query_cache.rb +8 -10
  158. data/lib/active_record/querying.rb +5 -3
  159. data/lib/active_record/railtie.rb +62 -6
  160. data/lib/active_record/railties/console_sandbox.rb +2 -0
  161. data/lib/active_record/railties/controller_runtime.rb +2 -0
  162. data/lib/active_record/railties/databases.rake +48 -38
  163. data/lib/active_record/readonly_attributes.rb +3 -2
  164. data/lib/active_record/reflection.rb +137 -207
  165. data/lib/active_record/relation.rb +132 -207
  166. data/lib/active_record/relation/batches.rb +32 -17
  167. data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
  168. data/lib/active_record/relation/calculations.rb +66 -25
  169. data/lib/active_record/relation/delegation.rb +45 -29
  170. data/lib/active_record/relation/finder_methods.rb +76 -85
  171. data/lib/active_record/relation/from_clause.rb +2 -8
  172. data/lib/active_record/relation/merger.rb +53 -23
  173. data/lib/active_record/relation/predicate_builder.rb +60 -79
  174. data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
  175. data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
  176. data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
  177. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
  178. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
  179. data/lib/active_record/relation/predicate_builder/range_handler.rb +26 -9
  180. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  181. data/lib/active_record/relation/query_attribute.rb +28 -2
  182. data/lib/active_record/relation/query_methods.rb +135 -103
  183. data/lib/active_record/relation/record_fetch_warning.rb +2 -0
  184. data/lib/active_record/relation/spawn_methods.rb +4 -2
  185. data/lib/active_record/relation/where_clause.rb +65 -67
  186. data/lib/active_record/relation/where_clause_factory.rb +5 -48
  187. data/lib/active_record/result.rb +2 -0
  188. data/lib/active_record/runtime_registry.rb +2 -0
  189. data/lib/active_record/sanitization.rb +129 -121
  190. data/lib/active_record/schema.rb +4 -2
  191. data/lib/active_record/schema_dumper.rb +36 -26
  192. data/lib/active_record/schema_migration.rb +2 -0
  193. data/lib/active_record/scoping.rb +12 -10
  194. data/lib/active_record/scoping/default.rb +10 -7
  195. data/lib/active_record/scoping/named.rb +40 -12
  196. data/lib/active_record/secure_token.rb +2 -0
  197. data/lib/active_record/serialization.rb +2 -0
  198. data/lib/active_record/statement_cache.rb +22 -12
  199. data/lib/active_record/store.rb +3 -1
  200. data/lib/active_record/suppressor.rb +2 -0
  201. data/lib/active_record/table_metadata.rb +12 -3
  202. data/lib/active_record/tasks/database_tasks.rb +38 -26
  203. data/lib/active_record/tasks/mysql_database_tasks.rb +11 -50
  204. data/lib/active_record/tasks/postgresql_database_tasks.rb +11 -3
  205. data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
  206. data/lib/active_record/timestamp.rb +13 -6
  207. data/lib/active_record/touch_later.rb +2 -0
  208. data/lib/active_record/transactions.rb +32 -27
  209. data/lib/active_record/translation.rb +2 -0
  210. data/lib/active_record/type.rb +4 -1
  211. data/lib/active_record/type/adapter_specific_registry.rb +2 -0
  212. data/lib/active_record/type/date.rb +2 -0
  213. data/lib/active_record/type/date_time.rb +2 -0
  214. data/lib/active_record/type/decimal_without_scale.rb +2 -0
  215. data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
  216. data/lib/active_record/type/internal/timezone.rb +2 -0
  217. data/lib/active_record/type/json.rb +30 -0
  218. data/lib/active_record/type/serialized.rb +6 -0
  219. data/lib/active_record/type/text.rb +2 -0
  220. data/lib/active_record/type/time.rb +2 -0
  221. data/lib/active_record/type/type_map.rb +2 -0
  222. data/lib/active_record/type/unsigned_integer.rb +2 -0
  223. data/lib/active_record/type_caster.rb +2 -0
  224. data/lib/active_record/type_caster/connection.rb +2 -0
  225. data/lib/active_record/type_caster/map.rb +3 -1
  226. data/lib/active_record/validations.rb +2 -0
  227. data/lib/active_record/validations/absence.rb +2 -0
  228. data/lib/active_record/validations/associated.rb +2 -0
  229. data/lib/active_record/validations/length.rb +2 -0
  230. data/lib/active_record/validations/presence.rb +2 -0
  231. data/lib/active_record/validations/uniqueness.rb +36 -6
  232. data/lib/active_record/version.rb +2 -0
  233. data/lib/rails/generators/active_record.rb +3 -1
  234. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  235. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  236. data/lib/rails/generators/active_record/migration.rb +2 -0
  237. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
  238. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
  239. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
  240. data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
  241. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
  242. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  243. metadata +24 -36
  244. data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
  245. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  246. data/lib/active_record/associations/preloader/has_many.rb +0 -15
  247. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  248. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  249. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  250. data/lib/active_record/associations/preloader/singular_association.rb +0 -18
  251. data/lib/active_record/attribute.rb +0 -240
  252. data/lib/active_record/attribute/user_provided_default.rb +0 -30
  253. data/lib/active_record/attribute_mutation_tracker.rb +0 -113
  254. data/lib/active_record/attribute_set.rb +0 -113
  255. data/lib/active_record/attribute_set/builder.rb +0 -124
  256. data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
  257. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
  258. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  259. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  260. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
  261. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  class Migration
3
5
  # <tt>ActiveRecord::Migration::CommandRecorder</tt> records commands done during
@@ -92,10 +94,6 @@ module ActiveRecord
92
94
  send(method, args, &block)
93
95
  end
94
96
 
95
- def respond_to_missing?(*args) # :nodoc:
96
- super || delegate.respond_to?(*args)
97
- end
98
-
99
97
  ReversibleAndIrreversibleMethods.each do |method|
100
98
  class_eval <<-EOV, __FILE__, __LINE__ + 1
101
99
  def #{method}(*args, &block) # def create_table(*args, &block)
@@ -112,7 +110,7 @@ module ActiveRecord
112
110
 
113
111
  private
114
112
 
115
- module StraightReversions
113
+ module StraightReversions # :nodoc:
116
114
  private
117
115
  { transaction: :transaction,
118
116
  execute_block: :execute_block,
@@ -163,8 +161,8 @@ module ActiveRecord
163
161
  table, columns, options = *args
164
162
  options ||= {}
165
163
 
166
- index_name = options[:name]
167
- options_hash = index_name ? { name: index_name } : { column: columns }
164
+ options_hash = options.slice(:name, :algorithm)
165
+ options_hash[:column] = columns if !options_hash[:name]
168
166
 
169
167
  [:remove_index, [table, options_hash]]
170
168
  end
@@ -225,10 +223,14 @@ module ActiveRecord
225
223
  [:add_foreign_key, reversed_args]
226
224
  end
227
225
 
226
+ def respond_to_missing?(method, _)
227
+ super || delegate.respond_to?(method)
228
+ end
229
+
228
230
  # Forwards any missing method call to the \target.
229
231
  def method_missing(method, *args, &block)
230
- if @delegate.respond_to?(method)
231
- @delegate.send(method, *args, &block)
232
+ if delegate.respond_to?(method)
233
+ delegate.public_send(method, *args, &block)
232
234
  else
233
235
  super
234
236
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  class Migration
3
5
  module Compatibility # :nodoc: all
@@ -11,10 +13,36 @@ module ActiveRecord
11
13
  const_get(name)
12
14
  end
13
15
 
14
- V5_1 = Current
16
+ V5_2 = Current
17
+
18
+ class V5_1 < V5_2
19
+ def change_column(table_name, column_name, type, options = {})
20
+ if connection.adapter_name == "PostgreSQL"
21
+ super(table_name, column_name, type, options.except(:default, :null, :comment))
22
+ connection.change_column_default(table_name, column_name, options[:default]) if options.key?(:default)
23
+ connection.change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
24
+ connection.change_column_comment(table_name, column_name, options[:comment]) if options.key?(:comment)
25
+ else
26
+ super
27
+ end
28
+ end
29
+
30
+ def create_table(table_name, options = {})
31
+ if connection.adapter_name == "Mysql2"
32
+ super(table_name, options: "ENGINE=InnoDB", **options)
33
+ else
34
+ super
35
+ end
36
+ end
37
+ end
15
38
 
16
39
  class V5_0 < V5_1
17
40
  module TableDefinition
41
+ def primary_key(name, type = :primary_key, **options)
42
+ type = :integer if type == :primary_key
43
+ super
44
+ end
45
+
18
46
  def references(*args, **options)
19
47
  super(*args, type: :integer, **options)
20
48
  end
@@ -22,19 +50,19 @@ module ActiveRecord
22
50
  end
23
51
 
24
52
  def create_table(table_name, options = {})
25
- if adapter_name == "PostgreSQL"
53
+ if connection.adapter_name == "PostgreSQL"
26
54
  if options[:id] == :uuid && !options.key?(:default)
27
55
  options[:default] = "uuid_generate_v4()"
28
56
  end
29
57
  end
30
58
 
31
- unless adapter_name == "Mysql2" && options[:id] == :bigint
59
+ unless connection.adapter_name == "Mysql2" && options[:id] == :bigint
32
60
  if [:integer, :bigint].include?(options[:id]) && !options.key?(:default)
33
61
  options[:default] = nil
34
62
  end
35
63
  end
36
64
 
37
- # Since 5.1 Postgres adapter uses bigserial type for primary
65
+ # Since 5.1 PostgreSQL adapter uses bigserial type for primary
38
66
  # keys by default and MySQL uses bigint. This compat layer makes old migrations utilize
39
67
  # serial/int type instead -- the way it used to work before 5.1.
40
68
  unless options.key?(:id)
@@ -42,11 +70,8 @@ module ActiveRecord
42
70
  end
43
71
 
44
72
  if block_given?
45
- super(table_name, options) do |t|
46
- class << t
47
- prepend TableDefinition
48
- end
49
- yield t
73
+ super do |t|
74
+ yield compatible_table_definition(t)
50
75
  end
51
76
  else
52
77
  super
@@ -55,21 +80,46 @@ module ActiveRecord
55
80
 
56
81
  def change_table(table_name, options = {})
57
82
  if block_given?
58
- super(table_name, options) do |t|
59
- class << t
60
- prepend TableDefinition
61
- end
62
- yield t
83
+ super do |t|
84
+ yield compatible_table_definition(t)
63
85
  end
64
86
  else
65
87
  super
66
88
  end
67
89
  end
68
90
 
91
+ def create_join_table(table_1, table_2, column_options: {}, **options)
92
+ column_options.reverse_merge!(type: :integer)
93
+
94
+ if block_given?
95
+ super do |t|
96
+ yield compatible_table_definition(t)
97
+ end
98
+ else
99
+ super
100
+ end
101
+ end
102
+
103
+ def add_column(table_name, column_name, type, options = {})
104
+ if type == :primary_key
105
+ type = :integer
106
+ options[:primary_key] = true
107
+ end
108
+ super
109
+ end
110
+
69
111
  def add_reference(table_name, ref_name, **options)
70
112
  super(table_name, ref_name, type: :integer, **options)
71
113
  end
72
114
  alias :add_belongs_to :add_reference
115
+
116
+ private
117
+ def compatible_table_definition(t)
118
+ class << t
119
+ prepend TableDefinition
120
+ end
121
+ t
122
+ end
73
123
  end
74
124
 
75
125
  class V4_2 < V5_0
@@ -88,11 +138,8 @@ module ActiveRecord
88
138
 
89
139
  def create_table(table_name, options = {})
90
140
  if block_given?
91
- super(table_name, options) do |t|
92
- class << t
93
- prepend TableDefinition
94
- end
95
- yield t
141
+ super do |t|
142
+ yield compatible_table_definition(t)
96
143
  end
97
144
  else
98
145
  super
@@ -101,11 +148,8 @@ module ActiveRecord
101
148
 
102
149
  def change_table(table_name, options = {})
103
150
  if block_given?
104
- super(table_name, options) do |t|
105
- class << t
106
- prepend TableDefinition
107
- end
108
- yield t
151
+ super do |t|
152
+ yield compatible_table_definition(t)
109
153
  end
110
154
  else
111
155
  super
@@ -129,7 +173,7 @@ module ActiveRecord
129
173
  if options[:name].present?
130
174
  options[:name].to_s
131
175
  else
132
- index_name(table_name, column: column_names)
176
+ connection.index_name(table_name, column: column_names)
133
177
  end
134
178
  super
135
179
  end
@@ -141,17 +185,25 @@ module ActiveRecord
141
185
  end
142
186
 
143
187
  private
188
+ def compatible_table_definition(t)
189
+ class << t
190
+ prepend TableDefinition
191
+ end
192
+ super
193
+ end
144
194
 
145
195
  def index_name_for_remove(table_name, options = {})
146
- index_name = index_name(table_name, options)
196
+ index_name = connection.index_name(table_name, options)
147
197
 
148
- unless index_name_exists?(table_name, index_name)
198
+ unless connection.index_name_exists?(table_name, index_name)
149
199
  if options.is_a?(Hash) && options.has_key?(:name)
150
200
  options_without_column = options.dup
151
201
  options_without_column.delete :column
152
- index_name_without_column = index_name(table_name, options_without_column)
202
+ index_name_without_column = connection.index_name(table_name, options_without_column)
153
203
 
154
- return index_name_without_column if index_name_exists?(table_name, index_name_without_column)
204
+ if connection.index_name_exists?(table_name, index_name_without_column)
205
+ return index_name_without_column
206
+ end
155
207
  end
156
208
 
157
209
  raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' does not exist"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  class Migration
3
5
  module JoinTable #:nodoc:
@@ -1,3 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "monitor"
4
+
1
5
  module ActiveRecord
2
6
  module ModelSchema
3
7
  extend ActiveSupport::Concern
@@ -82,19 +86,6 @@ module ActiveRecord
82
86
  #
83
87
  # Sets the name of the internal metadata table.
84
88
 
85
- ##
86
- # :singleton-method: protected_environments
87
- # :call-seq: protected_environments
88
- #
89
- # The array of names of environments where destructive actions should be prohibited. By default,
90
- # the value is <tt>["production"]</tt>.
91
-
92
- ##
93
- # :singleton-method: protected_environments=
94
- # :call-seq: protected_environments=(environments)
95
- #
96
- # Sets an array of names of environments where destructive actions should be prohibited.
97
-
98
89
  ##
99
90
  # :singleton-method: pluralize_table_names
100
91
  # :call-seq: pluralize_table_names
@@ -111,47 +102,22 @@ module ActiveRecord
111
102
  # If true, the default table name for a Product class will be "products". If false, it would just be "product".
112
103
  # See table_name for the full rules on table/class naming. This is true, by default.
113
104
 
114
- ##
115
- # :singleton-method: ignored_columns
116
- # :call-seq: ignored_columns
117
- #
118
- # The list of columns names the model should ignore. Ignored columns won't have attribute
119
- # accessors defined, and won't be referenced in SQL queries.
120
-
121
- ##
122
- # :singleton-method: ignored_columns=
123
- # :call-seq: ignored_columns=(columns)
124
- #
125
- # Sets the columns names the model should ignore. Ignored columns won't have attribute
126
- # accessors defined, and won't be referenced in SQL queries.
127
-
128
105
  included do
129
106
  mattr_accessor :primary_key_prefix_type, instance_writer: false
130
107
 
131
- class_attribute :table_name_prefix, instance_writer: false
132
- self.table_name_prefix = ""
133
-
134
- class_attribute :table_name_suffix, instance_writer: false
135
- self.table_name_suffix = ""
136
-
137
- class_attribute :schema_migrations_table_name, instance_accessor: false
138
- self.schema_migrations_table_name = "schema_migrations"
139
-
140
- class_attribute :internal_metadata_table_name, instance_accessor: false
141
- self.internal_metadata_table_name = "ar_internal_metadata"
108
+ class_attribute :table_name_prefix, instance_writer: false, default: ""
109
+ class_attribute :table_name_suffix, instance_writer: false, default: ""
110
+ class_attribute :schema_migrations_table_name, instance_accessor: false, default: "schema_migrations"
111
+ class_attribute :internal_metadata_table_name, instance_accessor: false, default: "ar_internal_metadata"
112
+ class_attribute :pluralize_table_names, instance_writer: false, default: true
142
113
 
143
- class_attribute :protected_environments, instance_accessor: false
144
114
  self.protected_environments = ["production"]
145
-
146
- class_attribute :pluralize_table_names, instance_writer: false
147
- self.pluralize_table_names = true
148
-
149
- class_attribute :ignored_columns, instance_accessor: false
150
- self.ignored_columns = [].freeze
151
-
152
115
  self.inheritance_column = "type"
116
+ self.ignored_columns = [].freeze
153
117
 
154
118
  delegate :type_for_attribute, to: :class
119
+
120
+ initialize_load_schema_monitor
155
121
  end
156
122
 
157
123
  # Derives the join table name for +first_table+ and +second_table+. The
@@ -259,6 +225,21 @@ module ActiveRecord
259
225
  (parents.detect { |p| p.respond_to?(:table_name_suffix) } || self).table_name_suffix
260
226
  end
261
227
 
228
+ # The array of names of environments where destructive actions should be prohibited. By default,
229
+ # the value is <tt>["production"]</tt>.
230
+ def protected_environments
231
+ if defined?(@protected_environments)
232
+ @protected_environments
233
+ else
234
+ superclass.protected_environments
235
+ end
236
+ end
237
+
238
+ # Sets an array of names of environments where destructive actions should be prohibited.
239
+ def protected_environments=(environments)
240
+ @protected_environments = environments.map(&:to_s)
241
+ end
242
+
262
243
  # Defines the name of the table column which will store the class name on single-table
263
244
  # inheritance situations.
264
245
  #
@@ -278,6 +259,22 @@ module ActiveRecord
278
259
  @explicit_inheritance_column = true
279
260
  end
280
261
 
262
+ # The list of columns names the model should ignore. Ignored columns won't have attribute
263
+ # accessors defined, and won't be referenced in SQL queries.
264
+ def ignored_columns
265
+ if defined?(@ignored_columns)
266
+ @ignored_columns
267
+ else
268
+ superclass.ignored_columns
269
+ end
270
+ end
271
+
272
+ # Sets the columns names the model should ignore. Ignored columns won't have attribute
273
+ # accessors defined, and won't be referenced in SQL queries.
274
+ def ignored_columns=(columns)
275
+ @ignored_columns = columns.map(&:to_s)
276
+ end
277
+
281
278
  def sequence_name
282
279
  if base_class == self
283
280
  @sequence_name ||= reset_sequence_name
@@ -328,11 +325,11 @@ module ActiveRecord
328
325
  end
329
326
 
330
327
  def attributes_builder # :nodoc:
331
- @attributes_builder ||= AttributeSet::Builder.new(attribute_types, primary_key) do |name|
332
- unless columns_hash.key?(name)
333
- _default_attributes[name].dup
334
- end
328
+ unless defined?(@attributes_builder) && @attributes_builder
329
+ defaults = _default_attributes.except(*(column_names - [primary_key]))
330
+ @attributes_builder = ActiveModel::AttributeSet::Builder.new(attribute_types, defaults)
335
331
  end
332
+ @attributes_builder
336
333
  end
337
334
 
338
335
  def columns_hash # :nodoc:
@@ -351,7 +348,7 @@ module ActiveRecord
351
348
  end
352
349
 
353
350
  def yaml_encoder # :nodoc:
354
- @yaml_encoder ||= AttributeSet::YAMLEncoder.new(attribute_types)
351
+ @yaml_encoder ||= ActiveModel::AttributeSet::YAMLEncoder.new(attribute_types)
355
352
  end
356
353
 
357
354
  # Returns the type of the attribute with the given name, after applying
@@ -364,8 +361,9 @@ module ActiveRecord
364
361
  # it).
365
362
  #
366
363
  # +attr_name+ The name of the attribute to retrieve the type for. Must be
367
- # a string
364
+ # a string or a symbol.
368
365
  def type_for_attribute(attr_name, &block)
366
+ attr_name = attr_name.to_s
369
367
  if block
370
368
  attribute_types.fetch(attr_name, &block)
371
369
  else
@@ -377,11 +375,12 @@ module ActiveRecord
377
375
  # default values when instantiating the Active Record object for this table.
378
376
  def column_defaults
379
377
  load_schema
380
- _default_attributes.to_hash
378
+ @column_defaults ||= _default_attributes.deep_dup.to_hash
381
379
  end
382
380
 
383
381
  def _default_attributes # :nodoc:
384
- @default_attributes ||= AttributeSet.new({})
382
+ load_schema
383
+ @default_attributes ||= ActiveModel::AttributeSet.new({})
385
384
  end
386
385
 
387
386
  # Returns an array of column names as strings.
@@ -428,22 +427,38 @@ module ActiveRecord
428
427
  # end
429
428
  def reset_column_information
430
429
  connection.clear_cache!
431
- undefine_attribute_methods
430
+ ([self] + descendants).each(&:undefine_attribute_methods)
432
431
  connection.schema_cache.clear_data_source_cache!(table_name)
433
432
 
434
433
  reload_schema_from_cache
435
434
  initialize_find_by_cache
436
435
  end
437
436
 
437
+ protected
438
+
439
+ def initialize_load_schema_monitor
440
+ @load_schema_monitor = Monitor.new
441
+ end
442
+
438
443
  private
439
444
 
445
+ def inherited(child_class)
446
+ super
447
+ child_class.initialize_load_schema_monitor
448
+ end
449
+
440
450
  def schema_loaded?
441
- defined?(@columns_hash) && @columns_hash
451
+ defined?(@schema_loaded) && @schema_loaded
442
452
  end
443
453
 
444
454
  def load_schema
445
- unless schema_loaded?
455
+ return if schema_loaded?
456
+ @load_schema_monitor.synchronize do
457
+ return if defined?(@columns_hash) && @columns_hash
458
+
446
459
  load_schema!
460
+
461
+ @schema_loaded = true
447
462
  end
448
463
  end
449
464
 
@@ -460,16 +475,17 @@ module ActiveRecord
460
475
  end
461
476
 
462
477
  def reload_schema_from_cache
463
- @arel_engine = nil
464
478
  @arel_table = nil
465
479
  @column_names = nil
466
480
  @attribute_types = nil
467
481
  @content_columns = nil
468
482
  @default_attributes = nil
483
+ @column_defaults = nil
469
484
  @inheritance_column = nil unless defined?(@explicit_inheritance_column) && @explicit_inheritance_column
470
485
  @attributes_builder = nil
471
486
  @columns = nil
472
487
  @columns_hash = nil
488
+ @schema_loaded = false
473
489
  @attribute_names = nil
474
490
  @yaml_encoder = nil
475
491
  direct_descendants.each do |descendant|