activerecord 5.1.5 → 5.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +450 -699
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -5
- data/examples/performance.rb +2 -0
- data/examples/simple.rb +2 -0
- data/lib/active_record/aggregations.rb +6 -5
- data/lib/active_record/association_relation.rb +4 -2
- data/lib/active_record/associations/alias_tracker.rb +19 -27
- data/lib/active_record/associations/association.rb +33 -37
- data/lib/active_record/associations/association_scope.rb +38 -50
- data/lib/active_record/associations/belongs_to_association.rb +28 -9
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
- data/lib/active_record/associations/builder/association.rb +4 -7
- data/lib/active_record/associations/builder/belongs_to.rb +14 -5
- data/lib/active_record/associations/builder/collection_association.rb +1 -1
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +2 -0
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_association.rb +52 -41
- data/lib/active_record/associations/collection_proxy.rb +12 -15
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +3 -1
- data/lib/active_record/associations/has_many_through_association.rb +8 -19
- data/lib/active_record/associations/has_one_association.rb +12 -1
- data/lib/active_record/associations/has_one_through_association.rb +13 -8
- data/lib/active_record/associations/join_dependency/join_association.rb +22 -67
- data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +9 -9
- data/lib/active_record/associations/join_dependency.rb +48 -93
- data/lib/active_record/associations/preloader/association.rb +45 -61
- data/lib/active_record/associations/preloader/through_association.rb +71 -79
- data/lib/active_record/associations/preloader.rb +17 -37
- data/lib/active_record/associations/singular_association.rb +14 -16
- data/lib/active_record/associations/through_association.rb +26 -11
- data/lib/active_record/associations.rb +40 -63
- data/lib/active_record/attribute_assignment.rb +2 -5
- data/lib/active_record/attribute_decorators.rb +3 -2
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
- data/lib/active_record/attribute_methods/dirty.rb +25 -214
- data/lib/active_record/attribute_methods/primary_key.rb +7 -6
- data/lib/active_record/attribute_methods/query.rb +2 -0
- data/lib/active_record/attribute_methods/read.rb +9 -3
- data/lib/active_record/attribute_methods/serialization.rb +23 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
- data/lib/active_record/attribute_methods/write.rb +21 -9
- data/lib/active_record/attribute_methods.rb +65 -24
- data/lib/active_record/attributes.rb +7 -6
- data/lib/active_record/autosave_association.rb +16 -14
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +12 -6
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +2 -0
- data/lib/active_record/collection_cache_key.rb +11 -7
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +110 -35
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +157 -29
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +7 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +15 -32
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +14 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +64 -6
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +149 -78
- data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -21
- data/lib/active_record/connection_adapters/abstract_adapter.rb +81 -96
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +92 -165
- data/lib/active_record/connection_adapters/column.rb +3 -1
- data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +47 -2
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -10
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -30
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +106 -1
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
- data/lib/active_record/connection_adapters/postgresql/column.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +8 -2
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +18 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +248 -112
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +57 -73
- data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +20 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +75 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +79 -92
- data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
- data/lib/active_record/connection_handling.rb +4 -2
- data/lib/active_record/core.rb +39 -60
- data/lib/active_record/counter_cache.rb +20 -15
- data/lib/active_record/define_callbacks.rb +5 -3
- data/lib/active_record/dynamic_matchers.rb +9 -9
- data/lib/active_record/enum.rb +17 -13
- data/lib/active_record/errors.rb +42 -3
- data/lib/active_record/explain.rb +3 -1
- data/lib/active_record/explain_registry.rb +2 -0
- data/lib/active_record/explain_subscriber.rb +2 -0
- data/lib/active_record/fixture_set/file.rb +2 -0
- data/lib/active_record/fixtures.rb +67 -60
- data/lib/active_record/gem_version.rb +4 -2
- data/lib/active_record/inheritance.rb +49 -19
- data/lib/active_record/integration.rb +58 -19
- data/lib/active_record/internal_metadata.rb +2 -0
- data/lib/active_record/legacy_yaml_adapter.rb +3 -1
- data/lib/active_record/locking/optimistic.rb +30 -42
- data/lib/active_record/locking/pessimistic.rb +9 -6
- data/lib/active_record/log_subscriber.rb +43 -0
- data/lib/active_record/migration/command_recorder.rb +11 -9
- data/lib/active_record/migration/compatibility.rb +40 -2
- data/lib/active_record/migration/join_table.rb +2 -0
- data/lib/active_record/migration.rb +189 -139
- data/lib/active_record/model_schema.rb +19 -24
- data/lib/active_record/nested_attributes.rb +18 -6
- data/lib/active_record/no_touching.rb +3 -1
- data/lib/active_record/null_relation.rb +2 -0
- data/lib/active_record/persistence.rb +196 -48
- data/lib/active_record/query_cache.rb +12 -14
- data/lib/active_record/querying.rb +3 -1
- data/lib/active_record/railtie.rb +61 -3
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +2 -0
- data/lib/active_record/railties/databases.rake +46 -36
- data/lib/active_record/readonly_attributes.rb +3 -2
- data/lib/active_record/reflection.rb +110 -192
- data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
- data/lib/active_record/relation/batches.rb +20 -5
- data/lib/active_record/relation/calculations.rb +31 -9
- data/lib/active_record/relation/delegation.rb +15 -27
- data/lib/active_record/relation/finder_methods.rb +71 -76
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +47 -20
- data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +26 -9
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
- data/lib/active_record/relation/predicate_builder.rb +55 -79
- data/lib/active_record/relation/query_attribute.rb +26 -2
- data/lib/active_record/relation/query_methods.rb +95 -91
- data/lib/active_record/relation/record_fetch_warning.rb +2 -0
- data/lib/active_record/relation/spawn_methods.rb +3 -1
- data/lib/active_record/relation/where_clause.rb +65 -68
- data/lib/active_record/relation/where_clause_factory.rb +5 -48
- data/lib/active_record/relation.rb +106 -219
- data/lib/active_record/result.rb +2 -0
- data/lib/active_record/runtime_registry.rb +2 -0
- data/lib/active_record/sanitization.rb +129 -121
- data/lib/active_record/schema.rb +4 -2
- data/lib/active_record/schema_dumper.rb +36 -26
- data/lib/active_record/schema_migration.rb +2 -0
- data/lib/active_record/scoping/default.rb +6 -7
- data/lib/active_record/scoping/named.rb +21 -7
- data/lib/active_record/scoping.rb +9 -8
- data/lib/active_record/secure_token.rb +2 -0
- data/lib/active_record/serialization.rb +2 -0
- data/lib/active_record/statement_cache.rb +22 -12
- data/lib/active_record/store.rb +3 -1
- data/lib/active_record/suppressor.rb +2 -0
- data/lib/active_record/table_metadata.rb +12 -3
- data/lib/active_record/tasks/database_tasks.rb +25 -14
- data/lib/active_record/tasks/mysql_database_tasks.rb +9 -48
- data/lib/active_record/tasks/postgresql_database_tasks.rb +10 -2
- data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
- data/lib/active_record/timestamp.rb +13 -6
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +32 -27
- data/lib/active_record/translation.rb +2 -0
- data/lib/active_record/type/adapter_specific_registry.rb +2 -0
- data/lib/active_record/type/date.rb +2 -0
- data/lib/active_record/type/date_time.rb +2 -0
- data/lib/active_record/type/decimal_without_scale.rb +2 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
- data/lib/active_record/type/internal/timezone.rb +2 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +6 -0
- data/lib/active_record/type/text.rb +2 -0
- data/lib/active_record/type/time.rb +2 -0
- data/lib/active_record/type/type_map.rb +2 -0
- data/lib/active_record/type/unsigned_integer.rb +2 -0
- data/lib/active_record/type.rb +4 -1
- data/lib/active_record/type_caster/connection.rb +2 -0
- data/lib/active_record/type_caster/map.rb +3 -1
- data/lib/active_record/type_caster.rb +2 -0
- data/lib/active_record/validations/absence.rb +2 -0
- data/lib/active_record/validations/associated.rb +2 -0
- data/lib/active_record/validations/length.rb +2 -0
- data/lib/active_record/validations/presence.rb +2 -0
- data/lib/active_record/validations/uniqueness.rb +36 -6
- data/lib/active_record/validations.rb +2 -0
- data/lib/active_record/version.rb +2 -0
- data/lib/active_record.rb +11 -4
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration.rb +2 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- data/lib/rails/generators/active_record.rb +3 -1
- metadata +23 -36
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
- data/lib/active_record/associations/preloader/collection_association.rb +0 -17
- data/lib/active_record/associations/preloader/has_many.rb +0 -15
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -15
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -18
- data/lib/active_record/attribute/user_provided_default.rb +0 -30
- data/lib/active_record/attribute.rb +0 -240
- data/lib/active_record/attribute_mutation_tracker.rb +0 -114
- data/lib/active_record/attribute_set/builder.rb +0 -124
- data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
- data/lib/active_record/attribute_set.rb +0 -113
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
- 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
|
-
|
324
|
+
_delete_row if persisted?
|
179
325
|
@destroyed = true
|
180
326
|
freeze
|
181
327
|
end
|
@@ -224,9 +370,10 @@ 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.
|
373
|
+
became = klass.allocate
|
374
|
+
became.send(:initialize)
|
228
375
|
became.instance_variable_set("@attributes", @attributes)
|
229
|
-
became.instance_variable_set("@
|
376
|
+
became.instance_variable_set("@mutations_from_database", @mutations_from_database ||= nil)
|
230
377
|
became.instance_variable_set("@changed_attributes", attributes_changed_by_setter)
|
231
378
|
became.instance_variable_set("@new_record", new_record?)
|
232
379
|
became.instance_variable_set("@destroyed", destroyed?)
|
@@ -326,13 +473,16 @@ module ActiveRecord
|
|
326
473
|
verify_readonly_attribute(key.to_s)
|
327
474
|
end
|
328
475
|
|
329
|
-
|
476
|
+
affected_rows = self.class._update_record(
|
477
|
+
attributes,
|
478
|
+
self.class.primary_key => id_in_database
|
479
|
+
)
|
330
480
|
|
331
481
|
attributes.each do |k, v|
|
332
|
-
|
482
|
+
write_attribute_without_type_cast(k, v)
|
333
483
|
end
|
334
484
|
|
335
|
-
|
485
|
+
affected_rows == 1
|
336
486
|
end
|
337
487
|
|
338
488
|
# Initializes +attribute+ to zero if +nil+ and adds the value passed as +by+ (default is 1).
|
@@ -347,7 +497,7 @@ module ActiveRecord
|
|
347
497
|
# Wrapper around #increment that writes the update to the database.
|
348
498
|
# Only +attribute+ is updated; the record itself is not saved.
|
349
499
|
# This means that any other modified attributes will still be dirty.
|
350
|
-
# Validations and callbacks are skipped. Supports the
|
500
|
+
# Validations and callbacks are skipped. Supports the +touch+ option from
|
351
501
|
# +update_counters+, see that for more.
|
352
502
|
# Returns +self+.
|
353
503
|
def increment!(attribute, by = 1, touch: nil)
|
@@ -368,7 +518,7 @@ module ActiveRecord
|
|
368
518
|
# Wrapper around #decrement that writes the update to the database.
|
369
519
|
# Only +attribute+ is updated; the record itself is not saved.
|
370
520
|
# This means that any other modified attributes will still be dirty.
|
371
|
-
# Validations and callbacks are skipped. Supports the
|
521
|
+
# Validations and callbacks are skipped. Supports the +touch+ option from
|
372
522
|
# +update_counters+, see that for more.
|
373
523
|
# Returns +self+.
|
374
524
|
def decrement!(attribute, by = 1, touch: nil)
|
@@ -505,36 +655,12 @@ module ActiveRecord
|
|
505
655
|
MSG
|
506
656
|
end
|
507
657
|
|
508
|
-
|
509
|
-
|
510
|
-
attributes.concat(names)
|
511
|
-
|
512
|
-
unless attributes.empty?
|
513
|
-
changes = {}
|
514
|
-
|
515
|
-
attributes.each do |column|
|
516
|
-
column = column.to_s
|
517
|
-
changes[column] = write_attribute(column, time)
|
518
|
-
end
|
519
|
-
|
520
|
-
primary_key = self.class.primary_key
|
521
|
-
scope = self.class.unscoped.where(primary_key => _read_attribute(primary_key))
|
522
|
-
|
523
|
-
if locking_enabled?
|
524
|
-
locking_column = self.class.locking_column
|
525
|
-
scope = scope.where(locking_column => _read_attribute(locking_column))
|
526
|
-
changes[locking_column] = increment_lock
|
527
|
-
end
|
528
|
-
|
529
|
-
clear_attribute_changes(changes.keys)
|
530
|
-
result = scope.update_all(changes) == 1
|
531
|
-
|
532
|
-
if !result && locking_enabled?
|
533
|
-
raise ActiveRecord::StaleObjectError.new(self, "touch")
|
534
|
-
end
|
658
|
+
attribute_names = timestamp_attributes_for_update_in_model
|
659
|
+
attribute_names |= names.map(&:to_s)
|
535
660
|
|
536
|
-
|
537
|
-
|
661
|
+
unless attribute_names.empty?
|
662
|
+
affected_rows = _touch_row(attribute_names, time)
|
663
|
+
@_trigger_update_callback = affected_rows == 1
|
538
664
|
else
|
539
665
|
true
|
540
666
|
end
|
@@ -547,15 +673,34 @@ module ActiveRecord
|
|
547
673
|
end
|
548
674
|
|
549
675
|
def destroy_row
|
550
|
-
|
676
|
+
_delete_row
|
551
677
|
end
|
552
678
|
|
553
|
-
def
|
554
|
-
self.class.
|
679
|
+
def _delete_row
|
680
|
+
self.class._delete_record(self.class.primary_key => id_in_database)
|
681
|
+
end
|
682
|
+
|
683
|
+
def _touch_row(attribute_names, time)
|
684
|
+
time ||= current_time_from_proper_timezone
|
685
|
+
|
686
|
+
attribute_names.each do |attr_name|
|
687
|
+
write_attribute(attr_name, time)
|
688
|
+
clear_attribute_change(attr_name)
|
689
|
+
end
|
690
|
+
|
691
|
+
_update_row(attribute_names, "touch")
|
692
|
+
end
|
693
|
+
|
694
|
+
def _update_row(attribute_names, attempted_action = "update")
|
695
|
+
self.class._update_record(
|
696
|
+
attributes_with_values(attribute_names),
|
697
|
+
self.class.primary_key => id_in_database
|
698
|
+
)
|
555
699
|
end
|
556
700
|
|
557
701
|
def create_or_update(*args, &block)
|
558
702
|
_raise_readonly_record_error if readonly?
|
703
|
+
return false if destroyed?
|
559
704
|
result = new_record? ? _create_record(&block) : _update_record(*args, &block)
|
560
705
|
result != false
|
561
706
|
end
|
@@ -563,26 +708,29 @@ module ActiveRecord
|
|
563
708
|
# Updates the associated record with values matching those of the instance attributes.
|
564
709
|
# Returns the number of affected rows.
|
565
710
|
def _update_record(attribute_names = self.attribute_names)
|
566
|
-
|
567
|
-
|
568
|
-
|
711
|
+
attribute_names &= self.class.column_names
|
712
|
+
attribute_names = attributes_for_update(attribute_names)
|
713
|
+
|
714
|
+
if attribute_names.empty?
|
715
|
+
affected_rows = 0
|
569
716
|
@_trigger_update_callback = true
|
570
717
|
else
|
571
|
-
|
572
|
-
@_trigger_update_callback =
|
718
|
+
affected_rows = _update_row(attribute_names)
|
719
|
+
@_trigger_update_callback = affected_rows == 1
|
573
720
|
end
|
574
721
|
|
575
722
|
yield(self) if block_given?
|
576
723
|
|
577
|
-
|
724
|
+
affected_rows
|
578
725
|
end
|
579
726
|
|
580
727
|
# Creates a record with values matching those of the instance attributes
|
581
728
|
# and returns its id.
|
582
729
|
def _create_record(attribute_names = self.attribute_names)
|
583
|
-
|
730
|
+
attribute_names &= self.class.column_names
|
731
|
+
attributes_values = attributes_with_values_for_create(attribute_names)
|
584
732
|
|
585
|
-
new_id = self.class.
|
733
|
+
new_id = self.class._insert_record(attributes_values)
|
586
734
|
self.id ||= new_id if self.class.primary_key
|
587
735
|
|
588
736
|
@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
|
@@ -5,35 +7,31 @@ module ActiveRecord
|
|
5
7
|
# Enable the query cache within the block if Active Record is configured.
|
6
8
|
# If it's not, it will execute the given block.
|
7
9
|
def cache(&block)
|
8
|
-
if configurations.empty?
|
9
|
-
yield
|
10
|
-
else
|
10
|
+
if connected? || !configurations.empty?
|
11
11
|
connection.cache(&block)
|
12
|
+
else
|
13
|
+
yield
|
12
14
|
end
|
13
15
|
end
|
14
16
|
|
15
17
|
# Disable the query cache within the block if Active Record is configured.
|
16
18
|
# If it's not, it will execute the given block.
|
17
19
|
def uncached(&block)
|
18
|
-
if configurations.empty?
|
19
|
-
yield
|
20
|
-
else
|
20
|
+
if connected? || !configurations.empty?
|
21
21
|
connection.uncached(&block)
|
22
|
+
else
|
23
|
+
yield
|
22
24
|
end
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
26
28
|
def self.run
|
27
|
-
|
28
|
-
|
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(
|
36
|
-
|
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 :
|
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,
|
@@ -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 ==
|
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 #{
|
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.
|
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
|
@@ -166,5 +178,51 @@ end_warning
|
|
166
178
|
path = app.paths["db"].first
|
167
179
|
config.watchable_files.concat ["#{path}/schema.rb", "#{path}/structure.sql"]
|
168
180
|
end
|
181
|
+
|
182
|
+
initializer "active_record.clear_active_connections" do
|
183
|
+
config.after_initialize do
|
184
|
+
ActiveSupport.on_load(:active_record) do
|
185
|
+
# Ideally the application doesn't connect to the database during boot,
|
186
|
+
# but sometimes it does. In case it did, we want to empty out the
|
187
|
+
# connection pools so that a non-database-using process (e.g. a master
|
188
|
+
# process in a forking server model) doesn't retain a needless
|
189
|
+
# connection. If it was needed, the incremental cost of reestablishing
|
190
|
+
# this connection is trivial: the rest of the pool would need to be
|
191
|
+
# populated anyway.
|
192
|
+
|
193
|
+
clear_active_connections!
|
194
|
+
flush_idle_connections!
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
initializer "active_record.check_represent_sqlite3_boolean_as_integer" do
|
200
|
+
config.after_initialize do
|
201
|
+
ActiveSupport.on_load(:active_record_sqlite3adapter) do
|
202
|
+
represent_boolean_as_integer = Rails.application.config.active_record.sqlite3.delete(:represent_boolean_as_integer)
|
203
|
+
unless represent_boolean_as_integer.nil?
|
204
|
+
ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer = represent_boolean_as_integer
|
205
|
+
end
|
206
|
+
|
207
|
+
unless ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer
|
208
|
+
ActiveSupport::Deprecation.warn <<-MSG
|
209
|
+
Leaving `ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer`
|
210
|
+
set to false is deprecated. SQLite databases have used 't' and 'f' to serialize
|
211
|
+
boolean values and must have old data converted to 1 and 0 (its native boolean
|
212
|
+
serialization) before setting this flag to true. Conversion can be accomplished
|
213
|
+
by setting up a rake task which runs
|
214
|
+
|
215
|
+
ExampleModel.where("boolean_column = 't'").update_all(boolean_column: 1)
|
216
|
+
ExampleModel.where("boolean_column = 'f'").update_all(boolean_column: 0)
|
217
|
+
|
218
|
+
for all models and all boolean columns, after which the flag must be set to
|
219
|
+
true by adding the following to your application.rb file:
|
220
|
+
|
221
|
+
Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
|
222
|
+
MSG
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
169
227
|
end
|
170
228
|
end
|