activerecord 5.1.7 → 5.2.0.beta1
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 +5 -5
- data/CHANGELOG.md +221 -900
- data/README.rdoc +3 -3
- data/examples/performance.rb +2 -0
- data/examples/simple.rb +2 -0
- data/lib/active_record.rb +10 -3
- data/lib/active_record/aggregations.rb +2 -0
- data/lib/active_record/association_relation.rb +2 -0
- data/lib/active_record/associations.rb +13 -42
- data/lib/active_record/associations/alias_tracker.rb +17 -17
- data/lib/active_record/associations/association.rb +11 -22
- data/lib/active_record/associations/association_scope.rb +32 -44
- data/lib/active_record/associations/belongs_to_association.rb +6 -4
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -1
- data/lib/active_record/associations/builder/association.rb +2 -5
- data/lib/active_record/associations/builder/belongs_to.rb +7 -12
- 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 +41 -33
- data/lib/active_record/associations/collection_proxy.rb +11 -14
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +4 -2
- data/lib/active_record/associations/has_many_through_association.rb +4 -2
- data/lib/active_record/associations/has_one_association.rb +3 -1
- data/lib/active_record/associations/has_one_through_association.rb +3 -1
- data/lib/active_record/associations/join_dependency.rb +22 -40
- data/lib/active_record/associations/join_dependency/join_association.rb +17 -56
- data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -9
- data/lib/active_record/associations/preloader.rb +17 -37
- data/lib/active_record/associations/preloader/association.rb +42 -58
- data/lib/active_record/associations/preloader/through_association.rb +71 -79
- data/lib/active_record/associations/singular_association.rb +14 -10
- data/lib/active_record/associations/through_association.rb +3 -1
- data/lib/active_record/attribute_assignment.rb +2 -0
- data/lib/active_record/attribute_decorators.rb +3 -2
- data/lib/active_record/attribute_methods.rb +47 -7
- 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 +8 -2
- 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/attributes.rb +7 -6
- data/lib/active_record/autosave_association.rb +5 -11
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +6 -8
- 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 +10 -5
- 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 +120 -28
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +7 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +14 -33
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +13 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +40 -2
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +103 -63
- data/lib/active_record/connection_adapters/abstract/transaction.rb +45 -9
- data/lib/active_record/connection_adapters/abstract_adapter.rb +62 -90
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +75 -138
- 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 +3 -1
- 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 -6
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -30
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +91 -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.rb +2 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +3 -11
- 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_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 +3 -5
- 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/quoting.rb +10 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +11 -7
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +79 -65
- 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 +47 -82
- data/lib/active_record/connection_adapters/schema_cache.rb +2 -0
- 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 +19 -2
- 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 +71 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +34 -89
- 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 +27 -57
- data/lib/active_record/counter_cache.rb +15 -12
- data/lib/active_record/define_callbacks.rb +5 -3
- data/lib/active_record/dynamic_matchers.rb +9 -9
- data/lib/active_record/enum.rb +15 -13
- data/lib/active_record/errors.rb +54 -21
- 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 +40 -24
- data/lib/active_record/gem_version.rb +5 -3
- data/lib/active_record/inheritance.rb +6 -5
- 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 +31 -20
- data/lib/active_record/locking/pessimistic.rb +10 -7
- data/lib/active_record/log_subscriber.rb +2 -0
- data/lib/active_record/migration.rb +47 -21
- data/lib/active_record/migration/command_recorder.rb +11 -9
- data/lib/active_record/migration/compatibility.rb +20 -2
- data/lib/active_record/migration/join_table.rb +2 -0
- data/lib/active_record/model_schema.rb +29 -38
- 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 +184 -40
- data/lib/active_record/query_cache.rb +17 -12
- data/lib/active_record/querying.rb +3 -1
- data/lib/active_record/railtie.rb +54 -1
- 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 +41 -28
- data/lib/active_record/readonly_attributes.rb +3 -2
- data/lib/active_record/reflection.rb +100 -182
- data/lib/active_record/relation.rb +61 -193
- data/lib/active_record/relation/batches.rb +20 -5
- data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
- data/lib/active_record/relation/calculations.rb +40 -23
- data/lib/active_record/relation/delegation.rb +10 -27
- data/lib/active_record/relation/finder_methods.rb +53 -49
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +22 -19
- data/lib/active_record/relation/predicate_builder.rb +42 -79
- 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 +54 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -6
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
- data/lib/active_record/relation/query_attribute.rb +9 -2
- data/lib/active_record/relation/query_methods.rb +80 -69
- data/lib/active_record/relation/record_fetch_warning.rb +2 -0
- data/lib/active_record/relation/spawn_methods.rb +2 -0
- data/lib/active_record/relation/where_clause.rb +50 -67
- data/lib/active_record/relation/where_clause_factory.rb +4 -46
- data/lib/active_record/result.rb +2 -0
- data/lib/active_record/runtime_registry.rb +2 -0
- data/lib/active_record/sanitization.rb +15 -9
- data/lib/active_record/schema.rb +3 -1
- data/lib/active_record/schema_dumper.rb +24 -23
- data/lib/active_record/schema_migration.rb +2 -0
- data/lib/active_record/scoping.rb +9 -8
- data/lib/active_record/scoping/default.rb +6 -7
- data/lib/active_record/scoping/named.rb +15 -7
- 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 +2 -0
- data/lib/active_record/suppressor.rb +2 -0
- data/lib/active_record/table_metadata.rb +3 -1
- data/lib/active_record/tasks/database_tasks.rb +23 -12
- 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 +5 -12
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +9 -7
- data/lib/active_record/translation.rb +2 -0
- data/lib/active_record/type.rb +4 -1
- 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 +2 -4
- 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_caster.rb +2 -0
- data/lib/active_record/type_caster/connection.rb +2 -0
- data/lib/active_record/type_caster/map.rb +2 -0
- data/lib/active_record/validations.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/version.rb +2 -0
- data/lib/rails/generators/active_record.rb +3 -1
- 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.rb +2 -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/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
- metadata +25 -38
- 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.rb +0 -240
- data/lib/active_record/attribute/user_provided_default.rb +0 -30
- data/lib/active_record/attribute_mutation_tracker.rb +0 -122
- data/lib/active_record/attribute_set.rb +0 -113
- data/lib/active_record/attribute_set/builder.rb +0 -126
- data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
- 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
|
# Returns the version of the currently loaded Active Record as a <tt>Gem::Version</tt>
|
3
5
|
def self.gem_version
|
@@ -6,9 +8,9 @@ module ActiveRecord
|
|
6
8
|
|
7
9
|
module VERSION
|
8
10
|
MAJOR = 5
|
9
|
-
MINOR =
|
10
|
-
TINY =
|
11
|
-
PRE =
|
11
|
+
MINOR = 2
|
12
|
+
TINY = 0
|
13
|
+
PRE = "beta1"
|
12
14
|
|
13
15
|
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
|
14
16
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/hash/indifferent_access"
|
2
4
|
|
3
5
|
module ActiveRecord
|
@@ -30,7 +32,7 @@ module ActiveRecord
|
|
30
32
|
# for differentiating between them or reloading the right type with find.
|
31
33
|
#
|
32
34
|
# Note, all the attributes for all the cases are kept in the same table. Read more:
|
33
|
-
#
|
35
|
+
# https://www.martinfowler.com/eaaCatalog/singleTableInheritance.html
|
34
36
|
#
|
35
37
|
module Inheritance
|
36
38
|
extend ActiveSupport::Concern
|
@@ -38,8 +40,7 @@ module ActiveRecord
|
|
38
40
|
included do
|
39
41
|
# Determines whether to store the full constant name including namespace when using STI.
|
40
42
|
# This is true, by default.
|
41
|
-
class_attribute :store_full_sti_class, instance_writer: false
|
42
|
-
self.store_full_sti_class = true
|
43
|
+
class_attribute :store_full_sti_class, instance_writer: false, default: true
|
43
44
|
end
|
44
45
|
|
45
46
|
module ClassMethods
|
@@ -217,7 +218,7 @@ module ActiveRecord
|
|
217
218
|
def subclass_from_attributes(attrs)
|
218
219
|
attrs = attrs.to_h if attrs.respond_to?(:permitted?)
|
219
220
|
if attrs.is_a?(Hash)
|
220
|
-
subclass_name = attrs
|
221
|
+
subclass_name = attrs[inheritance_column] || attrs[inheritance_column.to_sym]
|
221
222
|
|
222
223
|
if subclass_name.present?
|
223
224
|
find_sti_class(subclass_name)
|
@@ -246,7 +247,7 @@ module ActiveRecord
|
|
246
247
|
def ensure_proper_type
|
247
248
|
klass = self.class
|
248
249
|
if klass.finder_needs_type_condition?
|
249
|
-
|
250
|
+
_write_attribute(klass.inheritance_column, klass.sti_name)
|
250
251
|
end
|
251
252
|
end
|
252
253
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/string/filters"
|
2
4
|
|
3
5
|
module ActiveRecord
|
@@ -7,12 +9,19 @@ module ActiveRecord
|
|
7
9
|
included do
|
8
10
|
##
|
9
11
|
# :singleton-method:
|
10
|
-
# Indicates the format used to generate the timestamp in the cache key
|
11
|
-
# Accepts any of the symbols in <tt>Time::DATE_FORMATS</tt>.
|
12
|
+
# Indicates the format used to generate the timestamp in the cache key, if
|
13
|
+
# versioning is off. Accepts any of the symbols in <tt>Time::DATE_FORMATS</tt>.
|
12
14
|
#
|
13
15
|
# This is +:usec+, by default.
|
14
|
-
class_attribute :cache_timestamp_format, instance_writer: false
|
15
|
-
|
16
|
+
class_attribute :cache_timestamp_format, instance_writer: false, default: :usec
|
17
|
+
|
18
|
+
##
|
19
|
+
# :singleton-method:
|
20
|
+
# Indicates whether to use a stable #cache_key method that is accompanied
|
21
|
+
# by a changing version in the #cache_version method.
|
22
|
+
#
|
23
|
+
# This is +false+, by default until Rails 6.0.
|
24
|
+
class_attribute :cache_versioning, instance_writer: false, default: false
|
16
25
|
end
|
17
26
|
|
18
27
|
# Returns a +String+, which Action Pack uses for constructing a URL to this
|
@@ -42,35 +51,65 @@ module ActiveRecord
|
|
42
51
|
id && id.to_s # Be sure to stringify the id for routes
|
43
52
|
end
|
44
53
|
|
45
|
-
# Returns a cache key that can be used to identify this record.
|
54
|
+
# Returns a stable cache key that can be used to identify this record.
|
46
55
|
#
|
47
56
|
# Product.new.cache_key # => "products/new"
|
48
|
-
# Product.find(5).cache_key # => "products/5"
|
49
|
-
# Person.find(5).cache_key # => "people/5-20071224150000" (updated_at available)
|
57
|
+
# Product.find(5).cache_key # => "products/5"
|
50
58
|
#
|
51
|
-
#
|
52
|
-
#
|
59
|
+
# If ActiveRecord::Base.cache_versioning is turned off, as it was in Rails 5.1 and earlier,
|
60
|
+
# the cache key will also include a version.
|
53
61
|
#
|
54
|
-
#
|
62
|
+
# Product.cache_versioning = false
|
63
|
+
# Person.find(5).cache_key # => "people/5-20071224150000" (updated_at available)
|
55
64
|
def cache_key(*timestamp_names)
|
56
65
|
if new_record?
|
57
66
|
"#{model_name.cache_key}/new"
|
58
67
|
else
|
59
|
-
|
60
|
-
|
68
|
+
if cache_version && timestamp_names.none?
|
69
|
+
"#{model_name.cache_key}/#{id}"
|
61
70
|
else
|
62
|
-
|
63
|
-
|
71
|
+
timestamp = if timestamp_names.any?
|
72
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
73
|
+
Specifying a timestamp name for #cache_key has been deprecated in favor of
|
74
|
+
the explicit #cache_version method that can be overwritten.
|
75
|
+
MSG
|
64
76
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
77
|
+
max_updated_column_timestamp(timestamp_names)
|
78
|
+
else
|
79
|
+
max_updated_column_timestamp
|
80
|
+
end
|
81
|
+
|
82
|
+
if timestamp
|
83
|
+
timestamp = timestamp.utc.to_s(cache_timestamp_format)
|
84
|
+
"#{model_name.cache_key}/#{id}-#{timestamp}"
|
85
|
+
else
|
86
|
+
"#{model_name.cache_key}/#{id}"
|
87
|
+
end
|
70
88
|
end
|
71
89
|
end
|
72
90
|
end
|
73
91
|
|
92
|
+
# Returns a cache version that can be used together with the cache key to form
|
93
|
+
# a recyclable caching scheme. By default, the #updated_at column is used for the
|
94
|
+
# cache_version, but this method can be overwritten to return something else.
|
95
|
+
#
|
96
|
+
# Note, this method will return nil if ActiveRecord::Base.cache_versioning is set to
|
97
|
+
# +false+ (which it is by default until Rails 6.0).
|
98
|
+
def cache_version
|
99
|
+
if cache_versioning && timestamp = try(:updated_at)
|
100
|
+
timestamp.utc.to_s(:usec)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Returns a cache key along with the version.
|
105
|
+
def cache_key_with_version
|
106
|
+
if version = cache_version
|
107
|
+
"#{cache_key}-#{version}"
|
108
|
+
else
|
109
|
+
cache_key
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
74
113
|
module ClassMethods
|
75
114
|
# Defines your model's +to_param+ method to generate "pretty" URLs
|
76
115
|
# using +method_name+, which can be any attribute or method that
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module LegacyYamlAdapter
|
3
5
|
def self.convert(klass, coder)
|
@@ -6,7 +8,7 @@ module ActiveRecord
|
|
6
8
|
case coder["active_record_yaml_version"]
|
7
9
|
when 1, 2 then coder
|
8
10
|
else
|
9
|
-
if coder["attributes"].is_a?(AttributeSet)
|
11
|
+
if coder["attributes"].is_a?(ActiveModel::AttributeSet)
|
10
12
|
Rails420.convert(klass, coder)
|
11
13
|
else
|
12
14
|
Rails41.convert(klass, coder)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Locking
|
3
5
|
# == What is Optimistic Locking
|
@@ -51,8 +53,7 @@ module ActiveRecord
|
|
51
53
|
extend ActiveSupport::Concern
|
52
54
|
|
53
55
|
included do
|
54
|
-
class_attribute :lock_optimistically, instance_writer: false
|
55
|
-
self.lock_optimistically = true
|
56
|
+
class_attribute :lock_optimistically, instance_writer: false, default: true
|
56
57
|
end
|
57
58
|
|
58
59
|
def locking_enabled? #:nodoc:
|
@@ -60,6 +61,13 @@ module ActiveRecord
|
|
60
61
|
end
|
61
62
|
|
62
63
|
private
|
64
|
+
|
65
|
+
def increment_lock
|
66
|
+
lock_col = self.class.locking_column
|
67
|
+
previous_lock_value = send(lock_col)
|
68
|
+
send("#{lock_col}=", previous_lock_value + 1)
|
69
|
+
end
|
70
|
+
|
63
71
|
def _create_record(attribute_names = self.attribute_names, *)
|
64
72
|
if locking_enabled?
|
65
73
|
# We always want to persist the locking version, even if we don't detect
|
@@ -69,37 +77,40 @@ module ActiveRecord
|
|
69
77
|
super
|
70
78
|
end
|
71
79
|
|
72
|
-
def
|
73
|
-
super
|
74
|
-
ensure
|
75
|
-
clear_attribute_change(self.class.locking_column) if locking_enabled?
|
76
|
-
end
|
77
|
-
|
78
|
-
def _update_row(attribute_names, attempted_action = "update")
|
80
|
+
def _update_record(attribute_names = self.attribute_names)
|
79
81
|
return super unless locking_enabled?
|
82
|
+
return 0 if attribute_names.empty?
|
80
83
|
|
81
84
|
begin
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
+
lock_col = self.class.locking_column
|
86
|
+
|
87
|
+
previous_lock_value = read_attribute_before_type_cast(lock_col)
|
85
88
|
|
86
|
-
|
89
|
+
increment_lock
|
87
90
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
91
|
+
attribute_names.push(lock_col)
|
92
|
+
|
93
|
+
relation = self.class.unscoped
|
94
|
+
|
95
|
+
affected_rows = relation.where(
|
96
|
+
self.class.primary_key => id,
|
97
|
+
lock_col => previous_lock_value
|
98
|
+
).update_all(
|
99
|
+
attributes_for_update(attribute_names).map do |name|
|
100
|
+
[name, _read_attribute(name)]
|
101
|
+
end.to_h
|
92
102
|
)
|
93
103
|
|
94
|
-
|
95
|
-
raise ActiveRecord::StaleObjectError.new(self,
|
104
|
+
unless affected_rows == 1
|
105
|
+
raise ActiveRecord::StaleObjectError.new(self, "update")
|
96
106
|
end
|
97
107
|
|
98
108
|
affected_rows
|
99
109
|
|
100
110
|
# If something went wrong, revert the locking_column value.
|
101
111
|
rescue Exception
|
102
|
-
|
112
|
+
send("#{lock_col}=", previous_lock_value.to_i)
|
113
|
+
|
103
114
|
raise
|
104
115
|
end
|
105
116
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Locking
|
3
5
|
# Locking::Pessimistic provides support for row-level locking using
|
@@ -51,8 +53,8 @@ module ActiveRecord
|
|
51
53
|
# end
|
52
54
|
#
|
53
55
|
# Database-specific information on row locking:
|
54
|
-
# MySQL:
|
55
|
-
# PostgreSQL:
|
56
|
+
# MySQL: https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html
|
57
|
+
# PostgreSQL: https://www.postgresql.org/docs/current/interactive/sql-select.html#SQL-FOR-UPDATE-SHARE
|
56
58
|
module Pessimistic
|
57
59
|
# Obtain a row lock on this record. Reloads the record to obtain the requested
|
58
60
|
# lock. Pass an SQL locking clause to append the end of the SELECT statement
|
@@ -60,13 +62,14 @@ module ActiveRecord
|
|
60
62
|
# the locked record.
|
61
63
|
def lock!(lock = true)
|
62
64
|
if persisted?
|
63
|
-
if
|
64
|
-
|
65
|
-
Locking a record with unpersisted changes is
|
66
|
-
|
67
|
-
|
65
|
+
if changed?
|
66
|
+
raise(<<-MSG.squish)
|
67
|
+
Locking a record with unpersisted changes is not supported. Use
|
68
|
+
`save` to persist the changes, or `reload` to discard them
|
69
|
+
explicitly.
|
68
70
|
MSG
|
69
71
|
end
|
72
|
+
|
70
73
|
reload(lock: lock)
|
71
74
|
end
|
72
75
|
self
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "set"
|
2
4
|
require "zlib"
|
3
5
|
require "active_support/core_ext/module/attribute_accessors"
|
@@ -157,7 +159,7 @@ module ActiveRecord
|
|
157
159
|
|
158
160
|
class ProtectedEnvironmentError < ActiveRecordError #:nodoc:
|
159
161
|
def initialize(env = "production")
|
160
|
-
msg = "You are attempting to run a destructive action against your '#{env}' database.\n"
|
162
|
+
msg = "You are attempting to run a destructive action against your '#{env}' database.\n".dup
|
161
163
|
msg << "If you are sure you want to continue, run the same command with the environment variable:\n"
|
162
164
|
msg << "DISABLE_DATABASE_ENVIRONMENT_CHECK=1"
|
163
165
|
super(msg)
|
@@ -166,7 +168,7 @@ module ActiveRecord
|
|
166
168
|
|
167
169
|
class EnvironmentMismatchError < ActiveRecordError
|
168
170
|
def initialize(current: nil, stored: nil)
|
169
|
-
msg = "You are attempting to modify a database that was last run in `#{ stored }` environment.\n"
|
171
|
+
msg = "You are attempting to modify a database that was last run in `#{ stored }` environment.\n".dup
|
170
172
|
msg << "You are running in `#{ current }` environment. "
|
171
173
|
msg << "If you are sure you want to continue, first set the environment using:\n\n"
|
172
174
|
msg << " bin/rails db:environment:set"
|
@@ -352,9 +354,9 @@ module ActiveRecord
|
|
352
354
|
# to match the structure of your database.
|
353
355
|
#
|
354
356
|
# To roll the database back to a previous migration version, use
|
355
|
-
# <tt>rails db:
|
357
|
+
# <tt>rails db:rollback VERSION=X</tt> where <tt>X</tt> is the version to which
|
356
358
|
# you wish to downgrade. Alternatively, you can also use the STEP option if you
|
357
|
-
# wish to rollback last few migrations. <tt>rails db:
|
359
|
+
# wish to rollback last few migrations. <tt>rails db:rollback STEP=2</tt> will rollback
|
358
360
|
# the latest two migrations.
|
359
361
|
#
|
360
362
|
# If any of the migrations throw an <tt>ActiveRecord::IrreversibleMigration</tt> exception,
|
@@ -579,7 +581,8 @@ module ActiveRecord
|
|
579
581
|
def load_schema_if_pending!
|
580
582
|
if ActiveRecord::Migrator.needs_migration? || !ActiveRecord::Migrator.any_migrations?
|
581
583
|
# Roundtrip to Rake to allow plugins to hook into database initialization.
|
582
|
-
|
584
|
+
root = defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
|
585
|
+
FileUtils.cd(root) do
|
583
586
|
current_config = Base.connection_config
|
584
587
|
Base.clear_all_connections!
|
585
588
|
system("bin/rails db:test:prepare")
|
@@ -731,6 +734,24 @@ module ActiveRecord
|
|
731
734
|
execute_block { yield helper }
|
732
735
|
end
|
733
736
|
|
737
|
+
# Used to specify an operation that is only run when migrating up
|
738
|
+
# (for example, populating a new column with its initial values).
|
739
|
+
#
|
740
|
+
# In the following example, the new column +published+ will be given
|
741
|
+
# the value +true+ for all existing records.
|
742
|
+
#
|
743
|
+
# class AddPublishedToPosts < ActiveRecord::Migration[5.2]
|
744
|
+
# def change
|
745
|
+
# add_column :posts, :published, :boolean, default: false
|
746
|
+
# up_only do
|
747
|
+
# execute "update posts set published = 'true'"
|
748
|
+
# end
|
749
|
+
# end
|
750
|
+
# end
|
751
|
+
def up_only
|
752
|
+
execute_block { yield } unless reverting?
|
753
|
+
end
|
754
|
+
|
734
755
|
# Runs the given migration classes.
|
735
756
|
# Last argument can specify options:
|
736
757
|
# - :direction (default is :up)
|
@@ -863,15 +884,17 @@ module ActiveRecord
|
|
863
884
|
source_migrations.each do |migration|
|
864
885
|
source = File.binread(migration.filename)
|
865
886
|
inserted_comment = "# This migration comes from #{scope} (originally #{migration.version})\n"
|
866
|
-
|
887
|
+
magic_comments = "".dup
|
888
|
+
loop do
|
867
889
|
# If we have a magic comment in the original migration,
|
868
890
|
# insert our comment after the first newline(end of the magic comment line)
|
869
891
|
# so the magic keep working.
|
870
892
|
# Note that magic comments must be at the first line(except sh-bang).
|
871
|
-
source
|
872
|
-
|
873
|
-
|
893
|
+
source.sub!(/\A(?:#.*\b(?:en)?coding:\s*\S+|#\s*frozen_string_literal:\s*(?:true|false)).*\n/) do |magic_comment|
|
894
|
+
magic_comments << magic_comment; ""
|
895
|
+
end || break
|
874
896
|
end
|
897
|
+
source = "#{magic_comments}#{inserted_comment}#{source}"
|
875
898
|
|
876
899
|
if duplicate = destination_migrations.detect { |m| m.name == migration.name }
|
877
900
|
if options[:on_skip] && duplicate.scope != scope.to_s
|
@@ -1022,11 +1045,6 @@ module ActiveRecord
|
|
1022
1045
|
new(:up, migrations(migrations_paths), nil)
|
1023
1046
|
end
|
1024
1047
|
|
1025
|
-
def schema_migrations_table_name
|
1026
|
-
SchemaMigration.table_name
|
1027
|
-
end
|
1028
|
-
deprecate :schema_migrations_table_name
|
1029
|
-
|
1030
1048
|
def get_all_versions(connection = Base.connection)
|
1031
1049
|
if SchemaMigration.table_exists?
|
1032
1050
|
SchemaMigration.all_versions.map(&:to_i)
|
@@ -1104,13 +1122,21 @@ module ActiveRecord
|
|
1104
1122
|
|
1105
1123
|
def move(direction, migrations_paths, steps)
|
1106
1124
|
migrator = new(direction, migrations(migrations_paths))
|
1107
|
-
start_index = migrator.migrations.index(migrator.current_migration)
|
1108
1125
|
|
1109
|
-
if
|
1110
|
-
|
1111
|
-
version = finish ? finish.version : 0
|
1112
|
-
send(direction, migrations_paths, version)
|
1126
|
+
if current_version != 0 && !migrator.current_migration
|
1127
|
+
raise UnknownMigrationVersionError.new(current_version)
|
1113
1128
|
end
|
1129
|
+
|
1130
|
+
start_index =
|
1131
|
+
if current_version == 0
|
1132
|
+
0
|
1133
|
+
else
|
1134
|
+
migrator.migrations.index(migrator.current_migration)
|
1135
|
+
end
|
1136
|
+
|
1137
|
+
finish = migrator.migrations[start_index + steps]
|
1138
|
+
version = finish ? finish.version : 0
|
1139
|
+
send(direction, migrations_paths, version)
|
1114
1140
|
end
|
1115
1141
|
end
|
1116
1142
|
|
@@ -1217,7 +1243,7 @@ module ActiveRecord
|
|
1217
1243
|
|
1218
1244
|
# Return true if a valid version is not provided.
|
1219
1245
|
def invalid_target?
|
1220
|
-
|
1246
|
+
@target_version && @target_version != 0 && !target
|
1221
1247
|
end
|
1222
1248
|
|
1223
1249
|
def execute_migration_in_transaction(migration, direction)
|
@@ -1231,7 +1257,7 @@ module ActiveRecord
|
|
1231
1257
|
record_version_state_after_migrating(migration.version)
|
1232
1258
|
end
|
1233
1259
|
rescue => e
|
1234
|
-
msg = "An error has occurred, "
|
1260
|
+
msg = "An error has occurred, ".dup
|
1235
1261
|
msg << "this and " if use_transaction?(migration)
|
1236
1262
|
msg << "all later migrations canceled:\n\n#{e}"
|
1237
1263
|
raise StandardError, msg, e.backtrace
|