activerecord 4.2.11.1 → 5.2.4.5
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 +594 -1620
- data/MIT-LICENSE +2 -2
- data/README.rdoc +10 -11
- data/examples/performance.rb +32 -31
- data/examples/simple.rb +5 -4
- data/lib/active_record/aggregations.rb +263 -249
- data/lib/active_record/association_relation.rb +11 -6
- data/lib/active_record/associations/alias_tracker.rb +29 -35
- data/lib/active_record/associations/association.rb +77 -43
- data/lib/active_record/associations/association_scope.rb +106 -133
- data/lib/active_record/associations/belongs_to_association.rb +52 -41
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
- data/lib/active_record/associations/builder/association.rb +29 -38
- data/lib/active_record/associations/builder/belongs_to.rb +77 -30
- data/lib/active_record/associations/builder/collection_association.rb +9 -22
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +42 -35
- data/lib/active_record/associations/builder/has_many.rb +6 -4
- data/lib/active_record/associations/builder/has_one.rb +13 -6
- data/lib/active_record/associations/builder/singular_association.rb +15 -11
- data/lib/active_record/associations/collection_association.rb +139 -280
- data/lib/active_record/associations/collection_proxy.rb +231 -133
- data/lib/active_record/associations/foreign_association.rb +3 -1
- data/lib/active_record/associations/has_many_association.rb +34 -89
- data/lib/active_record/associations/has_many_through_association.rb +49 -76
- data/lib/active_record/associations/has_one_association.rb +38 -24
- data/lib/active_record/associations/has_one_through_association.rb +18 -9
- data/lib/active_record/associations/join_dependency/join_association.rb +40 -87
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
- data/lib/active_record/associations/join_dependency.rb +133 -159
- data/lib/active_record/associations/preloader/association.rb +85 -120
- data/lib/active_record/associations/preloader/through_association.rb +85 -74
- data/lib/active_record/associations/preloader.rb +81 -91
- data/lib/active_record/associations/singular_association.rb +27 -34
- data/lib/active_record/associations/through_association.rb +38 -18
- data/lib/active_record/associations.rb +1732 -1597
- data/lib/active_record/attribute_assignment.rb +58 -182
- data/lib/active_record/attribute_decorators.rb +39 -15
- data/lib/active_record/attribute_methods/before_type_cast.rb +10 -8
- data/lib/active_record/attribute_methods/dirty.rb +94 -135
- data/lib/active_record/attribute_methods/primary_key.rb +86 -71
- data/lib/active_record/attribute_methods/query.rb +4 -2
- data/lib/active_record/attribute_methods/read.rb +45 -63
- data/lib/active_record/attribute_methods/serialization.rb +40 -20
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +58 -36
- data/lib/active_record/attribute_methods/write.rb +30 -45
- data/lib/active_record/attribute_methods.rb +166 -109
- data/lib/active_record/attributes.rb +201 -82
- data/lib/active_record/autosave_association.rb +94 -36
- data/lib/active_record/base.rb +57 -44
- data/lib/active_record/callbacks.rb +97 -57
- data/lib/active_record/coders/json.rb +3 -1
- data/lib/active_record/coders/yaml_column.rb +24 -12
- data/lib/active_record/collection_cache_key.rb +53 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +712 -290
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +10 -5
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +237 -90
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +71 -21
- data/lib/active_record/connection_adapters/abstract/quoting.rb +118 -52
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +67 -46
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +318 -217
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +81 -36
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +570 -228
- data/lib/active_record/connection_adapters/abstract/transaction.rb +138 -70
- data/lib/active_record/connection_adapters/abstract_adapter.rb +325 -202
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +542 -601
- data/lib/active_record/connection_adapters/column.rb +50 -41
- data/lib/active_record/connection_adapters/connection_specification.rb +147 -135
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +33 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +140 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +73 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +87 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +80 -0
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +148 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +35 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +41 -180
- data/lib/active_record/connection_adapters/postgresql/column.rb +35 -11
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +45 -114
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -58
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +10 -6
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -22
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
- data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +55 -53
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +107 -47
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +65 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +144 -90
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +462 -284
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +39 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +432 -323
- data/lib/active_record/connection_adapters/schema_cache.rb +48 -24
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +34 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +67 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +106 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +269 -308
- data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
- data/lib/active_record/connection_handling.rb +40 -27
- data/lib/active_record/core.rb +178 -198
- data/lib/active_record/counter_cache.rb +79 -36
- data/lib/active_record/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +87 -105
- data/lib/active_record/enum.rb +135 -88
- data/lib/active_record/errors.rb +179 -52
- data/lib/active_record/explain.rb +23 -11
- data/lib/active_record/explain_registry.rb +4 -2
- data/lib/active_record/explain_subscriber.rb +10 -5
- data/lib/active_record/fixture_set/file.rb +35 -9
- data/lib/active_record/fixtures.rb +188 -132
- data/lib/active_record/gem_version.rb +5 -3
- data/lib/active_record/inheritance.rb +148 -112
- data/lib/active_record/integration.rb +70 -28
- data/lib/active_record/internal_metadata.rb +45 -0
- data/lib/active_record/legacy_yaml_adapter.rb +21 -3
- data/lib/active_record/locale/en.yml +3 -2
- data/lib/active_record/locking/optimistic.rb +88 -96
- data/lib/active_record/locking/pessimistic.rb +15 -3
- data/lib/active_record/log_subscriber.rb +95 -33
- data/lib/active_record/migration/command_recorder.rb +133 -90
- data/lib/active_record/migration/compatibility.rb +217 -0
- data/lib/active_record/migration/join_table.rb +8 -6
- data/lib/active_record/migration.rb +581 -282
- data/lib/active_record/model_schema.rb +290 -111
- data/lib/active_record/nested_attributes.rb +264 -222
- data/lib/active_record/no_touching.rb +7 -1
- data/lib/active_record/null_relation.rb +24 -37
- data/lib/active_record/persistence.rb +347 -119
- data/lib/active_record/query_cache.rb +13 -24
- data/lib/active_record/querying.rb +19 -17
- data/lib/active_record/railtie.rb +94 -32
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +9 -3
- data/lib/active_record/railties/databases.rake +149 -156
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +414 -267
- data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
- data/lib/active_record/relation/batches.rb +204 -55
- data/lib/active_record/relation/calculations.rb +256 -248
- data/lib/active_record/relation/delegation.rb +67 -60
- data/lib/active_record/relation/finder_methods.rb +288 -239
- data/lib/active_record/relation/from_clause.rb +26 -0
- data/lib/active_record/relation/merger.rb +86 -86
- data/lib/active_record/relation/predicate_builder/array_handler.rb +24 -24
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +19 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +20 -0
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +42 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
- data/lib/active_record/relation/predicate_builder.rb +116 -119
- data/lib/active_record/relation/query_attribute.rb +45 -0
- data/lib/active_record/relation/query_methods.rb +448 -393
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +11 -13
- data/lib/active_record/relation/where_clause.rb +186 -0
- data/lib/active_record/relation/where_clause_factory.rb +34 -0
- data/lib/active_record/relation.rb +287 -340
- data/lib/active_record/result.rb +54 -36
- data/lib/active_record/runtime_registry.rb +6 -4
- data/lib/active_record/sanitization.rb +155 -124
- data/lib/active_record/schema.rb +30 -24
- data/lib/active_record/schema_dumper.rb +91 -87
- data/lib/active_record/schema_migration.rb +19 -16
- data/lib/active_record/scoping/default.rb +102 -85
- data/lib/active_record/scoping/named.rb +81 -32
- data/lib/active_record/scoping.rb +45 -26
- data/lib/active_record/secure_token.rb +40 -0
- data/lib/active_record/serialization.rb +5 -5
- data/lib/active_record/statement_cache.rb +45 -35
- data/lib/active_record/store.rb +42 -36
- data/lib/active_record/suppressor.rb +61 -0
- data/lib/active_record/table_metadata.rb +82 -0
- data/lib/active_record/tasks/database_tasks.rb +134 -96
- data/lib/active_record/tasks/mysql_database_tasks.rb +56 -100
- data/lib/active_record/tasks/postgresql_database_tasks.rb +83 -41
- data/lib/active_record/tasks/sqlite_database_tasks.rb +44 -16
- data/lib/active_record/timestamp.rb +70 -38
- data/lib/active_record/touch_later.rb +64 -0
- data/lib/active_record/transactions.rb +199 -124
- data/lib/active_record/translation.rb +2 -0
- data/lib/active_record/type/adapter_specific_registry.rb +136 -0
- data/lib/active_record/type/date.rb +4 -45
- data/lib/active_record/type/date_time.rb +4 -49
- data/lib/active_record/type/decimal_without_scale.rb +6 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
- data/lib/active_record/type/internal/timezone.rb +17 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +24 -15
- data/lib/active_record/type/text.rb +2 -2
- data/lib/active_record/type/time.rb +11 -16
- data/lib/active_record/type/type_map.rb +15 -17
- data/lib/active_record/type/unsigned_integer.rb +9 -7
- data/lib/active_record/type.rb +79 -23
- data/lib/active_record/type_caster/connection.rb +33 -0
- data/lib/active_record/type_caster/map.rb +23 -0
- data/lib/active_record/type_caster.rb +9 -0
- data/lib/active_record/validations/absence.rb +25 -0
- data/lib/active_record/validations/associated.rb +13 -4
- data/lib/active_record/validations/length.rb +26 -0
- data/lib/active_record/validations/presence.rb +14 -13
- data/lib/active_record/validations/uniqueness.rb +40 -41
- data/lib/active_record/validations.rb +38 -35
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +34 -22
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +43 -35
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +8 -3
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +8 -1
- data/lib/rails/generators/active_record/migration.rb +18 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +18 -22
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +3 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +72 -49
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -24
- data/lib/active_record/associations/preloader/has_many.rb +0 -17
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -23
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -21
- data/lib/active_record/attribute.rb +0 -163
- data/lib/active_record/attribute_set/builder.rb +0 -106
- data/lib/active_record/attribute_set.rb +0 -81
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
- data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
- data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/serializers/xml_serializer.rb +0 -193
- data/lib/active_record/type/big_integer.rb +0 -13
- data/lib/active_record/type/binary.rb +0 -50
- data/lib/active_record/type/boolean.rb +0 -31
- data/lib/active_record/type/decimal.rb +0 -64
- data/lib/active_record/type/decorator.rb +0 -14
- data/lib/active_record/type/float.rb +0 -19
- data/lib/active_record/type/integer.rb +0 -59
- data/lib/active_record/type/mutable.rb +0 -16
- data/lib/active_record/type/numeric.rb +0 -36
- data/lib/active_record/type/string.rb +0 -40
- data/lib/active_record/type/time_value.rb +0 -38
- data/lib/active_record/type/value.rb +0 -110
data/lib/active_record/base.rb
CHANGED
@@ -1,27 +1,28 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
16
|
-
require
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
20
|
-
require
|
21
|
-
require
|
22
|
-
require
|
23
|
-
require
|
24
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "yaml"
|
4
|
+
require "active_support/benchmarkable"
|
5
|
+
require "active_support/dependencies"
|
6
|
+
require "active_support/descendants_tracker"
|
7
|
+
require "active_support/time"
|
8
|
+
require "active_support/core_ext/module/attribute_accessors"
|
9
|
+
require "active_support/core_ext/array/extract_options"
|
10
|
+
require "active_support/core_ext/hash/deep_merge"
|
11
|
+
require "active_support/core_ext/hash/slice"
|
12
|
+
require "active_support/core_ext/hash/transform_values"
|
13
|
+
require "active_support/core_ext/string/behavior"
|
14
|
+
require "active_support/core_ext/kernel/singleton_class"
|
15
|
+
require "active_support/core_ext/module/introspection"
|
16
|
+
require "active_support/core_ext/object/duplicable"
|
17
|
+
require "active_support/core_ext/class/subclasses"
|
18
|
+
require "active_record/attribute_decorators"
|
19
|
+
require "active_record/define_callbacks"
|
20
|
+
require "active_record/errors"
|
21
|
+
require "active_record/log_subscriber"
|
22
|
+
require "active_record/explain_subscriber"
|
23
|
+
require "active_record/relation/delegation"
|
24
|
+
require "active_record/attributes"
|
25
|
+
require "active_record/type_caster"
|
25
26
|
|
26
27
|
module ActiveRecord #:nodoc:
|
27
28
|
# = Active Record
|
@@ -133,14 +134,11 @@ module ActiveRecord #:nodoc:
|
|
133
134
|
# end
|
134
135
|
# end
|
135
136
|
#
|
136
|
-
# You can alternatively use <tt>self[:attribute]=(value)</tt> and <tt>self[:attribute]</tt>
|
137
|
-
# or <tt>write_attribute(:attribute, value)</tt> and <tt>read_attribute(:attribute)</tt>.
|
138
|
-
#
|
139
137
|
# == Attribute query methods
|
140
138
|
#
|
141
139
|
# In addition to the basic accessors, query methods are also automatically available on the Active Record object.
|
142
140
|
# Query methods allow you to test whether an attribute value is present.
|
143
|
-
#
|
141
|
+
# Additionally, when dealing with numeric values, a query method will return false if the value is zero.
|
144
142
|
#
|
145
143
|
# For example, an Active Record User with the <tt>name</tt> attribute has a <tt>name?</tt> method that you can call
|
146
144
|
# to determine whether the user has a name:
|
@@ -171,10 +169,11 @@ module ActiveRecord #:nodoc:
|
|
171
169
|
# <tt>Person.find_by_user_name(user_name)</tt>.
|
172
170
|
#
|
173
171
|
# It's possible to add an exclamation point (!) on the end of the dynamic finders to get them to raise an
|
174
|
-
#
|
172
|
+
# ActiveRecord::RecordNotFound error if they do not return any records,
|
175
173
|
# like <tt>Person.find_by_last_name!</tt>.
|
176
174
|
#
|
177
|
-
# It's also possible to use multiple attributes in the same
|
175
|
+
# It's also possible to use multiple attributes in the same <tt>find_by_</tt> by separating them with
|
176
|
+
# "_and_".
|
178
177
|
#
|
179
178
|
# Person.find_by(user_name: user_name, password: password)
|
180
179
|
# Person.find_by_user_name_and_password(user_name, password) # with dynamic finder
|
@@ -186,7 +185,8 @@ module ActiveRecord #:nodoc:
|
|
186
185
|
# == Saving arrays, hashes, and other non-mappable objects in text columns
|
187
186
|
#
|
188
187
|
# Active Record can serialize any object in text columns using YAML. To do so, you must
|
189
|
-
# specify this with a call to the class method
|
188
|
+
# specify this with a call to the class method
|
189
|
+
# {serialize}[rdoc-ref:AttributeMethods::Serialization::ClassMethods#serialize].
|
190
190
|
# This makes it possible to store arrays, hashes, and other non-mappable objects without doing
|
191
191
|
# any additional work.
|
192
192
|
#
|
@@ -226,39 +226,47 @@ module ActiveRecord #:nodoc:
|
|
226
226
|
#
|
227
227
|
# == Connection to multiple databases in different models
|
228
228
|
#
|
229
|
-
# Connections are usually created through
|
229
|
+
# Connections are usually created through
|
230
|
+
# {ActiveRecord::Base.establish_connection}[rdoc-ref:ConnectionHandling#establish_connection] and retrieved
|
230
231
|
# by ActiveRecord::Base.connection. All classes inheriting from ActiveRecord::Base will use this
|
231
232
|
# connection. But you can also set a class-specific connection. For example, if Course is an
|
232
233
|
# ActiveRecord::Base, but resides in a different database, you can just say <tt>Course.establish_connection</tt>
|
233
234
|
# and Course and all of its subclasses will use this connection instead.
|
234
235
|
#
|
235
236
|
# This feature is implemented by keeping a connection pool in ActiveRecord::Base that is
|
236
|
-
# a
|
237
|
+
# a hash indexed by the class. If a connection is requested, the
|
238
|
+
# {ActiveRecord::Base.retrieve_connection}[rdoc-ref:ConnectionHandling#retrieve_connection] method
|
237
239
|
# will go up the class-hierarchy until a connection is found in the connection pool.
|
238
240
|
#
|
239
241
|
# == Exceptions
|
240
242
|
#
|
241
243
|
# * ActiveRecordError - Generic error class and superclass of all other errors raised by Active Record.
|
242
|
-
# * AdapterNotSpecified - The configuration hash used in
|
243
|
-
#
|
244
|
-
#
|
245
|
-
#
|
244
|
+
# * AdapterNotSpecified - The configuration hash used in
|
245
|
+
# {ActiveRecord::Base.establish_connection}[rdoc-ref:ConnectionHandling#establish_connection]
|
246
|
+
# didn't include an <tt>:adapter</tt> key.
|
247
|
+
# * AdapterNotFound - The <tt>:adapter</tt> key used in
|
248
|
+
# {ActiveRecord::Base.establish_connection}[rdoc-ref:ConnectionHandling#establish_connection]
|
249
|
+
# specified a non-existent adapter
|
246
250
|
# (or a bad spelling of an existing one).
|
247
251
|
# * AssociationTypeMismatch - The object assigned to the association wasn't of the type
|
248
252
|
# specified in the association definition.
|
249
253
|
# * AttributeAssignmentError - An error occurred while doing a mass assignment through the
|
250
|
-
#
|
254
|
+
# {ActiveRecord::Base#attributes=}[rdoc-ref:AttributeAssignment#attributes=] method.
|
251
255
|
# You can inspect the +attribute+ property of the exception object to determine which attribute
|
252
256
|
# triggered the error.
|
253
|
-
# * ConnectionNotEstablished - No connection has been established.
|
254
|
-
# before querying.
|
257
|
+
# * ConnectionNotEstablished - No connection has been established.
|
258
|
+
# Use {ActiveRecord::Base.establish_connection}[rdoc-ref:ConnectionHandling#establish_connection] before querying.
|
255
259
|
# * MultiparameterAssignmentErrors - Collection of errors that occurred during a mass assignment using the
|
256
|
-
#
|
260
|
+
# {ActiveRecord::Base#attributes=}[rdoc-ref:AttributeAssignment#attributes=] method.
|
261
|
+
# The +errors+ property of this exception contains an array of
|
257
262
|
# AttributeAssignmentError
|
258
263
|
# objects that should be inspected to determine which attributes triggered the errors.
|
259
|
-
# * RecordInvalid - raised by save! and
|
260
|
-
#
|
261
|
-
#
|
264
|
+
# * RecordInvalid - raised by {ActiveRecord::Base#save!}[rdoc-ref:Persistence#save!] and
|
265
|
+
# {ActiveRecord::Base.create!}[rdoc-ref:Persistence::ClassMethods#create!]
|
266
|
+
# when the record is invalid.
|
267
|
+
# * RecordNotFound - No record responded to the {ActiveRecord::Base.find}[rdoc-ref:FinderMethods#find] method.
|
268
|
+
# Either the row with the given ID doesn't exist or the row didn't meet the additional restrictions.
|
269
|
+
# Some {ActiveRecord::Base.find}[rdoc-ref:FinderMethods#find] calls do not raise this exception to signal
|
262
270
|
# nothing was found, please check its documentation for further details.
|
263
271
|
# * SerializationTypeMismatch - The serialized object wasn't of the class specified as the second parameter.
|
264
272
|
# * StatementInvalid - The database server rejected the SQL statement. The precise error is added in the message.
|
@@ -280,6 +288,7 @@ module ActiveRecord #:nodoc:
|
|
280
288
|
extend Explain
|
281
289
|
extend Enum
|
282
290
|
extend Delegation::DelegateCache
|
291
|
+
extend CollectionCacheKey
|
283
292
|
|
284
293
|
include Core
|
285
294
|
include Persistence
|
@@ -297,6 +306,7 @@ module ActiveRecord #:nodoc:
|
|
297
306
|
include AttributeDecorators
|
298
307
|
include Locking::Optimistic
|
299
308
|
include Locking::Pessimistic
|
309
|
+
include DefineCallbacks
|
300
310
|
include AttributeMethods
|
301
311
|
include Callbacks
|
302
312
|
include Timestamp
|
@@ -306,10 +316,13 @@ module ActiveRecord #:nodoc:
|
|
306
316
|
include NestedAttributes
|
307
317
|
include Aggregations
|
308
318
|
include Transactions
|
319
|
+
include TouchLater
|
309
320
|
include NoTouching
|
310
321
|
include Reflection
|
311
322
|
include Serialization
|
312
323
|
include Store
|
324
|
+
include SecureToken
|
325
|
+
include Suppressor
|
313
326
|
end
|
314
327
|
|
315
328
|
ActiveSupport.run_load_hooks(:active_record, Base)
|
@@ -1,11 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
|
-
# = Active Record Callbacks
|
4
|
+
# = Active Record \Callbacks
|
3
5
|
#
|
4
|
-
# Callbacks are hooks into the life cycle of an Active Record object that allow you to trigger logic
|
6
|
+
# \Callbacks are hooks into the life cycle of an Active Record object that allow you to trigger logic
|
5
7
|
# before or after an alteration of the object state. This can be used to make sure that associated and
|
6
|
-
# dependent objects are deleted when
|
7
|
-
# before they're validated (by overwriting +before_validation+).
|
8
|
-
# the
|
8
|
+
# dependent objects are deleted when {ActiveRecord::Base#destroy}[rdoc-ref:Persistence#destroy] is called (by overwriting +before_destroy+) or
|
9
|
+
# to massage attributes before they're validated (by overwriting +before_validation+).
|
10
|
+
# As an example of the callbacks initiated, consider the {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] call for a new record:
|
9
11
|
#
|
10
12
|
# * (-) <tt>save</tt>
|
11
13
|
# * (-) <tt>valid</tt>
|
@@ -20,7 +22,7 @@ module ActiveRecord
|
|
20
22
|
# * (7) <tt>after_commit</tt>
|
21
23
|
#
|
22
24
|
# Also, an <tt>after_rollback</tt> callback can be configured to be triggered whenever a rollback is issued.
|
23
|
-
# Check out
|
25
|
+
# Check out ActiveRecord::Transactions for more details about <tt>after_commit</tt> and
|
24
26
|
# <tt>after_rollback</tt>.
|
25
27
|
#
|
26
28
|
# Additionally, an <tt>after_touch</tt> callback is triggered whenever an
|
@@ -31,7 +33,7 @@ module ActiveRecord
|
|
31
33
|
# are instantiated as well.
|
32
34
|
#
|
33
35
|
# There are nineteen callbacks in total, which give you immense power to react and prepare for each state in the
|
34
|
-
# Active Record life cycle. The sequence for calling
|
36
|
+
# Active Record life cycle. The sequence for calling {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] for an existing record is similar,
|
35
37
|
# except that each <tt>_create</tt> callback is replaced by the corresponding <tt>_update</tt> callback.
|
36
38
|
#
|
37
39
|
# Examples:
|
@@ -53,9 +55,9 @@ module ActiveRecord
|
|
53
55
|
# end
|
54
56
|
#
|
55
57
|
# class Firm < ActiveRecord::Base
|
56
|
-
# #
|
57
|
-
# before_destroy { |record| Person.
|
58
|
-
# before_destroy { |record| Client.
|
58
|
+
# # Disables access to the system, for associated clients and people when the firm is destroyed
|
59
|
+
# before_destroy { |record| Person.where(firm_id: record.id).update_all(access: 'disabled') }
|
60
|
+
# before_destroy { |record| Client.where(client_of: record.id).update_all(access: 'disabled') }
|
59
61
|
# end
|
60
62
|
#
|
61
63
|
# == Inheritable callback queues
|
@@ -96,9 +98,9 @@ module ActiveRecord
|
|
96
98
|
# == Types of callbacks
|
97
99
|
#
|
98
100
|
# There are four types of callbacks accepted by the callback macros: Method references (symbol), callback objects,
|
99
|
-
# inline methods (using a proc)
|
101
|
+
# inline methods (using a proc). Method references and callback objects
|
100
102
|
# are the recommended approaches, inline methods using a proc are sometimes appropriate (such as for
|
101
|
-
# creating mix-ins)
|
103
|
+
# creating mix-ins).
|
102
104
|
#
|
103
105
|
# The method reference callbacks work by specifying a protected or private method available in the object, like this:
|
104
106
|
#
|
@@ -175,43 +177,30 @@ module ActiveRecord
|
|
175
177
|
# end
|
176
178
|
# end
|
177
179
|
#
|
178
|
-
# The callback macros usually accept a symbol for the method they're supposed to run, but you can also
|
179
|
-
# pass a "method string", which will then be evaluated within the binding of the callback. Example:
|
180
|
-
#
|
181
|
-
# class Topic < ActiveRecord::Base
|
182
|
-
# before_destroy 'self.class.delete_all "parent_id = #{id}"'
|
183
|
-
# end
|
184
|
-
#
|
185
|
-
# Notice that single quotes (') are used so the <tt>#{id}</tt> part isn't evaluated until the callback
|
186
|
-
# is triggered. Also note that these inline callbacks can be stacked just like the regular ones:
|
187
|
-
#
|
188
|
-
# class Topic < ActiveRecord::Base
|
189
|
-
# before_destroy 'self.class.delete_all "parent_id = #{id}"',
|
190
|
-
# 'puts "Evaluated after parents are destroyed"'
|
191
|
-
# end
|
192
|
-
#
|
193
180
|
# == <tt>before_validation*</tt> returning statements
|
194
181
|
#
|
195
|
-
# If the
|
196
|
-
# aborted and
|
197
|
-
# ActiveRecord::
|
182
|
+
# If the +before_validation+ callback throws +:abort+, the process will be
|
183
|
+
# aborted and {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] will return +false+.
|
184
|
+
# If {ActiveRecord::Base#save!}[rdoc-ref:Persistence#save!] is called it will raise an ActiveRecord::RecordInvalid exception.
|
185
|
+
# Nothing will be appended to the errors object.
|
198
186
|
#
|
199
187
|
# == Canceling callbacks
|
200
188
|
#
|
201
|
-
# If a <tt>before_*</tt> callback
|
202
|
-
# cancelled.
|
189
|
+
# If a <tt>before_*</tt> callback throws +:abort+, all the later callbacks and
|
190
|
+
# the associated action are cancelled.
|
203
191
|
# Callbacks are generally run in the order they are defined, with the exception of callbacks defined as
|
204
192
|
# methods on the model, which are called last.
|
205
193
|
#
|
206
194
|
# == Ordering callbacks
|
207
195
|
#
|
208
196
|
# Sometimes the code needs that the callbacks execute in a specific order. For example, a +before_destroy+
|
209
|
-
# callback (+log_children+ in this case) should be executed before the children get destroyed by the
|
197
|
+
# callback (+log_children+ in this case) should be executed before the children get destroyed by the
|
198
|
+
# <tt>dependent: :destroy</tt> option.
|
210
199
|
#
|
211
200
|
# Let's look at the code below:
|
212
201
|
#
|
213
202
|
# class Topic < ActiveRecord::Base
|
214
|
-
# has_many :children, dependent: destroy
|
203
|
+
# has_many :children, dependent: :destroy
|
215
204
|
#
|
216
205
|
# before_destroy :log_children
|
217
206
|
#
|
@@ -222,10 +211,11 @@ module ActiveRecord
|
|
222
211
|
# end
|
223
212
|
#
|
224
213
|
# In this case, the problem is that when the +before_destroy+ callback is executed, the children are not available
|
225
|
-
# because the
|
214
|
+
# because the {ActiveRecord::Base#destroy}[rdoc-ref:Persistence#destroy] callback gets executed first.
|
215
|
+
# You can use the +prepend+ option on the +before_destroy+ callback to avoid this.
|
226
216
|
#
|
227
217
|
# class Topic < ActiveRecord::Base
|
228
|
-
# has_many :children, dependent: destroy
|
218
|
+
# has_many :children, dependent: :destroy
|
229
219
|
#
|
230
220
|
# before_destroy :log_children, prepend: true
|
231
221
|
#
|
@@ -235,23 +225,72 @@ module ActiveRecord
|
|
235
225
|
# end
|
236
226
|
# end
|
237
227
|
#
|
238
|
-
# This way, the +before_destroy+ gets executed before the <tt>dependent: destroy</tt> is called, and the data is still available.
|
228
|
+
# This way, the +before_destroy+ gets executed before the <tt>dependent: :destroy</tt> is called, and the data is still available.
|
229
|
+
#
|
230
|
+
# Also, there are cases when you want several callbacks of the same type to
|
231
|
+
# be executed in order.
|
232
|
+
#
|
233
|
+
# For example:
|
234
|
+
#
|
235
|
+
# class Topic < ActiveRecord::Base
|
236
|
+
# has_many :children
|
237
|
+
#
|
238
|
+
# after_save :log_children
|
239
|
+
# after_save :do_something_else
|
240
|
+
#
|
241
|
+
# private
|
242
|
+
#
|
243
|
+
# def log_children
|
244
|
+
# # Child processing
|
245
|
+
# end
|
246
|
+
#
|
247
|
+
# def do_something_else
|
248
|
+
# # Something else
|
249
|
+
# end
|
250
|
+
# end
|
251
|
+
#
|
252
|
+
# In this case the +log_children+ gets executed before +do_something_else+.
|
253
|
+
# The same applies to all non-transactional callbacks.
|
254
|
+
#
|
255
|
+
# In case there are multiple transactional callbacks as seen below, the order
|
256
|
+
# is reversed.
|
257
|
+
#
|
258
|
+
# For example:
|
239
259
|
#
|
240
|
-
#
|
260
|
+
# class Topic < ActiveRecord::Base
|
261
|
+
# has_many :children
|
262
|
+
#
|
263
|
+
# after_commit :log_children
|
264
|
+
# after_commit :do_something_else
|
241
265
|
#
|
242
|
-
#
|
243
|
-
#
|
244
|
-
#
|
266
|
+
# private
|
267
|
+
#
|
268
|
+
# def log_children
|
269
|
+
# # Child processing
|
270
|
+
# end
|
271
|
+
#
|
272
|
+
# def do_something_else
|
273
|
+
# # Something else
|
274
|
+
# end
|
275
|
+
# end
|
276
|
+
#
|
277
|
+
# In this case the +do_something_else+ gets executed before +log_children+.
|
278
|
+
#
|
279
|
+
# == \Transactions
|
280
|
+
#
|
281
|
+
# The entire callback chain of a {#save}[rdoc-ref:Persistence#save], {#save!}[rdoc-ref:Persistence#save!],
|
282
|
+
# or {#destroy}[rdoc-ref:Persistence#destroy] call runs within a transaction. That includes <tt>after_*</tt> hooks.
|
283
|
+
# If everything goes fine a COMMIT is executed once the chain has been completed.
|
245
284
|
#
|
246
285
|
# If a <tt>before_*</tt> callback cancels the action a ROLLBACK is issued. You
|
247
286
|
# can also trigger a ROLLBACK raising an exception in any of the callbacks,
|
248
287
|
# including <tt>after_*</tt> hooks. Note, however, that in that case the client
|
249
|
-
# needs to be aware of it because an ordinary
|
288
|
+
# needs to be aware of it because an ordinary {#save}[rdoc-ref:Persistence#save] will raise such exception
|
250
289
|
# instead of quietly returning +false+.
|
251
290
|
#
|
252
291
|
# == Debugging callbacks
|
253
292
|
#
|
254
|
-
# The callback chain is accessible via the <tt>_*_callbacks</tt> method on an object.
|
293
|
+
# The callback chain is accessible via the <tt>_*_callbacks</tt> method on an object. Active Model \Callbacks support
|
255
294
|
# <tt>:before</tt>, <tt>:after</tt> and <tt>:around</tt> as values for the <tt>kind</tt> property. The <tt>kind</tt> property
|
256
295
|
# defines what part of the chain the callback runs in.
|
257
296
|
#
|
@@ -277,36 +316,37 @@ module ActiveRecord
|
|
277
316
|
:before_destroy, :around_destroy, :after_destroy, :after_commit, :after_rollback
|
278
317
|
]
|
279
318
|
|
280
|
-
module ClassMethods
|
281
|
-
include ActiveModel::Callbacks
|
282
|
-
end
|
283
|
-
|
284
|
-
included do
|
285
|
-
include ActiveModel::Validations::Callbacks
|
286
|
-
|
287
|
-
define_model_callbacks :initialize, :find, :touch, :only => :after
|
288
|
-
define_model_callbacks :save, :create, :update, :destroy
|
289
|
-
end
|
290
|
-
|
291
319
|
def destroy #:nodoc:
|
320
|
+
@_destroy_callback_already_called ||= false
|
321
|
+
return if @_destroy_callback_already_called
|
322
|
+
@_destroy_callback_already_called = true
|
292
323
|
_run_destroy_callbacks { super }
|
324
|
+
rescue RecordNotDestroyed => e
|
325
|
+
@_association_destroy_exception = e
|
326
|
+
false
|
327
|
+
ensure
|
328
|
+
@_destroy_callback_already_called = false
|
293
329
|
end
|
294
330
|
|
295
331
|
def touch(*) #:nodoc:
|
296
332
|
_run_touch_callbacks { super }
|
297
333
|
end
|
298
334
|
|
335
|
+
def increment!(attribute, by = 1, touch: nil) # :nodoc:
|
336
|
+
touch ? _run_touch_callbacks { super } : super
|
337
|
+
end
|
338
|
+
|
299
339
|
private
|
300
340
|
|
301
|
-
def create_or_update
|
341
|
+
def create_or_update(*)
|
302
342
|
_run_save_callbacks { super }
|
303
343
|
end
|
304
344
|
|
305
|
-
def _create_record
|
345
|
+
def _create_record
|
306
346
|
_run_create_callbacks { super }
|
307
347
|
end
|
308
348
|
|
309
|
-
def _update_record(*)
|
349
|
+
def _update_record(*)
|
310
350
|
_run_update_callbacks { super }
|
311
351
|
end
|
312
352
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Coders # :nodoc:
|
3
5
|
class JSON # :nodoc:
|
@@ -6,7 +8,7 @@ module ActiveRecord
|
|
6
8
|
end
|
7
9
|
|
8
10
|
def self.load(json)
|
9
|
-
ActiveSupport::JSON.decode(json) unless json.
|
11
|
+
ActiveSupport::JSON.decode(json) unless json.blank?
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
@@ -1,38 +1,50 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "yaml"
|
2
4
|
|
3
5
|
module ActiveRecord
|
4
6
|
module Coders # :nodoc:
|
5
7
|
class YAMLColumn # :nodoc:
|
6
|
-
|
7
8
|
attr_accessor :object_class
|
8
9
|
|
9
|
-
def initialize(object_class = Object)
|
10
|
+
def initialize(attr_name, object_class = Object)
|
11
|
+
@attr_name = attr_name
|
10
12
|
@object_class = object_class
|
13
|
+
check_arity_of_constructor
|
11
14
|
end
|
12
15
|
|
13
16
|
def dump(obj)
|
14
17
|
return if obj.nil?
|
15
18
|
|
16
|
-
|
17
|
-
raise SerializationTypeMismatch,
|
18
|
-
"Attribute was supposed to be a #{object_class}, but was a #{obj.class}. -- #{obj.inspect}"
|
19
|
-
end
|
19
|
+
assert_valid_value(obj, action: "dump")
|
20
20
|
YAML.dump obj
|
21
21
|
end
|
22
22
|
|
23
23
|
def load(yaml)
|
24
24
|
return object_class.new if object_class != Object && yaml.nil?
|
25
|
-
return yaml unless yaml.is_a?(String) && yaml
|
25
|
+
return yaml unless yaml.is_a?(String) && /^---/.match?(yaml)
|
26
26
|
obj = YAML.load(yaml)
|
27
27
|
|
28
|
-
|
29
|
-
raise SerializationTypeMismatch,
|
30
|
-
"Attribute was supposed to be a #{object_class}, but was a #{obj.class}"
|
31
|
-
end
|
28
|
+
assert_valid_value(obj, action: "load")
|
32
29
|
obj ||= object_class.new if object_class != Object
|
33
30
|
|
34
31
|
obj
|
35
32
|
end
|
33
|
+
|
34
|
+
def assert_valid_value(obj, action:)
|
35
|
+
unless obj.nil? || obj.is_a?(object_class)
|
36
|
+
raise SerializationTypeMismatch,
|
37
|
+
"can't #{action} `#{@attr_name}`: was supposed to be a #{object_class}, but was a #{obj.class}. -- #{obj.inspect}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def check_arity_of_constructor
|
44
|
+
load(nil)
|
45
|
+
rescue ArgumentError
|
46
|
+
raise ArgumentError, "Cannot serialize #{object_class}. Classes passed to `serialize` must have a 0 argument constructor."
|
47
|
+
end
|
36
48
|
end
|
37
49
|
end
|
38
50
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module CollectionCacheKey
|
5
|
+
def collection_cache_key(collection = all, timestamp_column = :updated_at) # :nodoc:
|
6
|
+
query_signature = ActiveSupport::Digest.hexdigest(collection.to_sql)
|
7
|
+
key = "#{collection.model_name.cache_key}/query-#{query_signature}"
|
8
|
+
|
9
|
+
if collection.loaded? || collection.distinct_value
|
10
|
+
size = collection.records.size
|
11
|
+
if size > 0
|
12
|
+
timestamp = collection.max_by(×tamp_column)._read_attribute(timestamp_column)
|
13
|
+
end
|
14
|
+
else
|
15
|
+
if collection.eager_loading?
|
16
|
+
collection = collection.send(:apply_join_dependency)
|
17
|
+
end
|
18
|
+
column_type = type_for_attribute(timestamp_column)
|
19
|
+
column = connection.column_name_from_arel_node(collection.arel_attribute(timestamp_column))
|
20
|
+
select_values = "COUNT(*) AS #{connection.quote_column_name("size")}, MAX(%s) AS timestamp"
|
21
|
+
|
22
|
+
if collection.has_limit_or_offset?
|
23
|
+
query = collection.select("#{column} AS collection_cache_key_timestamp")
|
24
|
+
subquery_alias = "subquery_for_cache_key"
|
25
|
+
subquery_column = "#{subquery_alias}.collection_cache_key_timestamp"
|
26
|
+
subquery = query.arel.as(subquery_alias)
|
27
|
+
arel = Arel::SelectManager.new(subquery).project(select_values % subquery_column)
|
28
|
+
else
|
29
|
+
query = collection.unscope(:order)
|
30
|
+
query.select_values = [select_values % column]
|
31
|
+
arel = query.arel
|
32
|
+
end
|
33
|
+
|
34
|
+
result = connection.select_one(arel, nil)
|
35
|
+
|
36
|
+
if result.blank?
|
37
|
+
size = 0
|
38
|
+
timestamp = nil
|
39
|
+
else
|
40
|
+
size = result["size"]
|
41
|
+
timestamp = column_type.deserialize(result["timestamp"])
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
if timestamp
|
47
|
+
"#{key}-#{size}-#{timestamp.utc.to_s(cache_timestamp_format)}"
|
48
|
+
else
|
49
|
+
"#{key}-#{size}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|