activerecord 5.1.7 → 5.2.8.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (261) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +629 -661
  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/aggregations.rb +6 -5
  8. data/lib/active_record/association_relation.rb +7 -5
  9. data/lib/active_record/associations/alias_tracker.rb +19 -27
  10. data/lib/active_record/associations/association.rb +41 -37
  11. data/lib/active_record/associations/association_scope.rb +38 -50
  12. data/lib/active_record/associations/belongs_to_association.rb +27 -8
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
  14. data/lib/active_record/associations/builder/association.rb +4 -7
  15. data/lib/active_record/associations/builder/belongs_to.rb +12 -4
  16. data/lib/active_record/associations/builder/collection_association.rb +3 -3
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
  18. data/lib/active_record/associations/builder/has_many.rb +2 -0
  19. data/lib/active_record/associations/builder/has_one.rb +2 -0
  20. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  21. data/lib/active_record/associations/collection_association.rb +59 -47
  22. data/lib/active_record/associations/collection_proxy.rb +20 -49
  23. data/lib/active_record/associations/foreign_association.rb +2 -0
  24. data/lib/active_record/associations/has_many_association.rb +12 -1
  25. data/lib/active_record/associations/has_many_through_association.rb +36 -30
  26. data/lib/active_record/associations/has_one_association.rb +12 -1
  27. data/lib/active_record/associations/has_one_through_association.rb +13 -8
  28. data/lib/active_record/associations/join_dependency/join_association.rb +39 -63
  29. data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
  30. data/lib/active_record/associations/join_dependency/join_part.rb +9 -9
  31. data/lib/active_record/associations/join_dependency.rb +48 -93
  32. data/lib/active_record/associations/preloader/association.rb +45 -61
  33. data/lib/active_record/associations/preloader/through_association.rb +71 -79
  34. data/lib/active_record/associations/preloader.rb +18 -38
  35. data/lib/active_record/associations/singular_association.rb +14 -16
  36. data/lib/active_record/associations/through_association.rb +26 -11
  37. data/lib/active_record/associations.rb +40 -63
  38. data/lib/active_record/attribute_assignment.rb +2 -5
  39. data/lib/active_record/attribute_decorators.rb +3 -2
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
  41. data/lib/active_record/attribute_methods/dirty.rb +30 -214
  42. data/lib/active_record/attribute_methods/primary_key.rb +7 -6
  43. data/lib/active_record/attribute_methods/query.rb +2 -0
  44. data/lib/active_record/attribute_methods/read.rb +9 -3
  45. data/lib/active_record/attribute_methods/serialization.rb +23 -0
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
  47. data/lib/active_record/attribute_methods/write.rb +21 -9
  48. data/lib/active_record/attribute_methods.rb +65 -24
  49. data/lib/active_record/attributes.rb +6 -5
  50. data/lib/active_record/autosave_association.rb +35 -19
  51. data/lib/active_record/base.rb +2 -0
  52. data/lib/active_record/callbacks.rb +8 -6
  53. data/lib/active_record/coders/json.rb +2 -0
  54. data/lib/active_record/coders/yaml_column.rb +15 -1
  55. data/lib/active_record/collection_cache_key.rb +12 -8
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +139 -41
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -0
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +174 -33
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +15 -5
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +13 -31
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +14 -5
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +64 -6
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +152 -81
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -21
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +84 -97
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +92 -165
  69. data/lib/active_record/connection_adapters/column.rb +3 -1
  70. data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +13 -2
  72. data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +47 -2
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -10
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -30
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +106 -1
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +2 -0
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -0
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +2 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +2 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
  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 -1
  97. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +5 -3
  99. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
  101. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +4 -2
  102. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
  104. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  107. data/lib/active_record/connection_adapters/postgresql/oid.rb +3 -1
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +18 -0
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  110. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +50 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
  112. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +233 -111
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +3 -1
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +57 -73
  117. data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
  118. data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
  119. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
  120. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +22 -0
  121. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
  123. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
  124. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +75 -1
  125. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +81 -94
  126. data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
  127. data/lib/active_record/connection_handling.rb +4 -2
  128. data/lib/active_record/core.rb +51 -61
  129. data/lib/active_record/counter_cache.rb +10 -3
  130. data/lib/active_record/define_callbacks.rb +5 -3
  131. data/lib/active_record/dynamic_matchers.rb +9 -9
  132. data/lib/active_record/enum.rb +18 -13
  133. data/lib/active_record/errors.rb +42 -3
  134. data/lib/active_record/explain.rb +3 -1
  135. data/lib/active_record/explain_registry.rb +2 -0
  136. data/lib/active_record/explain_subscriber.rb +2 -0
  137. data/lib/active_record/fixture_set/file.rb +2 -0
  138. data/lib/active_record/fixtures.rb +67 -60
  139. data/lib/active_record/gem_version.rb +5 -3
  140. data/lib/active_record/inheritance.rb +49 -19
  141. data/lib/active_record/integration.rb +58 -19
  142. data/lib/active_record/internal_metadata.rb +2 -0
  143. data/lib/active_record/legacy_yaml_adapter.rb +3 -1
  144. data/lib/active_record/locking/optimistic.rb +14 -17
  145. data/lib/active_record/locking/pessimistic.rb +9 -6
  146. data/lib/active_record/log_subscriber.rb +43 -0
  147. data/lib/active_record/migration/command_recorder.rb +11 -9
  148. data/lib/active_record/migration/compatibility.rb +47 -9
  149. data/lib/active_record/migration/join_table.rb +2 -0
  150. data/lib/active_record/migration.rb +189 -139
  151. data/lib/active_record/model_schema.rb +16 -21
  152. data/lib/active_record/nested_attributes.rb +18 -6
  153. data/lib/active_record/no_touching.rb +3 -1
  154. data/lib/active_record/null_relation.rb +2 -0
  155. data/lib/active_record/persistence.rb +167 -16
  156. data/lib/active_record/query_cache.rb +6 -8
  157. data/lib/active_record/querying.rb +4 -2
  158. data/lib/active_record/railtie.rb +80 -6
  159. data/lib/active_record/railties/console_sandbox.rb +2 -0
  160. data/lib/active_record/railties/controller_runtime.rb +2 -0
  161. data/lib/active_record/railties/databases.rake +46 -36
  162. data/lib/active_record/readonly_attributes.rb +3 -2
  163. data/lib/active_record/reflection.rb +108 -194
  164. data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
  165. data/lib/active_record/relation/batches.rb +20 -5
  166. data/lib/active_record/relation/calculations.rb +45 -19
  167. data/lib/active_record/relation/delegation.rb +45 -27
  168. data/lib/active_record/relation/finder_methods.rb +75 -76
  169. data/lib/active_record/relation/from_clause.rb +2 -8
  170. data/lib/active_record/relation/merger.rb +53 -23
  171. data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
  172. data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
  173. data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
  174. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
  175. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
  176. data/lib/active_record/relation/predicate_builder/range_handler.rb +26 -9
  177. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  178. data/lib/active_record/relation/predicate_builder.rb +60 -79
  179. data/lib/active_record/relation/query_attribute.rb +28 -2
  180. data/lib/active_record/relation/query_methods.rb +128 -99
  181. data/lib/active_record/relation/record_fetch_warning.rb +2 -0
  182. data/lib/active_record/relation/spawn_methods.rb +4 -2
  183. data/lib/active_record/relation/where_clause.rb +65 -68
  184. data/lib/active_record/relation/where_clause_factory.rb +5 -48
  185. data/lib/active_record/relation.rb +120 -214
  186. data/lib/active_record/result.rb +2 -0
  187. data/lib/active_record/runtime_registry.rb +2 -0
  188. data/lib/active_record/sanitization.rb +129 -121
  189. data/lib/active_record/schema.rb +4 -2
  190. data/lib/active_record/schema_dumper.rb +36 -26
  191. data/lib/active_record/schema_migration.rb +2 -0
  192. data/lib/active_record/scoping/default.rb +8 -9
  193. data/lib/active_record/scoping/named.rb +23 -7
  194. data/lib/active_record/scoping.rb +9 -8
  195. data/lib/active_record/secure_token.rb +2 -0
  196. data/lib/active_record/serialization.rb +2 -0
  197. data/lib/active_record/statement_cache.rb +23 -13
  198. data/lib/active_record/store.rb +3 -1
  199. data/lib/active_record/suppressor.rb +2 -0
  200. data/lib/active_record/table_metadata.rb +12 -3
  201. data/lib/active_record/tasks/database_tasks.rb +25 -14
  202. data/lib/active_record/tasks/mysql_database_tasks.rb +9 -48
  203. data/lib/active_record/tasks/postgresql_database_tasks.rb +10 -2
  204. data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
  205. data/lib/active_record/timestamp.rb +6 -6
  206. data/lib/active_record/touch_later.rb +2 -0
  207. data/lib/active_record/transactions.rb +33 -28
  208. data/lib/active_record/translation.rb +2 -0
  209. data/lib/active_record/type/adapter_specific_registry.rb +2 -0
  210. data/lib/active_record/type/date.rb +2 -0
  211. data/lib/active_record/type/date_time.rb +2 -0
  212. data/lib/active_record/type/decimal_without_scale.rb +2 -0
  213. data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
  214. data/lib/active_record/type/internal/timezone.rb +2 -0
  215. data/lib/active_record/type/json.rb +30 -0
  216. data/lib/active_record/type/serialized.rb +2 -0
  217. data/lib/active_record/type/text.rb +2 -0
  218. data/lib/active_record/type/time.rb +2 -0
  219. data/lib/active_record/type/type_map.rb +2 -0
  220. data/lib/active_record/type/unsigned_integer.rb +2 -0
  221. data/lib/active_record/type.rb +4 -1
  222. data/lib/active_record/type_caster/connection.rb +2 -0
  223. data/lib/active_record/type_caster/map.rb +3 -1
  224. data/lib/active_record/type_caster.rb +2 -0
  225. data/lib/active_record/validations/absence.rb +2 -0
  226. data/lib/active_record/validations/associated.rb +2 -0
  227. data/lib/active_record/validations/length.rb +2 -0
  228. data/lib/active_record/validations/presence.rb +2 -0
  229. data/lib/active_record/validations/uniqueness.rb +35 -5
  230. data/lib/active_record/validations.rb +2 -0
  231. data/lib/active_record/version.rb +2 -0
  232. data/lib/active_record.rb +11 -4
  233. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  234. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  235. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
  236. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
  237. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
  238. data/lib/rails/generators/active_record/migration.rb +2 -0
  239. data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
  240. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
  241. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  242. data/lib/rails/generators/active_record.rb +3 -1
  243. metadata +26 -39
  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/user_provided_default.rb +0 -30
  252. data/lib/active_record/attribute.rb +0 -240
  253. data/lib/active_record/attribute_mutation_tracker.rb +0 -122
  254. data/lib/active_record/attribute_set/builder.rb +0 -126
  255. data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
  256. data/lib/active_record/attribute_set.rb +0 -113
  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 -37
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # = Active Record \Persistence
3
5
  module Persistence
@@ -69,6 +71,142 @@ module ActiveRecord
69
71
  klass.allocate.init_with("attributes" => attributes, "new_record" => false, &block)
70
72
  end
71
73
 
74
+ # Updates an object (or multiple objects) and saves it to the database, if validations pass.
75
+ # The resulting object is returned whether the object was saved successfully to the database or not.
76
+ #
77
+ # ==== Parameters
78
+ #
79
+ # * +id+ - This should be the id or an array of ids to be updated.
80
+ # * +attributes+ - This should be a hash of attributes or an array of hashes.
81
+ #
82
+ # ==== Examples
83
+ #
84
+ # # Updates one record
85
+ # Person.update(15, user_name: "Samuel", group: "expert")
86
+ #
87
+ # # Updates multiple records
88
+ # people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
89
+ # Person.update(people.keys, people.values)
90
+ #
91
+ # # Updates multiple records from the result of a relation
92
+ # people = Person.where(group: "expert")
93
+ # people.update(group: "masters")
94
+ #
95
+ # Note: Updating a large number of records will run an UPDATE
96
+ # query for each record, which may cause a performance issue.
97
+ # When running callbacks is not needed for each record update,
98
+ # it is preferred to use {update_all}[rdoc-ref:Relation#update_all]
99
+ # for updating all records in a single query.
100
+ def update(id = :all, attributes)
101
+ if id.is_a?(Array)
102
+ id.map { |one_id| find(one_id) }.each_with_index { |object, idx|
103
+ object.update(attributes[idx])
104
+ }
105
+ elsif id == :all
106
+ all.each { |record| record.update(attributes) }
107
+ else
108
+ if ActiveRecord::Base === id
109
+ raise ArgumentError,
110
+ "You are passing an instance of ActiveRecord::Base to `update`. " \
111
+ "Please pass the id of the object by calling `.id`."
112
+ end
113
+ object = find(id)
114
+ object.update(attributes)
115
+ object
116
+ end
117
+ end
118
+
119
+ # Destroy an object (or multiple objects) that has the given id. The object is instantiated first,
120
+ # therefore all callbacks and filters are fired off before the object is deleted. This method is
121
+ # less efficient than #delete but allows cleanup methods and other actions to be run.
122
+ #
123
+ # This essentially finds the object (or multiple objects) with the given id, creates a new object
124
+ # from the attributes, and then calls destroy on it.
125
+ #
126
+ # ==== Parameters
127
+ #
128
+ # * +id+ - This should be the id or an array of ids to be destroyed.
129
+ #
130
+ # ==== Examples
131
+ #
132
+ # # Destroy a single object
133
+ # Todo.destroy(1)
134
+ #
135
+ # # Destroy multiple objects
136
+ # todos = [1,2,3]
137
+ # Todo.destroy(todos)
138
+ def destroy(id)
139
+ if id.is_a?(Array)
140
+ find(id).each(&:destroy)
141
+ else
142
+ find(id).destroy
143
+ end
144
+ end
145
+
146
+ # Deletes the row with a primary key matching the +id+ argument, using a
147
+ # SQL +DELETE+ statement, and returns the number of rows deleted. Active
148
+ # Record objects are not instantiated, so the object's callbacks are not
149
+ # executed, including any <tt>:dependent</tt> association options.
150
+ #
151
+ # You can delete multiple rows at once by passing an Array of <tt>id</tt>s.
152
+ #
153
+ # Note: Although it is often much faster than the alternative, #destroy,
154
+ # skipping callbacks might bypass business logic in your application
155
+ # that ensures referential integrity or performs other essential jobs.
156
+ #
157
+ # ==== Examples
158
+ #
159
+ # # Delete a single row
160
+ # Todo.delete(1)
161
+ #
162
+ # # Delete multiple rows
163
+ # Todo.delete([2,3,4])
164
+ def delete(id_or_array)
165
+ where(primary_key => id_or_array).delete_all
166
+ end
167
+
168
+ def _insert_record(values) # :nodoc:
169
+ primary_key_value = nil
170
+
171
+ if primary_key && Hash === values
172
+ primary_key_value = values[primary_key]
173
+
174
+ if !primary_key_value && prefetch_primary_key?
175
+ primary_key_value = next_sequence_value
176
+ values[primary_key] = primary_key_value
177
+ end
178
+ end
179
+
180
+ if values.empty?
181
+ im = arel_table.compile_insert(connection.empty_insert_statement_value)
182
+ im.into arel_table
183
+ else
184
+ im = arel_table.compile_insert(_substitute_values(values))
185
+ end
186
+
187
+ connection.insert(im, "#{self} Create", primary_key || false, primary_key_value)
188
+ end
189
+
190
+ def _update_record(values, constraints) # :nodoc:
191
+ constraints = _substitute_values(constraints).map { |attr, bind| attr.eq(bind) }
192
+
193
+ um = arel_table.where(
194
+ constraints.reduce(&:and)
195
+ ).compile_update(_substitute_values(values), primary_key)
196
+
197
+ connection.update(um, "#{self} Update")
198
+ end
199
+
200
+ def _delete_record(constraints) # :nodoc:
201
+ constraints = _substitute_values(constraints).map { |attr, bind| attr.eq(bind) }
202
+
203
+ dm = Arel::DeleteManager.new
204
+ dm.from(arel_table)
205
+ dm.wheres = constraints
206
+
207
+ connection.delete(dm, "#{self} Destroy")
208
+ end
209
+
72
210
  private
73
211
  # Called by +instantiate+ to decide which class to use for a new
74
212
  # record instance.
@@ -78,6 +216,14 @@ module ActiveRecord
78
216
  def discriminate_class_for_record(record)
79
217
  self
80
218
  end
219
+
220
+ def _substitute_values(values)
221
+ values.map do |name, value|
222
+ attr = arel_attribute(name)
223
+ bind = predicate_builder.build_bind_attribute(name, value)
224
+ [attr, bind]
225
+ end
226
+ end
81
227
  end
82
228
 
83
229
  # Returns true if this object hasn't been saved yet -- that is, a record
@@ -175,7 +321,7 @@ module ActiveRecord
175
321
  # callbacks or any <tt>:dependent</tt> association
176
322
  # options, use <tt>#destroy</tt>.
177
323
  def delete
178
- self.class.delete(id) if persisted?
324
+ _delete_row if persisted?
179
325
  @destroyed = true
180
326
  freeze
181
327
  end
@@ -224,9 +370,9 @@ module ActiveRecord
224
370
  # Any change to the attributes on either instance will affect both instances.
225
371
  # If you want to change the sti column as well, use #becomes! instead.
226
372
  def becomes(klass)
227
- became = klass.new
373
+ became = klass.allocate
374
+ became.send(:initialize)
228
375
  became.instance_variable_set("@attributes", @attributes)
229
- became.instance_variable_set("@mutation_tracker", @mutation_tracker ||= nil)
230
376
  became.instance_variable_set("@mutations_from_database", @mutations_from_database ||= nil)
231
377
  became.instance_variable_set("@changed_attributes", attributes_changed_by_setter)
232
378
  became.instance_variable_set("@new_record", new_record?)
@@ -327,13 +473,17 @@ module ActiveRecord
327
473
  verify_readonly_attribute(key.to_s)
328
474
  end
329
475
 
330
- updated_count = self.class.unscoped.where(self.class.primary_key => id).update_all(attributes)
331
-
476
+ id_in_database = self.id_in_database
332
477
  attributes.each do |k, v|
333
- raw_write_attribute(k, v)
478
+ write_attribute_without_type_cast(k, v)
334
479
  end
335
480
 
336
- updated_count == 1
481
+ affected_rows = self.class._update_record(
482
+ attributes,
483
+ self.class.primary_key => id_in_database
484
+ )
485
+
486
+ affected_rows == 1
337
487
  end
338
488
 
339
489
  # Initializes +attribute+ to zero if +nil+ and adds the value passed as +by+ (default is 1).
@@ -348,7 +498,7 @@ module ActiveRecord
348
498
  # Wrapper around #increment that writes the update to the database.
349
499
  # Only +attribute+ is updated; the record itself is not saved.
350
500
  # This means that any other modified attributes will still be dirty.
351
- # Validations and callbacks are skipped. Supports the `touch` option from
501
+ # Validations and callbacks are skipped. Supports the +touch+ option from
352
502
  # +update_counters+, see that for more.
353
503
  # Returns +self+.
354
504
  def increment!(attribute, by = 1, touch: nil)
@@ -369,7 +519,7 @@ module ActiveRecord
369
519
  # Wrapper around #decrement that writes the update to the database.
370
520
  # Only +attribute+ is updated; the record itself is not saved.
371
521
  # This means that any other modified attributes will still be dirty.
372
- # Validations and callbacks are skipped. Supports the `touch` option from
522
+ # Validations and callbacks are skipped. Supports the +touch+ option from
373
523
  # +update_counters+, see that for more.
374
524
  # Returns +self+.
375
525
  def decrement!(attribute, by = 1, touch: nil)
@@ -524,11 +674,11 @@ module ActiveRecord
524
674
  end
525
675
 
526
676
  def destroy_row
527
- relation_for_destroy.delete_all
677
+ _delete_row
528
678
  end
529
679
 
530
- def relation_for_destroy
531
- self.class.unscoped.where(self.class.primary_key => id)
680
+ def _delete_row
681
+ self.class._delete_record(self.class.primary_key => id_in_database)
532
682
  end
533
683
 
534
684
  def _touch_row(attribute_names, time)
@@ -543,14 +693,15 @@ module ActiveRecord
543
693
  end
544
694
 
545
695
  def _update_row(attribute_names, attempted_action = "update")
546
- self.class.unscoped._update_record(
547
- arel_attributes_with_values(attribute_names),
696
+ self.class._update_record(
697
+ attributes_with_values(attribute_names),
548
698
  self.class.primary_key => id_in_database
549
699
  )
550
700
  end
551
701
 
552
702
  def create_or_update(*args, &block)
553
703
  _raise_readonly_record_error if readonly?
704
+ return false if destroyed?
554
705
  result = new_record? ? _create_record(&block) : _update_record(*args, &block)
555
706
  result != false
556
707
  end
@@ -578,9 +729,9 @@ module ActiveRecord
578
729
  # and returns its id.
579
730
  def _create_record(attribute_names = self.attribute_names)
580
731
  attribute_names &= self.class.column_names
581
- attributes_values = arel_attributes_with_values_for_create(attribute_names)
732
+ attributes_values = attributes_with_values_for_create(attribute_names)
582
733
 
583
- new_id = self.class.unscoped.insert attributes_values
734
+ new_id = self.class._insert_record(attributes_values)
584
735
  self.id ||= new_id if self.class.primary_key
585
736
 
586
737
  @new_record = false
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # = Active Record Query Cache
3
5
  class QueryCache
@@ -24,16 +26,12 @@ module ActiveRecord
24
26
  end
25
27
 
26
28
  def self.run
27
- caching_pool = ActiveRecord::Base.connection_pool
28
- caching_was_enabled = caching_pool.query_cache_enabled
29
-
30
- caching_pool.enable_query_cache!
31
-
32
- [caching_pool, caching_was_enabled]
29
+ ActiveRecord::Base.connection_handler.connection_pool_list.
30
+ reject { |p| p.query_cache_enabled }.each { |p| p.enable_query_cache! }
33
31
  end
34
32
 
35
- def self.complete((caching_pool, caching_was_enabled))
36
- caching_pool.disable_query_cache! unless caching_was_enabled
33
+ def self.complete(pools)
34
+ pools.each { |pool| pool.disable_query_cache! }
37
35
 
38
36
  ActiveRecord::Base.connection_handler.connection_pool_list.each do |pool|
39
37
  pool.release_connection if pool.active_connection? && !pool.connection.transaction_open?
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Querying
3
5
  delegate :find, :take, :take!, :first, :first!, :last, :last!, :exists?, :any?, :many?, :none?, :one?, to: :all
@@ -5,7 +7,7 @@ module ActiveRecord
5
7
  delegate :first_or_create, :first_or_create!, :first_or_initialize, to: :all
6
8
  delegate :find_or_create_by, :find_or_create_by!, :find_or_initialize_by, to: :all
7
9
  delegate :find_by, :find_by!, to: :all
8
- delegate :destroy, :destroy_all, :delete, :delete_all, :update, :update_all, to: :all
10
+ delegate :destroy_all, :delete_all, :update_all, to: :all
9
11
  delegate :find_each, :find_in_batches, :in_batches, to: :all
10
12
  delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins, :left_joins, :left_outer_joins, :or,
11
13
  :where, :rewhere, :preload, :eager_load, :includes, :from, :lock, :readonly, :extending,
@@ -38,7 +40,7 @@ module ActiveRecord
38
40
  def find_by_sql(sql, binds = [], preparable: nil, &block)
39
41
  result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds, preparable: preparable)
40
42
  column_types = result_set.column_types.dup
41
- columns_hash.each_key { |k| column_types.delete k }
43
+ attribute_types.each_key { |k| column_types.delete k }
42
44
  message_bus = ActiveSupport::Notifications.instrumenter
43
45
 
44
46
  payload = {
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_record"
2
4
  require "rails"
3
5
  require "active_model/railtie"
@@ -26,6 +28,9 @@ module ActiveRecord
26
28
  config.active_record.use_schema_cache_dump = true
27
29
  config.active_record.maintain_test_schema = true
28
30
 
31
+ config.active_record.sqlite3 = ActiveSupport::OrderedOptions.new
32
+ config.active_record.sqlite3.represent_boolean_as_integer = nil
33
+
29
34
  config.eager_load_namespaces << ActiveRecord
30
35
 
31
36
  rake_tasks do
@@ -54,6 +59,7 @@ module ActiveRecord
54
59
  console = ActiveSupport::Logger.new(STDERR)
55
60
  Rails.logger.extend ActiveSupport::Logger.broadcast console
56
61
  end
62
+ ActiveRecord::Base.verbose_query_logs = false
57
63
  end
58
64
 
59
65
  runner do
@@ -85,12 +91,16 @@ module ActiveRecord
85
91
  filename = File.join(app.config.paths["db"].first, "schema_cache.yml")
86
92
 
87
93
  if File.file?(filename)
94
+ current_version = ActiveRecord::Migrator.current_version
95
+
96
+ next if current_version.nil?
97
+
88
98
  cache = YAML.load(File.read(filename))
89
- if cache.version == ActiveRecord::Migrator.current_version
99
+ if cache.version == current_version
90
100
  connection.schema_cache = cache
91
101
  connection_pool.schema_cache = cache.dup
92
102
  else
93
- warn "Ignoring db/schema_cache.yml because it has expired. The current schema version is #{ActiveRecord::Migrator.current_version}, but the one in the cache is #{cache.version}."
103
+ warn "Ignoring db/schema_cache.yml because it has expired. The current schema version is #{current_version}, but the one in the cache is #{cache.version}."
94
104
  end
95
105
  end
96
106
  end
@@ -108,7 +118,9 @@ module ActiveRecord
108
118
 
109
119
  initializer "active_record.set_configs" do |app|
110
120
  ActiveSupport.on_load(:active_record) do
111
- app.config.active_record.each do |k, v|
121
+ configs = app.config.active_record.dup
122
+ configs.delete(:sqlite3)
123
+ configs.each do |k, v|
112
124
  send "#{k}=", v
113
125
  end
114
126
  end
@@ -157,14 +169,76 @@ end_warning
157
169
  end
158
170
 
159
171
  initializer "active_record.set_executor_hooks" do
160
- ActiveSupport.on_load(:active_record) do
161
- ActiveRecord::QueryCache.install_executor_hooks
162
- end
172
+ ActiveRecord::QueryCache.install_executor_hooks
163
173
  end
164
174
 
165
175
  initializer "active_record.add_watchable_files" do |app|
166
176
  path = app.paths["db"].first
167
177
  config.watchable_files.concat ["#{path}/schema.rb", "#{path}/structure.sql"]
168
178
  end
179
+
180
+ initializer "active_record.clear_active_connections" do
181
+ config.after_initialize do
182
+ ActiveSupport.on_load(:active_record) do
183
+ # Ideally the application doesn't connect to the database during boot,
184
+ # but sometimes it does. In case it did, we want to empty out the
185
+ # connection pools so that a non-database-using process (e.g. a master
186
+ # process in a forking server model) doesn't retain a needless
187
+ # connection. If it was needed, the incremental cost of reestablishing
188
+ # this connection is trivial: the rest of the pool would need to be
189
+ # populated anyway.
190
+
191
+ clear_active_connections!
192
+ flush_idle_connections!
193
+ end
194
+ end
195
+ end
196
+
197
+ initializer "active_record.check_represent_sqlite3_boolean_as_integer" do
198
+ config.after_initialize do
199
+ ActiveSupport.on_load(:active_record_sqlite3adapter) do
200
+ represent_boolean_as_integer = Rails.application.config.active_record.sqlite3.delete(:represent_boolean_as_integer)
201
+ unless represent_boolean_as_integer.nil?
202
+ ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer = represent_boolean_as_integer
203
+ end
204
+
205
+ unless ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer
206
+ ActiveSupport::Deprecation.warn <<-MSG
207
+ Leaving `ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer`
208
+ set to false is deprecated. SQLite databases have used 't' and 'f' to serialize
209
+ boolean values and must have old data converted to 1 and 0 (its native boolean
210
+ serialization) before setting this flag to true. Conversion can be accomplished
211
+ by setting up a rake task which runs
212
+
213
+ ExampleModel.where("boolean_column = 't'").update_all(boolean_column: 1)
214
+ ExampleModel.where("boolean_column = 'f'").update_all(boolean_column: 0)
215
+
216
+ for all models and all boolean columns, after which the flag must be set to
217
+ true by adding the following to your application.rb file:
218
+
219
+ Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
220
+ MSG
221
+ end
222
+ end
223
+ end
224
+ end
225
+
226
+ initializer "active_record.use_yaml_unsafe_load" do |app|
227
+ config.after_initialize do
228
+ unless app.config.active_record.use_yaml_unsafe_load.nil?
229
+ ActiveRecord::Base.use_yaml_unsafe_load =
230
+ app.config.active_record.use_yaml_unsafe_load
231
+ end
232
+ end
233
+ end
234
+
235
+ initializer "active_record.yaml_column_permitted_classes" do |app|
236
+ config.after_initialize do
237
+ unless app.config.active_record.yaml_column_permitted_classes.nil?
238
+ ActiveRecord::Base.yaml_column_permitted_classes =
239
+ app.config.active_record.yaml_column_permitted_classes
240
+ end
241
+ end
242
+ end
169
243
  end
170
244
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ActiveRecord::Base.connection.begin_transaction(joinable: false)
2
4
 
3
5
  at_exit do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/module/attr_internal"
2
4
  require "active_record/log_subscriber"
3
5