activerecord 5.2.8 → 7.0.2
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 +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
|
|