activerecord 5.2.8 → 7.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +1393 -587
 - data/MIT-LICENSE +3 -1
 - data/README.rdoc +7 -5
 - data/examples/performance.rb +1 -1
 - data/lib/active_record/aggregations.rb +10 -9
 - data/lib/active_record/association_relation.rb +22 -12
 - data/lib/active_record/associations/alias_tracker.rb +19 -16
 - data/lib/active_record/associations/association.rb +122 -47
 - data/lib/active_record/associations/association_scope.rb +24 -24
 - data/lib/active_record/associations/belongs_to_association.rb +67 -49
 - data/lib/active_record/associations/belongs_to_polymorphic_association.rb +16 -7
 - data/lib/active_record/associations/builder/association.rb +52 -23
 - data/lib/active_record/associations/builder/belongs_to.rb +44 -61
 - data/lib/active_record/associations/builder/collection_association.rb +17 -19
 - data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -41
 - data/lib/active_record/associations/builder/has_many.rb +10 -3
 - data/lib/active_record/associations/builder/has_one.rb +35 -3
 - data/lib/active_record/associations/builder/singular_association.rb +5 -3
 - data/lib/active_record/associations/collection_association.rb +59 -50
 - data/lib/active_record/associations/collection_proxy.rb +32 -23
 - data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
 - data/lib/active_record/associations/foreign_association.rb +20 -0
 - data/lib/active_record/associations/has_many_association.rb +27 -14
 - data/lib/active_record/associations/has_many_through_association.rb +26 -19
 - data/lib/active_record/associations/has_one_association.rb +52 -37
 - data/lib/active_record/associations/has_one_through_association.rb +6 -6
 - data/lib/active_record/associations/join_dependency/join_association.rb +44 -22
 - data/lib/active_record/associations/join_dependency/join_part.rb +5 -5
 - data/lib/active_record/associations/join_dependency.rb +97 -62
 - data/lib/active_record/associations/preloader/association.rb +220 -60
 - data/lib/active_record/associations/preloader/batch.rb +48 -0
 - data/lib/active_record/associations/preloader/branch.rb +147 -0
 - data/lib/active_record/associations/preloader/through_association.rb +85 -40
 - data/lib/active_record/associations/preloader.rb +44 -105
 - data/lib/active_record/associations/singular_association.rb +9 -17
 - data/lib/active_record/associations/through_association.rb +4 -4
 - data/lib/active_record/associations.rb +207 -66
 - data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
 - data/lib/active_record/attribute_assignment.rb +17 -19
 - data/lib/active_record/attribute_methods/before_type_cast.rb +19 -8
 - data/lib/active_record/attribute_methods/dirty.rb +141 -47
 - data/lib/active_record/attribute_methods/primary_key.rb +22 -27
 - data/lib/active_record/attribute_methods/query.rb +6 -10
 - data/lib/active_record/attribute_methods/read.rb +15 -55
 - data/lib/active_record/attribute_methods/serialization.rb +77 -18
 - data/lib/active_record/attribute_methods/time_zone_conversion.rb +16 -18
 - data/lib/active_record/attribute_methods/write.rb +18 -37
 - data/lib/active_record/attribute_methods.rb +90 -153
 - data/lib/active_record/attributes.rb +38 -12
 - data/lib/active_record/autosave_association.rb +50 -50
 - data/lib/active_record/base.rb +23 -18
 - data/lib/active_record/callbacks.rb +159 -44
 - data/lib/active_record/coders/yaml_column.rb +12 -3
 - data/lib/active_record/connection_adapters/abstract/connection_handler.rb +292 -0
 - data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
 - data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
 - data/lib/active_record/connection_adapters/abstract/connection_pool.rb +92 -464
 - data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -51
 - data/lib/active_record/connection_adapters/abstract/database_statements.rb +209 -164
 - data/lib/active_record/connection_adapters/abstract/query_cache.rb +38 -22
 - data/lib/active_record/connection_adapters/abstract/quoting.rb +103 -82
 - data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
 - data/lib/active_record/connection_adapters/abstract/schema_creation.rb +140 -110
 - data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +236 -94
 - data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +16 -5
 - data/lib/active_record/connection_adapters/abstract/schema_statements.rb +456 -159
 - data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -78
 - data/lib/active_record/connection_adapters/abstract_adapter.rb +367 -162
 - data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +311 -327
 - data/lib/active_record/connection_adapters/column.rb +33 -11
 - data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
 - data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
 - data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
 - data/lib/active_record/connection_adapters/mysql/database_statements.rb +113 -45
 - data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
 - data/lib/active_record/connection_adapters/mysql/quoting.rb +71 -5
 - data/lib/active_record/connection_adapters/mysql/schema_creation.rb +34 -10
 - data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +48 -32
 - data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +25 -8
 - data/lib/active_record/connection_adapters/mysql/schema_statements.rb +143 -19
 - data/lib/active_record/connection_adapters/mysql/type_metadata.rb +14 -9
 - data/lib/active_record/connection_adapters/mysql2_adapter.rb +63 -22
 - data/lib/active_record/connection_adapters/pool_config.rb +73 -0
 - data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
 - data/lib/active_record/connection_adapters/postgresql/column.rb +53 -28
 - data/lib/active_record/connection_adapters/postgresql/database_statements.rb +56 -63
 - data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
 - data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
 - data/lib/active_record/connection_adapters/postgresql/oid/date.rb +10 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +15 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +54 -16
 - data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +3 -4
 - data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/point.rb +3 -4
 - data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
 - data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +26 -12
 - data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
 - data/lib/active_record/connection_adapters/postgresql/oid.rb +4 -0
 - data/lib/active_record/connection_adapters/postgresql/quoting.rb +89 -52
 - data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +34 -2
 - data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +39 -4
 - data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +128 -91
 - data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -1
 - data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +149 -113
 - data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
 - data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
 - data/lib/active_record/connection_adapters/postgresql_adapter.rb +386 -182
 - data/lib/active_record/connection_adapters/schema_cache.rb +161 -22
 - data/lib/active_record/connection_adapters/sql_type_metadata.rb +17 -6
 - data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +152 -0
 - data/lib/active_record/connection_adapters/sqlite3/quoting.rb +65 -18
 - data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
 - data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +92 -26
 - data/lib/active_record/connection_adapters/sqlite3_adapter.rb +251 -204
 - data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
 - data/lib/active_record/connection_adapters.rb +53 -0
 - data/lib/active_record/connection_handling.rb +292 -38
 - data/lib/active_record/core.rb +385 -158
 - data/lib/active_record/counter_cache.rb +8 -30
 - data/lib/active_record/database_configurations/connection_url_resolver.rb +100 -0
 - data/lib/active_record/database_configurations/database_config.rb +83 -0
 - data/lib/active_record/database_configurations/hash_config.rb +154 -0
 - data/lib/active_record/database_configurations/url_config.rb +53 -0
 - data/lib/active_record/database_configurations.rb +256 -0
 - data/lib/active_record/delegated_type.rb +250 -0
 - data/lib/active_record/destroy_association_async_job.rb +36 -0
 - data/lib/active_record/disable_joins_association_relation.rb +39 -0
 - data/lib/active_record/dynamic_matchers.rb +4 -5
 - data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
 - data/lib/active_record/encryption/cipher.rb +53 -0
 - data/lib/active_record/encryption/config.rb +44 -0
 - data/lib/active_record/encryption/configurable.rb +61 -0
 - data/lib/active_record/encryption/context.rb +35 -0
 - data/lib/active_record/encryption/contexts.rb +72 -0
 - data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
 - data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
 - data/lib/active_record/encryption/encryptable_record.rb +208 -0
 - data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -0
 - data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
 - data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
 - data/lib/active_record/encryption/encryptor.rb +155 -0
 - data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
 - data/lib/active_record/encryption/errors.rb +15 -0
 - data/lib/active_record/encryption/extended_deterministic_queries.rb +160 -0
 - data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
 - data/lib/active_record/encryption/key.rb +28 -0
 - data/lib/active_record/encryption/key_generator.rb +42 -0
 - data/lib/active_record/encryption/key_provider.rb +46 -0
 - data/lib/active_record/encryption/message.rb +33 -0
 - data/lib/active_record/encryption/message_serializer.rb +90 -0
 - data/lib/active_record/encryption/null_encryptor.rb +21 -0
 - data/lib/active_record/encryption/properties.rb +76 -0
 - data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
 - data/lib/active_record/encryption/scheme.rb +99 -0
 - data/lib/active_record/encryption.rb +55 -0
 - data/lib/active_record/enum.rb +130 -51
 - data/lib/active_record/errors.rb +129 -23
 - data/lib/active_record/explain.rb +10 -6
 - data/lib/active_record/explain_registry.rb +11 -6
 - data/lib/active_record/explain_subscriber.rb +1 -1
 - data/lib/active_record/fixture_set/file.rb +22 -15
 - data/lib/active_record/fixture_set/model_metadata.rb +32 -0
 - data/lib/active_record/fixture_set/render_context.rb +17 -0
 - data/lib/active_record/fixture_set/table_row.rb +187 -0
 - data/lib/active_record/fixture_set/table_rows.rb +46 -0
 - data/lib/active_record/fixtures.rb +206 -490
 - data/lib/active_record/future_result.rb +139 -0
 - data/lib/active_record/gem_version.rb +3 -3
 - data/lib/active_record/inheritance.rb +104 -37
 - data/lib/active_record/insert_all.rb +278 -0
 - data/lib/active_record/integration.rb +69 -18
 - data/lib/active_record/internal_metadata.rb +24 -9
 - data/lib/active_record/legacy_yaml_adapter.rb +3 -36
 - data/lib/active_record/locking/optimistic.rb +41 -26
 - data/lib/active_record/locking/pessimistic.rb +18 -8
 - data/lib/active_record/log_subscriber.rb +46 -35
 - data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
 - data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
 - data/lib/active_record/middleware/database_selector.rb +82 -0
 - data/lib/active_record/middleware/shard_selector.rb +60 -0
 - data/lib/active_record/migration/command_recorder.rb +96 -44
 - data/lib/active_record/migration/compatibility.rb +246 -64
 - data/lib/active_record/migration/join_table.rb +1 -2
 - data/lib/active_record/migration.rb +266 -187
 - data/lib/active_record/model_schema.rb +165 -52
 - data/lib/active_record/nested_attributes.rb +17 -19
 - data/lib/active_record/no_touching.rb +11 -4
 - data/lib/active_record/null_relation.rb +2 -7
 - data/lib/active_record/persistence.rb +467 -92
 - data/lib/active_record/query_cache.rb +21 -4
 - data/lib/active_record/query_logs.rb +138 -0
 - data/lib/active_record/querying.rb +51 -24
 - data/lib/active_record/railtie.rb +224 -57
 - data/lib/active_record/railties/console_sandbox.rb +2 -4
 - data/lib/active_record/railties/controller_runtime.rb +31 -36
 - data/lib/active_record/railties/databases.rake +369 -101
 - data/lib/active_record/readonly_attributes.rb +15 -0
 - data/lib/active_record/reflection.rb +170 -137
 - data/lib/active_record/relation/batches/batch_enumerator.rb +44 -14
 - data/lib/active_record/relation/batches.rb +46 -37
 - data/lib/active_record/relation/calculations.rb +168 -96
 - data/lib/active_record/relation/delegation.rb +37 -52
 - data/lib/active_record/relation/finder_methods.rb +79 -58
 - data/lib/active_record/relation/from_clause.rb +5 -1
 - data/lib/active_record/relation/merger.rb +50 -51
 - data/lib/active_record/relation/predicate_builder/array_handler.rb +13 -13
 - data/lib/active_record/relation/predicate_builder/association_query_value.rb +5 -9
 - data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
 - data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +11 -10
 - data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
 - data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
 - data/lib/active_record/relation/predicate_builder.rb +58 -46
 - data/lib/active_record/relation/query_attribute.rb +9 -10
 - data/lib/active_record/relation/query_methods.rb +685 -208
 - data/lib/active_record/relation/record_fetch_warning.rb +9 -11
 - data/lib/active_record/relation/spawn_methods.rb +10 -10
 - data/lib/active_record/relation/where_clause.rb +108 -64
 - data/lib/active_record/relation.rb +515 -151
 - data/lib/active_record/result.rb +78 -42
 - data/lib/active_record/runtime_registry.rb +9 -13
 - data/lib/active_record/sanitization.rb +29 -44
 - data/lib/active_record/schema.rb +37 -31
 - data/lib/active_record/schema_dumper.rb +74 -23
 - data/lib/active_record/schema_migration.rb +7 -9
 - data/lib/active_record/scoping/default.rb +62 -17
 - data/lib/active_record/scoping/named.rb +17 -32
 - data/lib/active_record/scoping.rb +70 -41
 - data/lib/active_record/secure_token.rb +16 -8
 - data/lib/active_record/serialization.rb +6 -4
 - data/lib/active_record/signed_id.rb +116 -0
 - data/lib/active_record/statement_cache.rb +49 -6
 - data/lib/active_record/store.rb +88 -9
 - data/lib/active_record/suppressor.rb +13 -17
 - data/lib/active_record/table_metadata.rb +42 -43
 - data/lib/active_record/tasks/database_tasks.rb +352 -94
 - data/lib/active_record/tasks/mysql_database_tasks.rb +37 -39
 - data/lib/active_record/tasks/postgresql_database_tasks.rb +41 -39
 - data/lib/active_record/tasks/sqlite_database_tasks.rb +14 -17
 - data/lib/active_record/test_databases.rb +24 -0
 - data/lib/active_record/test_fixtures.rb +287 -0
 - data/lib/active_record/timestamp.rb +44 -34
 - data/lib/active_record/touch_later.rb +23 -22
 - data/lib/active_record/transactions.rb +67 -128
 - data/lib/active_record/translation.rb +3 -3
 - data/lib/active_record/type/adapter_specific_registry.rb +34 -19
 - data/lib/active_record/type/hash_lookup_type_map.rb +34 -2
 - data/lib/active_record/type/internal/timezone.rb +2 -2
 - data/lib/active_record/type/serialized.rb +7 -4
 - data/lib/active_record/type/time.rb +10 -0
 - data/lib/active_record/type/type_map.rb +17 -21
 - data/lib/active_record/type/unsigned_integer.rb +0 -1
 - data/lib/active_record/type.rb +9 -5
 - data/lib/active_record/type_caster/connection.rb +15 -15
 - data/lib/active_record/type_caster/map.rb +8 -8
 - data/lib/active_record/validations/associated.rb +2 -3
 - data/lib/active_record/validations/numericality.rb +35 -0
 - data/lib/active_record/validations/uniqueness.rb +39 -31
 - data/lib/active_record/validations.rb +4 -3
 - data/lib/active_record.rb +209 -32
 - data/lib/arel/alias_predication.rb +9 -0
 - data/lib/arel/attributes/attribute.rb +33 -0
 - data/lib/arel/collectors/bind.rb +29 -0
 - data/lib/arel/collectors/composite.rb +39 -0
 - data/lib/arel/collectors/plain_string.rb +20 -0
 - data/lib/arel/collectors/sql_string.rb +27 -0
 - data/lib/arel/collectors/substitute_binds.rb +35 -0
 - data/lib/arel/crud.rb +48 -0
 - data/lib/arel/delete_manager.rb +32 -0
 - data/lib/arel/errors.rb +9 -0
 - data/lib/arel/expressions.rb +29 -0
 - data/lib/arel/factory_methods.rb +49 -0
 - data/lib/arel/filter_predications.rb +9 -0
 - data/lib/arel/insert_manager.rb +48 -0
 - data/lib/arel/math.rb +45 -0
 - data/lib/arel/nodes/and.rb +32 -0
 - data/lib/arel/nodes/ascending.rb +23 -0
 - data/lib/arel/nodes/binary.rb +126 -0
 - data/lib/arel/nodes/bind_param.rb +44 -0
 - data/lib/arel/nodes/case.rb +55 -0
 - data/lib/arel/nodes/casted.rb +62 -0
 - data/lib/arel/nodes/comment.rb +29 -0
 - data/lib/arel/nodes/count.rb +12 -0
 - data/lib/arel/nodes/delete_statement.rb +44 -0
 - data/lib/arel/nodes/descending.rb +23 -0
 - data/lib/arel/nodes/equality.rb +15 -0
 - data/lib/arel/nodes/extract.rb +24 -0
 - data/lib/arel/nodes/false.rb +16 -0
 - data/lib/arel/nodes/filter.rb +10 -0
 - data/lib/arel/nodes/full_outer_join.rb +8 -0
 - data/lib/arel/nodes/function.rb +45 -0
 - data/lib/arel/nodes/grouping.rb +11 -0
 - data/lib/arel/nodes/homogeneous_in.rb +76 -0
 - data/lib/arel/nodes/in.rb +15 -0
 - data/lib/arel/nodes/infix_operation.rb +92 -0
 - data/lib/arel/nodes/inner_join.rb +8 -0
 - data/lib/arel/nodes/insert_statement.rb +37 -0
 - data/lib/arel/nodes/join_source.rb +20 -0
 - data/lib/arel/nodes/matches.rb +18 -0
 - data/lib/arel/nodes/named_function.rb +23 -0
 - data/lib/arel/nodes/node.rb +51 -0
 - data/lib/arel/nodes/node_expression.rb +13 -0
 - data/lib/arel/nodes/ordering.rb +27 -0
 - data/lib/arel/nodes/outer_join.rb +8 -0
 - data/lib/arel/nodes/over.rb +15 -0
 - data/lib/arel/nodes/regexp.rb +16 -0
 - data/lib/arel/nodes/right_outer_join.rb +8 -0
 - data/lib/arel/nodes/select_core.rb +67 -0
 - data/lib/arel/nodes/select_statement.rb +41 -0
 - data/lib/arel/nodes/sql_literal.rb +19 -0
 - data/lib/arel/nodes/string_join.rb +11 -0
 - data/lib/arel/nodes/table_alias.rb +31 -0
 - data/lib/arel/nodes/terminal.rb +16 -0
 - data/lib/arel/nodes/true.rb +16 -0
 - data/lib/arel/nodes/unary.rb +44 -0
 - data/lib/arel/nodes/unary_operation.rb +20 -0
 - data/lib/arel/nodes/unqualified_column.rb +22 -0
 - data/lib/arel/nodes/update_statement.rb +46 -0
 - data/lib/arel/nodes/values_list.rb +9 -0
 - data/lib/arel/nodes/window.rb +126 -0
 - data/lib/arel/nodes/with.rb +11 -0
 - data/lib/arel/nodes.rb +71 -0
 - data/lib/arel/order_predications.rb +13 -0
 - data/lib/arel/predications.rb +258 -0
 - data/lib/arel/select_manager.rb +276 -0
 - data/lib/arel/table.rb +117 -0
 - data/lib/arel/tree_manager.rb +60 -0
 - data/lib/arel/update_manager.rb +48 -0
 - data/lib/arel/visitors/dot.rb +298 -0
 - data/lib/arel/visitors/mysql.rb +99 -0
 - data/lib/arel/visitors/postgresql.rb +110 -0
 - data/lib/arel/visitors/sqlite.rb +38 -0
 - data/lib/arel/visitors/to_sql.rb +955 -0
 - data/lib/arel/visitors/visitor.rb +45 -0
 - data/lib/arel/visitors.rb +13 -0
 - data/lib/arel/window_predications.rb +9 -0
 - data/lib/arel.rb +55 -0
 - data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
 - data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
 - data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -5
 - data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +3 -1
 - data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +7 -5
 - data/lib/rails/generators/active_record/migration.rb +19 -2
 - data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
 - data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
 - data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
 - data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
 - data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
 - data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
 - metadata +162 -32
 - data/lib/active_record/attribute_decorators.rb +0 -90
 - data/lib/active_record/collection_cache_key.rb +0 -53
 - data/lib/active_record/connection_adapters/connection_specification.rb +0 -287
 - data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -33
 - data/lib/active_record/define_callbacks.rb +0 -22
 - data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -19
 - data/lib/active_record/relation/where_clause_factory.rb +0 -34
 
| 
         @@ -1,6 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            require "mutex_m"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "active_support/core_ext/enumerable"
         
     | 
| 
       4 
5 
     | 
    
         | 
| 
       5 
6 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       6 
7 
     | 
    
         
             
              # = Active Record Attribute Methods
         
     | 
| 
         @@ -18,33 +19,34 @@ module ActiveRecord 
     | 
|
| 
       18 
19 
     | 
    
         
             
                  include TimeZoneConversion
         
     | 
| 
       19 
20 
     | 
    
         
             
                  include Dirty
         
     | 
| 
       20 
21 
     | 
    
         
             
                  include Serialization
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                  delegate :column_for_attribute, to: :class
         
     | 
| 
       23 
22 
     | 
    
         
             
                end
         
     | 
| 
       24 
23 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
                 
     | 
| 
       26 
     | 
    
         
            -
                  def self.set_name_cache(name, value)
         
     | 
| 
       27 
     | 
    
         
            -
                    const_name = "ATTR_#{name}"
         
     | 
| 
       28 
     | 
    
         
            -
                    unless const_defined? const_name
         
     | 
| 
       29 
     | 
    
         
            -
                      const_set const_name, value.dup.freeze
         
     | 
| 
       30 
     | 
    
         
            -
                    end
         
     | 
| 
       31 
     | 
    
         
            -
                  end
         
     | 
| 
       32 
     | 
    
         
            -
                }
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
                BLACKLISTED_CLASS_METHODS = %w(private public protected allocate new name parent superclass)
         
     | 
| 
      
 24 
     | 
    
         
            +
                RESTRICTED_CLASS_METHODS = %w(private public protected allocate new name parent superclass)
         
     | 
| 
       35 
25 
     | 
    
         | 
| 
       36 
     | 
    
         
            -
                class GeneratedAttributeMethods < Module  
     | 
| 
      
 26 
     | 
    
         
            +
                class GeneratedAttributeMethods < Module # :nodoc:
         
     | 
| 
       37 
27 
     | 
    
         
             
                  include Mutex_m
         
     | 
| 
       38 
28 
     | 
    
         
             
                end
         
     | 
| 
       39 
29 
     | 
    
         | 
| 
      
 30 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 31 
     | 
    
         
            +
                  def dangerous_attribute_methods # :nodoc:
         
     | 
| 
      
 32 
     | 
    
         
            +
                    @dangerous_attribute_methods ||= (
         
     | 
| 
      
 33 
     | 
    
         
            +
                      Base.instance_methods +
         
     | 
| 
      
 34 
     | 
    
         
            +
                      Base.private_instance_methods -
         
     | 
| 
      
 35 
     | 
    
         
            +
                      Base.superclass.instance_methods -
         
     | 
| 
      
 36 
     | 
    
         
            +
                      Base.superclass.private_instance_methods
         
     | 
| 
      
 37 
     | 
    
         
            +
                    ).map { |m| -m.to_s }.to_set.freeze
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
       40 
41 
     | 
    
         
             
                module ClassMethods
         
     | 
| 
       41 
     | 
    
         
            -
                  def inherited(child_class)  
     | 
| 
      
 42 
     | 
    
         
            +
                  def inherited(child_class) # :nodoc:
         
     | 
| 
       42 
43 
     | 
    
         
             
                    child_class.initialize_generated_modules
         
     | 
| 
       43 
44 
     | 
    
         
             
                    super
         
     | 
| 
       44 
45 
     | 
    
         
             
                  end
         
     | 
| 
       45 
46 
     | 
    
         | 
| 
       46 
47 
     | 
    
         
             
                  def initialize_generated_modules # :nodoc:
         
     | 
| 
       47 
     | 
    
         
            -
                    @generated_attribute_methods = GeneratedAttributeMethods.new
         
     | 
| 
      
 48 
     | 
    
         
            +
                    @generated_attribute_methods = const_set(:GeneratedAttributeMethods, GeneratedAttributeMethods.new)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    private_constant :GeneratedAttributeMethods
         
     | 
| 
       48 
50 
     | 
    
         
             
                    @attribute_methods_generated = false
         
     | 
| 
       49 
51 
     | 
    
         
             
                    include @generated_attribute_methods
         
     | 
| 
       50 
52 
     | 
    
         | 
| 
         @@ -59,7 +61,7 @@ module ActiveRecord 
     | 
|
| 
       59 
61 
     | 
    
         
             
                    # attribute methods.
         
     | 
| 
       60 
62 
     | 
    
         
             
                    generated_attribute_methods.synchronize do
         
     | 
| 
       61 
63 
     | 
    
         
             
                      return false if @attribute_methods_generated
         
     | 
| 
       62 
     | 
    
         
            -
                      superclass.define_attribute_methods unless  
     | 
| 
      
 64 
     | 
    
         
            +
                      superclass.define_attribute_methods unless base_class?
         
     | 
| 
       63 
65 
     | 
    
         
             
                      super(attribute_names)
         
     | 
| 
       64 
66 
     | 
    
         
             
                      @attribute_methods_generated = true
         
     | 
| 
       65 
67 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -105,7 +107,7 @@ module ActiveRecord 
     | 
|
| 
       105 
107 
     | 
    
         
             
                  # A method name is 'dangerous' if it is already (re)defined by Active Record, but
         
     | 
| 
       106 
108 
     | 
    
         
             
                  # not by any ancestors. (So 'puts' is not dangerous but 'save' is.)
         
     | 
| 
       107 
109 
     | 
    
         
             
                  def dangerous_attribute_method?(name) # :nodoc:
         
     | 
| 
       108 
     | 
    
         
            -
                     
     | 
| 
      
 110 
     | 
    
         
            +
                    ::ActiveRecord::AttributeMethods.dangerous_attribute_methods.include?(name.to_s)
         
     | 
| 
       109 
111 
     | 
    
         
             
                  end
         
     | 
| 
       110 
112 
     | 
    
         | 
| 
       111 
113 
     | 
    
         
             
                  def method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc:
         
     | 
| 
         @@ -123,13 +125,11 @@ module ActiveRecord 
     | 
|
| 
       123 
125 
     | 
    
         
             
                  # A class method is 'dangerous' if it is already (re)defined by Active Record, but
         
     | 
| 
       124 
126 
     | 
    
         
             
                  # not by any ancestors. (So 'puts' is not dangerous but 'new' is.)
         
     | 
| 
       125 
127 
     | 
    
         
             
                  def dangerous_class_method?(method_name)
         
     | 
| 
       126 
     | 
    
         
            -
                     
     | 
| 
       127 
     | 
    
         
            -
                  end
         
     | 
| 
      
 128 
     | 
    
         
            +
                    return true if RESTRICTED_CLASS_METHODS.include?(method_name.to_s)
         
     | 
| 
       128 
129 
     | 
    
         | 
| 
       129 
     | 
    
         
            -
             
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
                        klass.method(name).owner != superklass.method(name).owner
         
     | 
| 
      
 130 
     | 
    
         
            +
                    if Base.respond_to?(method_name, true)
         
     | 
| 
      
 131 
     | 
    
         
            +
                      if Object.respond_to?(method_name, true)
         
     | 
| 
      
 132 
     | 
    
         
            +
                        Base.method(method_name).owner != Object.method(method_name).owner
         
     | 
| 
       133 
133 
     | 
    
         
             
                      else
         
     | 
| 
       134 
134 
     | 
    
         
             
                        true
         
     | 
| 
       135 
135 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -148,7 +148,7 @@ module ActiveRecord 
     | 
|
| 
       148 
148 
     | 
    
         
             
                  #   Person.attribute_method?(:age=)    # => true
         
     | 
| 
       149 
149 
     | 
    
         
             
                  #   Person.attribute_method?(:nothing) # => false
         
     | 
| 
       150 
150 
     | 
    
         
             
                  def attribute_method?(attribute)
         
     | 
| 
       151 
     | 
    
         
            -
                    super || (table_exists? && column_names.include?(attribute.to_s. 
     | 
| 
      
 151 
     | 
    
         
            +
                    super || (table_exists? && column_names.include?(attribute.to_s.delete_suffix("=")))
         
     | 
| 
       152 
152 
     | 
    
         
             
                  end
         
     | 
| 
       153 
153 
     | 
    
         | 
| 
       154 
154 
     | 
    
         
             
                  # Returns an array of column names as strings if it's not an abstract class and
         
     | 
| 
         @@ -164,90 +164,27 @@ module ActiveRecord 
     | 
|
| 
       164 
164 
     | 
    
         
             
                      attribute_types.keys
         
     | 
| 
       165 
165 
     | 
    
         
             
                    else
         
     | 
| 
       166 
166 
     | 
    
         
             
                      []
         
     | 
| 
       167 
     | 
    
         
            -
                    end
         
     | 
| 
       168 
     | 
    
         
            -
                  end
         
     | 
| 
       169 
     | 
    
         
            -
             
     | 
| 
       170 
     | 
    
         
            -
                  # Regexp whitelist. Matches the following:
         
     | 
| 
       171 
     | 
    
         
            -
                  #   "#{table_name}.#{column_name}"
         
     | 
| 
       172 
     | 
    
         
            -
                  #   "#{column_name}"
         
     | 
| 
       173 
     | 
    
         
            -
                  COLUMN_NAME_WHITELIST = /\A(?:\w+\.)?\w+\z/i
         
     | 
| 
       174 
     | 
    
         
            -
             
     | 
| 
       175 
     | 
    
         
            -
                  # Regexp whitelist. Matches the following:
         
     | 
| 
       176 
     | 
    
         
            -
                  #   "#{table_name}.#{column_name}"
         
     | 
| 
       177 
     | 
    
         
            -
                  #   "#{table_name}.#{column_name} #{direction}"
         
     | 
| 
       178 
     | 
    
         
            -
                  #   "#{table_name}.#{column_name} #{direction} NULLS FIRST"
         
     | 
| 
       179 
     | 
    
         
            -
                  #   "#{table_name}.#{column_name} NULLS LAST"
         
     | 
| 
       180 
     | 
    
         
            -
                  #   "#{column_name}"
         
     | 
| 
       181 
     | 
    
         
            -
                  #   "#{column_name} #{direction}"
         
     | 
| 
       182 
     | 
    
         
            -
                  #   "#{column_name} #{direction} NULLS FIRST"
         
     | 
| 
       183 
     | 
    
         
            -
                  #   "#{column_name} NULLS LAST"
         
     | 
| 
       184 
     | 
    
         
            -
                  COLUMN_NAME_ORDER_WHITELIST = /
         
     | 
| 
       185 
     | 
    
         
            -
                    \A
         
     | 
| 
       186 
     | 
    
         
            -
                    (?:\w+\.)?
         
     | 
| 
       187 
     | 
    
         
            -
                    \w+
         
     | 
| 
       188 
     | 
    
         
            -
                    (?:\s+asc|\s+desc)?
         
     | 
| 
       189 
     | 
    
         
            -
                    (?:\s+nulls\s+(?:first|last))?
         
     | 
| 
       190 
     | 
    
         
            -
                    \z
         
     | 
| 
       191 
     | 
    
         
            -
                  /ix
         
     | 
| 
       192 
     | 
    
         
            -
             
     | 
| 
       193 
     | 
    
         
            -
                  def enforce_raw_sql_whitelist(args, whitelist: COLUMN_NAME_WHITELIST) # :nodoc:
         
     | 
| 
       194 
     | 
    
         
            -
                    unexpected = args.reject do |arg|
         
     | 
| 
       195 
     | 
    
         
            -
                      arg.kind_of?(Arel::Node) ||
         
     | 
| 
       196 
     | 
    
         
            -
                        arg.is_a?(Arel::Nodes::SqlLiteral) ||
         
     | 
| 
       197 
     | 
    
         
            -
                        arg.is_a?(Arel::Attributes::Attribute) ||
         
     | 
| 
       198 
     | 
    
         
            -
                        arg.to_s.split(/\s*,\s*/).all? { |part| whitelist.match?(part) }
         
     | 
| 
       199 
     | 
    
         
            -
                    end
         
     | 
| 
       200 
     | 
    
         
            -
             
     | 
| 
       201 
     | 
    
         
            -
                    return if unexpected.none?
         
     | 
| 
       202 
     | 
    
         
            -
             
     | 
| 
       203 
     | 
    
         
            -
                    if allow_unsafe_raw_sql == :deprecated
         
     | 
| 
       204 
     | 
    
         
            -
                      ActiveSupport::Deprecation.warn(
         
     | 
| 
       205 
     | 
    
         
            -
                        "Dangerous query method (method whose arguments are used as raw " \
         
     | 
| 
       206 
     | 
    
         
            -
                        "SQL) called with non-attribute argument(s): " \
         
     | 
| 
       207 
     | 
    
         
            -
                        "#{unexpected.map(&:inspect).join(", ")}. Non-attribute " \
         
     | 
| 
       208 
     | 
    
         
            -
                        "arguments will be disallowed in Rails 6.0. This method should " \
         
     | 
| 
       209 
     | 
    
         
            -
                        "not be called with user-provided values, such as request " \
         
     | 
| 
       210 
     | 
    
         
            -
                        "parameters or model attributes. Known-safe values can be passed " \
         
     | 
| 
       211 
     | 
    
         
            -
                        "by wrapping them in Arel.sql()."
         
     | 
| 
       212 
     | 
    
         
            -
                      )
         
     | 
| 
       213 
     | 
    
         
            -
                    else
         
     | 
| 
       214 
     | 
    
         
            -
                      raise(ActiveRecord::UnknownAttributeReference,
         
     | 
| 
       215 
     | 
    
         
            -
                        "Query method called with non-attribute argument(s): " +
         
     | 
| 
       216 
     | 
    
         
            -
                        unexpected.map(&:inspect).join(", ")
         
     | 
| 
       217 
     | 
    
         
            -
                      )
         
     | 
| 
       218 
     | 
    
         
            -
                    end
         
     | 
| 
      
 167 
     | 
    
         
            +
                    end.freeze
         
     | 
| 
       219 
168 
     | 
    
         
             
                  end
         
     | 
| 
       220 
169 
     | 
    
         | 
| 
       221 
170 
     | 
    
         
             
                  # Returns true if the given attribute exists, otherwise false.
         
     | 
| 
       222 
171 
     | 
    
         
             
                  #
         
     | 
| 
       223 
172 
     | 
    
         
             
                  #   class Person < ActiveRecord::Base
         
     | 
| 
      
 173 
     | 
    
         
            +
                  #     alias_attribute :new_name, :name
         
     | 
| 
       224 
174 
     | 
    
         
             
                  #   end
         
     | 
| 
       225 
175 
     | 
    
         
             
                  #
         
     | 
| 
       226 
     | 
    
         
            -
                  #   Person.has_attribute?('name') 
     | 
| 
       227 
     | 
    
         
            -
                  #   Person.has_attribute?( 
     | 
| 
       228 
     | 
    
         
            -
                  #   Person.has_attribute?(: 
     | 
| 
      
 176 
     | 
    
         
            +
                  #   Person.has_attribute?('name')     # => true
         
     | 
| 
      
 177 
     | 
    
         
            +
                  #   Person.has_attribute?('new_name') # => true
         
     | 
| 
      
 178 
     | 
    
         
            +
                  #   Person.has_attribute?(:age)       # => true
         
     | 
| 
      
 179 
     | 
    
         
            +
                  #   Person.has_attribute?(:nothing)   # => false
         
     | 
| 
       229 
180 
     | 
    
         
             
                  def has_attribute?(attr_name)
         
     | 
| 
       230 
     | 
    
         
            -
                     
     | 
| 
      
 181 
     | 
    
         
            +
                    attr_name = attr_name.to_s
         
     | 
| 
      
 182 
     | 
    
         
            +
                    attr_name = attribute_aliases[attr_name] || attr_name
         
     | 
| 
      
 183 
     | 
    
         
            +
                    attribute_types.key?(attr_name)
         
     | 
| 
       231 
184 
     | 
    
         
             
                  end
         
     | 
| 
       232 
185 
     | 
    
         | 
| 
       233 
     | 
    
         
            -
                   
     | 
| 
       234 
     | 
    
         
            -
             
     | 
| 
       235 
     | 
    
         
            -
                  # named attribute does not exist.
         
     | 
| 
       236 
     | 
    
         
            -
                  #
         
     | 
| 
       237 
     | 
    
         
            -
                  #   class Person < ActiveRecord::Base
         
     | 
| 
       238 
     | 
    
         
            -
                  #   end
         
     | 
| 
       239 
     | 
    
         
            -
                  #
         
     | 
| 
       240 
     | 
    
         
            -
                  #   person = Person.new
         
     | 
| 
       241 
     | 
    
         
            -
                  #   person.column_for_attribute(:name) # the result depends on the ConnectionAdapter
         
     | 
| 
       242 
     | 
    
         
            -
                  #   # => #<ActiveRecord::ConnectionAdapters::Column:0x007ff4ab083980 @name="name", @sql_type="varchar(255)", @null=true, ...>
         
     | 
| 
       243 
     | 
    
         
            -
                  #
         
     | 
| 
       244 
     | 
    
         
            -
                  #   person.column_for_attribute(:nothing)
         
     | 
| 
       245 
     | 
    
         
            -
                  #   # => #<ActiveRecord::ConnectionAdapters::NullColumn:0xXXX @name=nil, @sql_type=nil, @cast_type=#<Type::Value>, ...>
         
     | 
| 
       246 
     | 
    
         
            -
                  def column_for_attribute(name)
         
     | 
| 
       247 
     | 
    
         
            -
                    name = name.to_s
         
     | 
| 
       248 
     | 
    
         
            -
                    columns_hash.fetch(name) do
         
     | 
| 
       249 
     | 
    
         
            -
                      ConnectionAdapters::NullColumn.new(name)
         
     | 
| 
       250 
     | 
    
         
            -
                    end
         
     | 
| 
      
 186 
     | 
    
         
            +
                  def _has_attribute?(attr_name) # :nodoc:
         
     | 
| 
      
 187 
     | 
    
         
            +
                    attribute_types.key?(attr_name)
         
     | 
| 
       251 
188 
     | 
    
         
             
                  end
         
     | 
| 
       252 
189 
     | 
    
         
             
                end
         
     | 
| 
       253 
190 
     | 
    
         | 
| 
         @@ -270,21 +207,14 @@ module ActiveRecord 
     | 
|
| 
       270 
207 
     | 
    
         
             
                def respond_to?(name, include_private = false)
         
     | 
| 
       271 
208 
     | 
    
         
             
                  return false unless super
         
     | 
| 
       272 
209 
     | 
    
         | 
| 
       273 
     | 
    
         
            -
                  case name
         
     | 
| 
       274 
     | 
    
         
            -
                  when :to_partial_path
         
     | 
| 
       275 
     | 
    
         
            -
                    name = "to_partial_path".freeze
         
     | 
| 
       276 
     | 
    
         
            -
                  when :to_model
         
     | 
| 
       277 
     | 
    
         
            -
                    name = "to_model".freeze
         
     | 
| 
       278 
     | 
    
         
            -
                  else
         
     | 
| 
       279 
     | 
    
         
            -
                    name = name.to_s
         
     | 
| 
       280 
     | 
    
         
            -
                  end
         
     | 
| 
       281 
     | 
    
         
            -
             
     | 
| 
       282 
210 
     | 
    
         
             
                  # If the result is true then check for the select case.
         
     | 
| 
       283 
211 
     | 
    
         
             
                  # For queries selecting a subset of columns, return false for unselected columns.
         
     | 
| 
       284 
212 
     | 
    
         
             
                  # We check defined?(@attributes) not to issue warnings if called on objects that
         
     | 
| 
       285 
213 
     | 
    
         
             
                  # have been allocated but not yet initialized.
         
     | 
| 
       286 
     | 
    
         
            -
                  if defined?(@attributes) 
     | 
| 
       287 
     | 
    
         
            -
                     
     | 
| 
      
 214 
     | 
    
         
            +
                  if defined?(@attributes)
         
     | 
| 
      
 215 
     | 
    
         
            +
                    if name = self.class.symbol_column_to_string(name.to_sym)
         
     | 
| 
      
 216 
     | 
    
         
            +
                      return _has_attribute?(name)
         
     | 
| 
      
 217 
     | 
    
         
            +
                    end
         
     | 
| 
       288 
218 
     | 
    
         
             
                  end
         
     | 
| 
       289 
219 
     | 
    
         | 
| 
       290 
220 
     | 
    
         
             
                  true
         
     | 
| 
         @@ -293,14 +223,22 @@ module ActiveRecord 
     | 
|
| 
       293 
223 
     | 
    
         
             
                # Returns +true+ if the given attribute is in the attributes hash, otherwise +false+.
         
     | 
| 
       294 
224 
     | 
    
         
             
                #
         
     | 
| 
       295 
225 
     | 
    
         
             
                #   class Person < ActiveRecord::Base
         
     | 
| 
      
 226 
     | 
    
         
            +
                #     alias_attribute :new_name, :name
         
     | 
| 
       296 
227 
     | 
    
         
             
                #   end
         
     | 
| 
       297 
228 
     | 
    
         
             
                #
         
     | 
| 
       298 
229 
     | 
    
         
             
                #   person = Person.new
         
     | 
| 
       299 
     | 
    
         
            -
                #   person.has_attribute?(:name) 
     | 
| 
       300 
     | 
    
         
            -
                #   person.has_attribute?( 
     | 
| 
       301 
     | 
    
         
            -
                #   person.has_attribute?( 
     | 
| 
      
 230 
     | 
    
         
            +
                #   person.has_attribute?(:name)     # => true
         
     | 
| 
      
 231 
     | 
    
         
            +
                #   person.has_attribute?(:new_name) # => true
         
     | 
| 
      
 232 
     | 
    
         
            +
                #   person.has_attribute?('age')     # => true
         
     | 
| 
      
 233 
     | 
    
         
            +
                #   person.has_attribute?(:nothing)  # => false
         
     | 
| 
       302 
234 
     | 
    
         
             
                def has_attribute?(attr_name)
         
     | 
| 
       303 
     | 
    
         
            -
                   
     | 
| 
      
 235 
     | 
    
         
            +
                  attr_name = attr_name.to_s
         
     | 
| 
      
 236 
     | 
    
         
            +
                  attr_name = self.class.attribute_aliases[attr_name] || attr_name
         
     | 
| 
      
 237 
     | 
    
         
            +
                  @attributes.key?(attr_name)
         
     | 
| 
      
 238 
     | 
    
         
            +
                end
         
     | 
| 
      
 239 
     | 
    
         
            +
             
     | 
| 
      
 240 
     | 
    
         
            +
                def _has_attribute?(attr_name) # :nodoc:
         
     | 
| 
      
 241 
     | 
    
         
            +
                  @attributes.key?(attr_name)
         
     | 
| 
       304 
242 
     | 
    
         
             
                end
         
     | 
| 
       305 
243 
     | 
    
         | 
| 
       306 
244 
     | 
    
         
             
                # Returns an array of names for the attributes available on this object.
         
     | 
| 
         @@ -329,9 +267,8 @@ module ActiveRecord 
     | 
|
| 
       329 
267 
     | 
    
         | 
| 
       330 
268 
     | 
    
         
             
                # Returns an <tt>#inspect</tt>-like string for the value of the
         
     | 
| 
       331 
269 
     | 
    
         
             
                # attribute +attr_name+. String attributes are truncated up to 50
         
     | 
| 
       332 
     | 
    
         
            -
                # characters 
     | 
| 
       333 
     | 
    
         
            -
                #  
     | 
| 
       334 
     | 
    
         
            -
                # <tt>#inspect</tt> without modification.
         
     | 
| 
      
 270 
     | 
    
         
            +
                # characters. Other attributes return the value of <tt>#inspect</tt>
         
     | 
| 
      
 271 
     | 
    
         
            +
                # without modification.
         
     | 
| 
       335 
272 
     | 
    
         
             
                #
         
     | 
| 
       336 
273 
     | 
    
         
             
                #   person = Person.create!(name: 'David Heinemeier Hansson ' * 3)
         
     | 
| 
       337 
274 
     | 
    
         
             
                #
         
     | 
| 
         @@ -339,20 +276,15 @@ module ActiveRecord 
     | 
|
| 
       339 
276 
     | 
    
         
             
                #   # => "\"David Heinemeier Hansson David Heinemeier Hansson ...\""
         
     | 
| 
       340 
277 
     | 
    
         
             
                #
         
     | 
| 
       341 
278 
     | 
    
         
             
                #   person.attribute_for_inspect(:created_at)
         
     | 
| 
       342 
     | 
    
         
            -
                #   # => "\"2012-10-22 00:15:07\""
         
     | 
| 
      
 279 
     | 
    
         
            +
                #   # => "\"2012-10-22 00:15:07.000000000 +0000\""
         
     | 
| 
       343 
280 
     | 
    
         
             
                #
         
     | 
| 
       344 
281 
     | 
    
         
             
                #   person.attribute_for_inspect(:tag_ids)
         
     | 
| 
       345 
282 
     | 
    
         
             
                #   # => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]"
         
     | 
| 
       346 
283 
     | 
    
         
             
                def attribute_for_inspect(attr_name)
         
     | 
| 
       347 
     | 
    
         
            -
                   
     | 
| 
       348 
     | 
    
         
            -
             
     | 
| 
       349 
     | 
    
         
            -
                   
     | 
| 
       350 
     | 
    
         
            -
             
     | 
| 
       351 
     | 
    
         
            -
                  elsif value.is_a?(Date) || value.is_a?(Time)
         
     | 
| 
       352 
     | 
    
         
            -
                    %("#{value.to_s(:db)}")
         
     | 
| 
       353 
     | 
    
         
            -
                  else
         
     | 
| 
       354 
     | 
    
         
            -
                    value.inspect
         
     | 
| 
       355 
     | 
    
         
            -
                  end
         
     | 
| 
      
 284 
     | 
    
         
            +
                  attr_name = attr_name.to_s
         
     | 
| 
      
 285 
     | 
    
         
            +
                  attr_name = self.class.attribute_aliases[attr_name] || attr_name
         
     | 
| 
      
 286 
     | 
    
         
            +
                  value = _read_attribute(attr_name)
         
     | 
| 
      
 287 
     | 
    
         
            +
                  format_for_inspect(attr_name, value)
         
     | 
| 
       356 
288 
     | 
    
         
             
                end
         
     | 
| 
       357 
289 
     | 
    
         | 
| 
       358 
290 
     | 
    
         
             
                # Returns +true+ if the specified +attribute+ has been set by the user or by a
         
     | 
| 
         @@ -370,8 +302,10 @@ module ActiveRecord 
     | 
|
| 
       370 
302 
     | 
    
         
             
                #   task.is_done = true
         
     | 
| 
       371 
303 
     | 
    
         
             
                #   task.attribute_present?(:title)   # => true
         
     | 
| 
       372 
304 
     | 
    
         
             
                #   task.attribute_present?(:is_done) # => true
         
     | 
| 
       373 
     | 
    
         
            -
                def attribute_present?( 
     | 
| 
       374 
     | 
    
         
            -
                   
     | 
| 
      
 305 
     | 
    
         
            +
                def attribute_present?(attr_name)
         
     | 
| 
      
 306 
     | 
    
         
            +
                  attr_name = attr_name.to_s
         
     | 
| 
      
 307 
     | 
    
         
            +
                  attr_name = self.class.attribute_aliases[attr_name] || attr_name
         
     | 
| 
      
 308 
     | 
    
         
            +
                  value = _read_attribute(attr_name)
         
     | 
| 
       375 
309 
     | 
    
         
             
                  !value.nil? && !(value.respond_to?(:empty?) && value.empty?)
         
     | 
| 
       376 
310 
     | 
    
         
             
                end
         
     | 
| 
       377 
311 
     | 
    
         | 
| 
         @@ -443,50 +377,53 @@ module ActiveRecord 
     | 
|
| 
       443 
377 
     | 
    
         
             
                  @attributes.accessed
         
     | 
| 
       444 
378 
     | 
    
         
             
                end
         
     | 
| 
       445 
379 
     | 
    
         | 
| 
       446 
     | 
    
         
            -
                 
     | 
| 
       447 
     | 
    
         
            -
             
     | 
| 
       448 
     | 
    
         
            -
                  def attribute_method?(attr_name) # :nodoc:
         
     | 
| 
      
 380 
     | 
    
         
            +
                private
         
     | 
| 
      
 381 
     | 
    
         
            +
                  def attribute_method?(attr_name)
         
     | 
| 
       449 
382 
     | 
    
         
             
                    # We check defined? because Syck calls respond_to? before actually calling initialize.
         
     | 
| 
       450 
383 
     | 
    
         
             
                    defined?(@attributes) && @attributes.key?(attr_name)
         
     | 
| 
       451 
384 
     | 
    
         
             
                  end
         
     | 
| 
       452 
385 
     | 
    
         | 
| 
       453 
     | 
    
         
            -
                private
         
     | 
| 
       454 
     | 
    
         
            -
             
     | 
| 
       455 
     | 
    
         
            -
                  def attributes_with_values_for_create(attribute_names)
         
     | 
| 
       456 
     | 
    
         
            -
                    attributes_with_values(attributes_for_create(attribute_names))
         
     | 
| 
       457 
     | 
    
         
            -
                  end
         
     | 
| 
       458 
     | 
    
         
            -
             
     | 
| 
       459 
     | 
    
         
            -
                  def attributes_with_values_for_update(attribute_names)
         
     | 
| 
       460 
     | 
    
         
            -
                    attributes_with_values(attributes_for_update(attribute_names))
         
     | 
| 
       461 
     | 
    
         
            -
                  end
         
     | 
| 
       462 
     | 
    
         
            -
             
     | 
| 
       463 
386 
     | 
    
         
             
                  def attributes_with_values(attribute_names)
         
     | 
| 
       464 
     | 
    
         
            -
                    attribute_names. 
     | 
| 
       465 
     | 
    
         
            -
                      attrs[name] = _read_attribute(name)
         
     | 
| 
       466 
     | 
    
         
            -
                    end
         
     | 
| 
      
 387 
     | 
    
         
            +
                    attribute_names.index_with { |name| @attributes[name] }
         
     | 
| 
       467 
388 
     | 
    
         
             
                  end
         
     | 
| 
       468 
389 
     | 
    
         | 
| 
       469 
     | 
    
         
            -
                  # Filters the primary keys  
     | 
| 
      
 390 
     | 
    
         
            +
                  # Filters the primary keys, readonly attributes and virtual columns from the attribute names.
         
     | 
| 
       470 
391 
     | 
    
         
             
                  def attributes_for_update(attribute_names)
         
     | 
| 
       471 
     | 
    
         
            -
                    attribute_names 
     | 
| 
       472 
     | 
    
         
            -
             
     | 
| 
      
 392 
     | 
    
         
            +
                    attribute_names &= self.class.column_names
         
     | 
| 
      
 393 
     | 
    
         
            +
                    attribute_names.delete_if do |name|
         
     | 
| 
      
 394 
     | 
    
         
            +
                      self.class.readonly_attribute?(name) ||
         
     | 
| 
      
 395 
     | 
    
         
            +
                        column_for_attribute(name).virtual?
         
     | 
| 
       473 
396 
     | 
    
         
             
                    end
         
     | 
| 
       474 
397 
     | 
    
         
             
                  end
         
     | 
| 
       475 
398 
     | 
    
         | 
| 
       476 
     | 
    
         
            -
                  # Filters out the primary keys, from the attribute names, when the primary
         
     | 
| 
      
 399 
     | 
    
         
            +
                  # Filters out the virtual columns and also primary keys, from the attribute names, when the primary
         
     | 
| 
       477 
400 
     | 
    
         
             
                  # key is to be generated (e.g. the id attribute has no value).
         
     | 
| 
       478 
401 
     | 
    
         
             
                  def attributes_for_create(attribute_names)
         
     | 
| 
       479 
     | 
    
         
            -
                    attribute_names 
     | 
| 
       480 
     | 
    
         
            -
             
     | 
| 
      
 402 
     | 
    
         
            +
                    attribute_names &= self.class.column_names
         
     | 
| 
      
 403 
     | 
    
         
            +
                    attribute_names.delete_if do |name|
         
     | 
| 
      
 404 
     | 
    
         
            +
                      (pk_attribute?(name) && id.nil?) ||
         
     | 
| 
      
 405 
     | 
    
         
            +
                        column_for_attribute(name).virtual?
         
     | 
| 
       481 
406 
     | 
    
         
             
                    end
         
     | 
| 
       482 
407 
     | 
    
         
             
                  end
         
     | 
| 
       483 
408 
     | 
    
         | 
| 
       484 
     | 
    
         
            -
                  def  
     | 
| 
       485 
     | 
    
         
            -
                     
     | 
| 
      
 409 
     | 
    
         
            +
                  def format_for_inspect(name, value)
         
     | 
| 
      
 410 
     | 
    
         
            +
                    if value.nil?
         
     | 
| 
      
 411 
     | 
    
         
            +
                      value.inspect
         
     | 
| 
      
 412 
     | 
    
         
            +
                    else
         
     | 
| 
      
 413 
     | 
    
         
            +
                      inspected_value = if value.is_a?(String) && value.length > 50
         
     | 
| 
      
 414 
     | 
    
         
            +
                        "#{value[0, 50]}...".inspect
         
     | 
| 
      
 415 
     | 
    
         
            +
                      elsif value.is_a?(Date) || value.is_a?(Time)
         
     | 
| 
      
 416 
     | 
    
         
            +
                        %("#{value.to_fs(:inspect)}")
         
     | 
| 
      
 417 
     | 
    
         
            +
                      else
         
     | 
| 
      
 418 
     | 
    
         
            +
                        value.inspect
         
     | 
| 
      
 419 
     | 
    
         
            +
                      end
         
     | 
| 
      
 420 
     | 
    
         
            +
             
     | 
| 
      
 421 
     | 
    
         
            +
                      inspection_filter.filter_param(name, inspected_value)
         
     | 
| 
      
 422 
     | 
    
         
            +
                    end
         
     | 
| 
       486 
423 
     | 
    
         
             
                  end
         
     | 
| 
       487 
424 
     | 
    
         | 
| 
       488 
425 
     | 
    
         
             
                  def pk_attribute?(name)
         
     | 
| 
       489 
     | 
    
         
            -
                    name ==  
     | 
| 
      
 426 
     | 
    
         
            +
                    name == @primary_key
         
     | 
| 
       490 
427 
     | 
    
         
             
                  end
         
     | 
| 
       491 
428 
     | 
    
         
             
              end
         
     | 
| 
       492 
429 
     | 
    
         
             
            end
         
     | 
| 
         @@ -41,6 +41,9 @@ module ActiveRecord 
     | 
|
| 
       41 
41 
     | 
    
         
             
                  # +range+ (PostgreSQL only) specifies that the type should be a range (see the
         
     | 
| 
       42 
42 
     | 
    
         
             
                  # examples below).
         
     | 
| 
       43 
43 
     | 
    
         
             
                  #
         
     | 
| 
      
 44 
     | 
    
         
            +
                  # When using a symbol for +cast_type+, extra options are forwarded to the
         
     | 
| 
      
 45 
     | 
    
         
            +
                  # constructor of the type object.
         
     | 
| 
      
 46 
     | 
    
         
            +
                  #
         
     | 
| 
       44 
47 
     | 
    
         
             
                  # ==== Examples
         
     | 
| 
       45 
48 
     | 
    
         
             
                  #
         
     | 
| 
       46 
49 
     | 
    
         
             
                  # The type detected by Active Record can be overridden.
         
     | 
| 
         @@ -112,6 +115,16 @@ module ActiveRecord 
     | 
|
| 
       112 
115 
     | 
    
         
             
                  #       my_float_range: 1.0..3.5
         
     | 
| 
       113 
116 
     | 
    
         
             
                  #     }
         
     | 
| 
       114 
117 
     | 
    
         
             
                  #
         
     | 
| 
      
 118 
     | 
    
         
            +
                  # Passing options to the type constructor
         
     | 
| 
      
 119 
     | 
    
         
            +
                  #
         
     | 
| 
      
 120 
     | 
    
         
            +
                  #   # app/models/my_model.rb
         
     | 
| 
      
 121 
     | 
    
         
            +
                  #   class MyModel < ActiveRecord::Base
         
     | 
| 
      
 122 
     | 
    
         
            +
                  #     attribute :small_int, :integer, limit: 2
         
     | 
| 
      
 123 
     | 
    
         
            +
                  #   end
         
     | 
| 
      
 124 
     | 
    
         
            +
                  #
         
     | 
| 
      
 125 
     | 
    
         
            +
                  #   MyModel.create(small_int: 65537)
         
     | 
| 
      
 126 
     | 
    
         
            +
                  #   # => Error: 65537 is out of range for the limit of two bytes
         
     | 
| 
      
 127 
     | 
    
         
            +
                  #
         
     | 
| 
       115 
128 
     | 
    
         
             
                  # ==== Creating Custom Types
         
     | 
| 
       116 
129 
     | 
    
         
             
                  #
         
     | 
| 
       117 
130 
     | 
    
         
             
                  # Users may also define their own custom types, as long as they respond
         
     | 
| 
         @@ -157,7 +170,7 @@ module ActiveRecord 
     | 
|
| 
       157 
170 
     | 
    
         
             
                  #   class Money < Struct.new(:amount, :currency)
         
     | 
| 
       158 
171 
     | 
    
         
             
                  #   end
         
     | 
| 
       159 
172 
     | 
    
         
             
                  #
         
     | 
| 
       160 
     | 
    
         
            -
                  #   class MoneyType < Type::Value
         
     | 
| 
      
 173 
     | 
    
         
            +
                  #   class MoneyType < ActiveRecord::Type::Value
         
     | 
| 
       161 
174 
     | 
    
         
             
                  #     def initialize(currency_converter:)
         
     | 
| 
       162 
175 
     | 
    
         
             
                  #       @currency_converter = currency_converter
         
     | 
| 
       163 
176 
     | 
    
         
             
                  #     end
         
     | 
| 
         @@ -192,14 +205,31 @@ module ActiveRecord 
     | 
|
| 
       192 
205 
     | 
    
         
             
                  # tracking is performed. The methods +changed?+ and +changed_in_place?+
         
     | 
| 
       193 
206 
     | 
    
         
             
                  # will be called from ActiveModel::Dirty. See the documentation for those
         
     | 
| 
       194 
207 
     | 
    
         
             
                  # methods in ActiveModel::Type::Value for more details.
         
     | 
| 
       195 
     | 
    
         
            -
                  def attribute(name, cast_type =  
     | 
| 
      
 208 
     | 
    
         
            +
                  def attribute(name, cast_type = nil, default: NO_DEFAULT_PROVIDED, **options)
         
     | 
| 
       196 
209 
     | 
    
         
             
                    name = name.to_s
         
     | 
| 
      
 210 
     | 
    
         
            +
                    name = attribute_aliases[name] || name
         
     | 
| 
      
 211 
     | 
    
         
            +
             
     | 
| 
       197 
212 
     | 
    
         
             
                    reload_schema_from_cache
         
     | 
| 
       198 
213 
     | 
    
         | 
| 
      
 214 
     | 
    
         
            +
                    case cast_type
         
     | 
| 
      
 215 
     | 
    
         
            +
                    when Symbol
         
     | 
| 
      
 216 
     | 
    
         
            +
                      cast_type = Type.lookup(cast_type, **options, adapter: Type.adapter_name_from(self))
         
     | 
| 
      
 217 
     | 
    
         
            +
                    when nil
         
     | 
| 
      
 218 
     | 
    
         
            +
                      if (prev_cast_type, prev_default = attributes_to_define_after_schema_loads[name])
         
     | 
| 
      
 219 
     | 
    
         
            +
                        default = prev_default if default == NO_DEFAULT_PROVIDED
         
     | 
| 
      
 220 
     | 
    
         
            +
                      else
         
     | 
| 
      
 221 
     | 
    
         
            +
                        prev_cast_type = -> subtype { subtype }
         
     | 
| 
      
 222 
     | 
    
         
            +
                      end
         
     | 
| 
      
 223 
     | 
    
         
            +
             
     | 
| 
      
 224 
     | 
    
         
            +
                      cast_type = if block_given?
         
     | 
| 
      
 225 
     | 
    
         
            +
                        -> subtype { yield Proc === prev_cast_type ? prev_cast_type[subtype] : prev_cast_type }
         
     | 
| 
      
 226 
     | 
    
         
            +
                      else
         
     | 
| 
      
 227 
     | 
    
         
            +
                        prev_cast_type
         
     | 
| 
      
 228 
     | 
    
         
            +
                      end
         
     | 
| 
      
 229 
     | 
    
         
            +
                    end
         
     | 
| 
      
 230 
     | 
    
         
            +
             
     | 
| 
       199 
231 
     | 
    
         
             
                    self.attributes_to_define_after_schema_loads =
         
     | 
| 
       200 
     | 
    
         
            -
                      attributes_to_define_after_schema_loads.merge(
         
     | 
| 
       201 
     | 
    
         
            -
                        name => [cast_type, options]
         
     | 
| 
       202 
     | 
    
         
            -
                      )
         
     | 
| 
      
 232 
     | 
    
         
            +
                      attributes_to_define_after_schema_loads.merge(name => [cast_type, default])
         
     | 
| 
       203 
233 
     | 
    
         
             
                  end
         
     | 
| 
       204 
234 
     | 
    
         | 
| 
       205 
235 
     | 
    
         
             
                  # This is the low level API which sits beneath +attribute+. It only
         
     | 
| 
         @@ -232,17 +262,13 @@ module ActiveRecord 
     | 
|
| 
       232 
262 
     | 
    
         | 
| 
       233 
263 
     | 
    
         
             
                  def load_schema! # :nodoc:
         
     | 
| 
       234 
264 
     | 
    
         
             
                    super
         
     | 
| 
       235 
     | 
    
         
            -
                    attributes_to_define_after_schema_loads.each do |name, ( 
     | 
| 
       236 
     | 
    
         
            -
                       
     | 
| 
       237 
     | 
    
         
            -
             
     | 
| 
       238 
     | 
    
         
            -
                      end
         
     | 
| 
       239 
     | 
    
         
            -
             
     | 
| 
       240 
     | 
    
         
            -
                      define_attribute(name, type, **options.slice(:default))
         
     | 
| 
      
 265 
     | 
    
         
            +
                    attributes_to_define_after_schema_loads.each do |name, (cast_type, default)|
         
     | 
| 
      
 266 
     | 
    
         
            +
                      cast_type = cast_type[type_for_attribute(name)] if Proc === cast_type
         
     | 
| 
      
 267 
     | 
    
         
            +
                      define_attribute(name, cast_type, default: default)
         
     | 
| 
       241 
268 
     | 
    
         
             
                    end
         
     | 
| 
       242 
269 
     | 
    
         
             
                  end
         
     | 
| 
       243 
270 
     | 
    
         | 
| 
       244 
271 
     | 
    
         
             
                  private
         
     | 
| 
       245 
     | 
    
         
            -
             
     | 
| 
       246 
272 
     | 
    
         
             
                    NO_DEFAULT_PROVIDED = Object.new # :nodoc:
         
     | 
| 
       247 
273 
     | 
    
         
             
                    private_constant :NO_DEFAULT_PROVIDED
         
     | 
| 
       248 
274 
     | 
    
         |