activerecord 6.0.0 → 7.2.3
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +996 -594
- data/MIT-LICENSE +1 -1
- data/README.rdoc +34 -34
- data/examples/performance.rb +2 -2
- data/lib/active_record/aggregations.rb +22 -20
- data/lib/active_record/association_relation.rb +22 -12
- data/lib/active_record/associations/alias_tracker.rb +41 -30
- data/lib/active_record/associations/association.rb +106 -41
- data/lib/active_record/associations/association_scope.rb +30 -21
- data/lib/active_record/associations/belongs_to_association.rb +69 -14
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +20 -6
- data/lib/active_record/associations/builder/association.rb +39 -6
- data/lib/active_record/associations/builder/belongs_to.rb +47 -17
- data/lib/active_record/associations/builder/collection_association.rb +14 -6
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -10
- data/lib/active_record/associations/builder/has_many.rb +7 -3
- data/lib/active_record/associations/builder/has_one.rb +13 -16
- data/lib/active_record/associations/builder/singular_association.rb +7 -3
- data/lib/active_record/associations/collection_association.rb +90 -53
- data/lib/active_record/associations/collection_proxy.rb +54 -19
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/errors.rb +265 -0
- data/lib/active_record/associations/foreign_association.rb +21 -1
- data/lib/active_record/associations/has_many_association.rb +41 -10
- data/lib/active_record/associations/has_many_through_association.rb +29 -12
- data/lib/active_record/associations/has_one_association.rb +33 -9
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +41 -17
- data/lib/active_record/associations/join_dependency/join_part.rb +3 -3
- data/lib/active_record/associations/join_dependency.rb +97 -54
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +237 -54
- data/lib/active_record/associations/preloader/batch.rb +48 -0
- data/lib/active_record/associations/preloader/branch.rb +153 -0
- data/lib/active_record/associations/preloader/through_association.rb +51 -17
- data/lib/active_record/associations/preloader.rb +55 -121
- data/lib/active_record/associations/singular_association.rb +16 -4
- data/lib/active_record/associations/through_association.rb +26 -15
- data/lib/active_record/associations.rb +454 -440
- data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
- data/lib/active_record/attribute_assignment.rb +11 -14
- data/lib/active_record/attribute_methods/before_type_cast.rb +36 -11
- data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
- data/lib/active_record/attribute_methods/dirty.rb +75 -34
- data/lib/active_record/attribute_methods/primary_key.rb +53 -31
- data/lib/active_record/attribute_methods/query.rb +31 -22
- data/lib/active_record/attribute_methods/read.rb +16 -17
- data/lib/active_record/attribute_methods/serialization.rb +177 -35
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +18 -15
- data/lib/active_record/attribute_methods/write.rb +16 -28
- data/lib/active_record/attribute_methods.rb +227 -100
- data/lib/active_record/attributes.rb +94 -56
- data/lib/active_record/autosave_association.rb +119 -73
- data/lib/active_record/base.rb +31 -21
- data/lib/active_record/callbacks.rb +168 -55
- data/lib/active_record/coders/column_serializer.rb +61 -0
- data/lib/active_record/coders/json.rb +1 -1
- data/lib/active_record/coders/yaml_column.rb +70 -25
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +284 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +79 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +367 -565
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -57
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +277 -89
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +241 -69
- data/lib/active_record/connection_adapters/abstract/quoting.rb +122 -134
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -116
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +324 -72
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +17 -4
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +611 -211
- data/lib/active_record/connection_adapters/abstract/transaction.rb +425 -82
- data/lib/active_record/connection_adapters/abstract_adapter.rb +698 -211
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +464 -239
- data/lib/active_record/connection_adapters/column.rb +28 -1
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +32 -137
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +90 -43
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +41 -7
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +18 -1
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +13 -4
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +53 -15
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +152 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +127 -63
- data/lib/active_record/connection_adapters/pool_config.rb +83 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +57 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +54 -2
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +127 -100
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +9 -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 +53 -15
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +5 -4
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +35 -8
- 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 +18 -6
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +23 -4
- data/lib/active_record/connection_adapters/postgresql/oid.rb +4 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +139 -106
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -2
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +98 -4
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +176 -4
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +462 -118
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -11
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +585 -295
- data/lib/active_record/connection_adapters/schema_cache.rb +399 -60
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +99 -48
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +80 -54
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +27 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +20 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +102 -24
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +425 -174
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -1
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +229 -0
- data/lib/active_record/connection_adapters.rb +176 -0
- data/lib/active_record/connection_handling.rb +243 -115
- data/lib/active_record/core.rb +481 -199
- data/lib/active_record/counter_cache.rb +69 -32
- data/lib/active_record/database_configurations/connection_url_resolver.rb +107 -0
- data/lib/active_record/database_configurations/database_config.rb +77 -10
- data/lib/active_record/database_configurations/hash_config.rb +148 -26
- data/lib/active_record/database_configurations/url_config.rb +44 -45
- data/lib/active_record/database_configurations.rb +190 -114
- data/lib/active_record/delegated_type.rb +279 -0
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +38 -0
- data/lib/active_record/disable_joins_association_relation.rb +39 -0
- data/lib/active_record/dynamic_matchers.rb +5 -6
- data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
- data/lib/active_record/encryption/cipher.rb +53 -0
- data/lib/active_record/encryption/config.rb +68 -0
- data/lib/active_record/encryption/configurable.rb +60 -0
- data/lib/active_record/encryption/context.rb +42 -0
- data/lib/active_record/encryption/contexts.rb +76 -0
- data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
- data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
- data/lib/active_record/encryption/encryptable_record.rb +230 -0
- data/lib/active_record/encryption/encrypted_attribute_type.rb +175 -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 +171 -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 +157 -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 +53 -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_pack_message_serializer.rb +76 -0
- data/lib/active_record/encryption/message_serializer.rb +96 -0
- data/lib/active_record/encryption/null_encryptor.rb +25 -0
- data/lib/active_record/encryption/properties.rb +76 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +28 -0
- data/lib/active_record/encryption/scheme.rb +100 -0
- data/lib/active_record/encryption.rb +58 -0
- data/lib/active_record/enum.rb +224 -73
- data/lib/active_record/errors.rb +254 -36
- data/lib/active_record/explain.rb +30 -17
- data/lib/active_record/explain_registry.rb +11 -6
- data/lib/active_record/explain_subscriber.rb +2 -2
- data/lib/active_record/fixture_set/file.rb +22 -15
- data/lib/active_record/fixture_set/model_metadata.rb +15 -6
- data/lib/active_record/fixture_set/render_context.rb +3 -1
- data/lib/active_record/fixture_set/table_row.rb +88 -16
- data/lib/active_record/fixture_set/table_rows.rb +4 -5
- data/lib/active_record/fixtures.rb +229 -116
- data/lib/active_record/future_result.rb +178 -0
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +121 -48
- data/lib/active_record/insert_all.rb +178 -29
- data/lib/active_record/integration.rb +16 -14
- data/lib/active_record/internal_metadata.rb +132 -21
- data/lib/active_record/legacy_yaml_adapter.rb +3 -36
- data/lib/active_record/locking/optimistic.rb +64 -33
- data/lib/active_record/locking/pessimistic.rb +21 -8
- data/lib/active_record/log_subscriber.rb +61 -30
- data/lib/active_record/marshalling.rb +59 -0
- data/lib/active_record/message_pack.rb +124 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +19 -19
- data/lib/active_record/middleware/database_selector.rb +25 -13
- data/lib/active_record/middleware/shard_selector.rb +62 -0
- data/lib/active_record/migration/command_recorder.rb +160 -55
- data/lib/active_record/migration/compatibility.rb +286 -43
- data/lib/active_record/migration/default_strategy.rb +22 -0
- data/lib/active_record/migration/execution_strategy.rb +19 -0
- data/lib/active_record/migration/join_table.rb +1 -2
- data/lib/active_record/migration/pending_migration_connection.rb +21 -0
- data/lib/active_record/migration.rb +421 -193
- data/lib/active_record/model_schema.rb +217 -125
- data/lib/active_record/nested_attributes.rb +62 -27
- data/lib/active_record/no_touching.rb +4 -4
- data/lib/active_record/normalization.rb +163 -0
- data/lib/active_record/persistence.rb +322 -319
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +18 -15
- data/lib/active_record/query_logs.rb +193 -0
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +54 -14
- data/lib/active_record/railtie.rb +250 -72
- data/lib/active_record/railties/console_sandbox.rb +2 -4
- data/lib/active_record/railties/controller_runtime.rb +25 -11
- data/lib/active_record/railties/databases.rake +312 -197
- data/lib/active_record/railties/job_runtime.rb +23 -0
- data/lib/active_record/readonly_attributes.rb +45 -3
- data/lib/active_record/reflection.rb +389 -146
- data/lib/active_record/relation/batches/batch_enumerator.rb +61 -16
- data/lib/active_record/relation/batches.rb +214 -73
- data/lib/active_record/relation/calculations.rb +379 -124
- data/lib/active_record/relation/delegation.rb +36 -23
- data/lib/active_record/relation/finder_methods.rb +159 -49
- data/lib/active_record/relation/from_clause.rb +5 -1
- data/lib/active_record/relation/merger.rb +41 -33
- data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -11
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -7
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +20 -13
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
- data/lib/active_record/relation/predicate_builder.rb +79 -53
- data/lib/active_record/relation/query_attribute.rb +30 -12
- data/lib/active_record/relation/query_methods.rb +1156 -279
- data/lib/active_record/relation/record_fetch_warning.rb +12 -11
- data/lib/active_record/relation/spawn_methods.rb +10 -9
- data/lib/active_record/relation/where_clause.rb +100 -66
- data/lib/active_record/relation.rb +829 -194
- data/lib/active_record/result.rb +76 -56
- data/lib/active_record/runtime_registry.rb +71 -13
- data/lib/active_record/sanitization.rb +86 -47
- data/lib/active_record/schema.rb +39 -23
- data/lib/active_record/schema_dumper.rb +140 -33
- data/lib/active_record/schema_migration.rb +74 -29
- data/lib/active_record/scoping/default.rb +73 -19
- data/lib/active_record/scoping/named.rb +10 -28
- data/lib/active_record/scoping.rb +65 -35
- data/lib/active_record/secure_password.rb +60 -0
- data/lib/active_record/secure_token.rb +34 -8
- data/lib/active_record/serialization.rb +11 -4
- data/lib/active_record/signed_id.rb +138 -0
- data/lib/active_record/statement_cache.rb +26 -10
- data/lib/active_record/store.rb +19 -14
- data/lib/active_record/suppressor.rb +15 -17
- data/lib/active_record/table_metadata.rb +46 -36
- data/lib/active_record/tasks/database_tasks.rb +371 -205
- data/lib/active_record/tasks/mysql_database_tasks.rb +43 -36
- data/lib/active_record/tasks/postgresql_database_tasks.rb +54 -41
- data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -13
- data/lib/active_record/test_databases.rb +5 -4
- data/lib/active_record/test_fixtures.rb +189 -104
- data/lib/active_record/testing/query_assertions.rb +121 -0
- data/lib/active_record/timestamp.rb +35 -25
- data/lib/active_record/token_for.rb +123 -0
- data/lib/active_record/touch_later.rb +31 -27
- data/lib/active_record/transaction.rb +132 -0
- data/lib/active_record/transactions.rb +131 -99
- data/lib/active_record/translation.rb +3 -5
- data/lib/active_record/type/adapter_specific_registry.rb +33 -18
- data/lib/active_record/type/hash_lookup_type_map.rb +34 -2
- data/lib/active_record/type/internal/timezone.rb +7 -2
- data/lib/active_record/type/serialized.rb +11 -6
- data/lib/active_record/type/time.rb +14 -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 +7 -2
- data/lib/active_record/type_caster/connection.rb +4 -5
- data/lib/active_record/type_caster/map.rb +8 -5
- data/lib/active_record/validations/absence.rb +1 -1
- data/lib/active_record/validations/associated.rb +13 -8
- data/lib/active_record/validations/numericality.rb +36 -0
- data/lib/active_record/validations/presence.rb +5 -28
- data/lib/active_record/validations/uniqueness.rb +88 -18
- data/lib/active_record/validations.rb +15 -8
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +446 -40
- data/lib/arel/alias_predication.rb +1 -1
- data/lib/arel/attributes/attribute.rb +4 -8
- data/lib/arel/collectors/bind.rb +8 -1
- data/lib/arel/collectors/composite.rb +15 -0
- data/lib/arel/collectors/sql_string.rb +7 -0
- data/lib/arel/collectors/substitute_binds.rb +7 -0
- data/lib/arel/crud.rb +30 -22
- data/lib/arel/delete_manager.rb +23 -4
- data/lib/arel/errors.rb +10 -0
- data/lib/arel/factory_methods.rb +4 -0
- data/lib/arel/filter_predications.rb +9 -0
- data/lib/arel/insert_manager.rb +2 -3
- data/lib/arel/nodes/binary.rb +82 -9
- data/lib/arel/nodes/bind_param.rb +8 -0
- data/lib/arel/nodes/bound_sql_literal.rb +65 -0
- data/lib/arel/nodes/casted.rb +22 -10
- data/lib/arel/nodes/cte.rb +36 -0
- data/lib/arel/nodes/delete_statement.rb +14 -13
- data/lib/arel/nodes/equality.rb +6 -9
- data/lib/arel/nodes/filter.rb +10 -0
- data/lib/arel/nodes/fragments.rb +35 -0
- data/lib/arel/nodes/function.rb +1 -0
- data/lib/arel/nodes/grouping.rb +3 -0
- data/lib/arel/nodes/homogeneous_in.rb +68 -0
- data/lib/arel/nodes/in.rb +8 -1
- data/lib/arel/nodes/infix_operation.rb +13 -1
- data/lib/arel/nodes/insert_statement.rb +2 -2
- data/lib/arel/nodes/join_source.rb +1 -1
- data/lib/arel/nodes/leading_join.rb +8 -0
- data/lib/arel/nodes/{and.rb → nary.rb} +9 -2
- data/lib/arel/nodes/node.rb +122 -11
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/select_core.rb +2 -2
- data/lib/arel/nodes/select_statement.rb +2 -2
- data/lib/arel/nodes/sql_literal.rb +16 -0
- data/lib/arel/nodes/table_alias.rb +11 -3
- data/lib/arel/nodes/unary.rb +0 -1
- data/lib/arel/nodes/update_statement.rb +11 -4
- data/lib/arel/nodes.rb +10 -3
- data/lib/arel/predications.rb +31 -28
- data/lib/arel/select_manager.rb +18 -9
- data/lib/arel/table.rb +21 -10
- data/lib/arel/tree_manager.rb +8 -15
- data/lib/arel/update_manager.rb +25 -5
- data/lib/arel/visitors/dot.rb +94 -90
- data/lib/arel/visitors/mysql.rb +34 -6
- data/lib/arel/visitors/postgresql.rb +5 -16
- data/lib/arel/visitors/sqlite.rb +25 -1
- data/lib/arel/visitors/to_sql.rb +227 -81
- data/lib/arel/visitors/visitor.rb +2 -3
- data/lib/arel/visitors.rb +0 -7
- data/lib/arel.rb +37 -15
- data/lib/rails/generators/active_record/application_record/USAGE +8 -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 +1 -0
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +6 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -4
- data/lib/rails/generators/active_record/migration.rb +9 -3
- data/lib/rails/generators/active_record/model/USAGE +113 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +49 -4
- 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 +1 -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 +117 -30
- data/lib/active_record/attribute_decorators.rb +0 -90
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -297
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
- data/lib/active_record/define_callbacks.rb +0 -22
- data/lib/active_record/null_relation.rb +0 -68
- data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
- data/lib/active_record/relation/where_clause_factory.rb +0 -33
- data/lib/arel/attributes.rb +0 -22
- data/lib/arel/visitors/depth_first.rb +0 -204
- data/lib/arel/visitors/ibm_db.rb +0 -34
- data/lib/arel/visitors/informix.rb +0 -62
- data/lib/arel/visitors/mssql.rb +0 -157
- data/lib/arel/visitors/oracle.rb +0 -159
- data/lib/arel/visitors/oracle12.rb +0 -66
- data/lib/arel/visitors/where_sql.rb +0 -23
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "
|
|
3
|
+
require "active_support/core_ext/enumerable"
|
|
4
4
|
|
|
5
5
|
module ActiveRecord
|
|
6
6
|
# = Active Record Attribute Methods
|
|
@@ -18,49 +18,133 @@ module ActiveRecord
|
|
|
18
18
|
include TimeZoneConversion
|
|
19
19
|
include Dirty
|
|
20
20
|
include Serialization
|
|
21
|
-
|
|
22
|
-
delegate :column_for_attribute, to: :class
|
|
23
21
|
end
|
|
24
22
|
|
|
25
|
-
RESTRICTED_CLASS_METHODS = %w(private public protected allocate new name
|
|
23
|
+
RESTRICTED_CLASS_METHODS = %w(private public protected allocate new name superclass)
|
|
26
24
|
|
|
27
|
-
class GeneratedAttributeMethods < Module
|
|
28
|
-
|
|
25
|
+
class GeneratedAttributeMethods < Module # :nodoc:
|
|
26
|
+
LOCK = Monitor.new
|
|
29
27
|
end
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
def
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
class << self
|
|
30
|
+
def dangerous_attribute_methods # :nodoc:
|
|
31
|
+
@dangerous_attribute_methods ||= (
|
|
32
|
+
Base.instance_methods +
|
|
33
|
+
Base.private_instance_methods -
|
|
34
|
+
Base.superclass.instance_methods -
|
|
35
|
+
Base.superclass.private_instance_methods +
|
|
36
|
+
%i[__id__ dup freeze frozen? hash class clone]
|
|
37
|
+
).map { |m| -m.to_s }.to_set.freeze
|
|
35
38
|
end
|
|
39
|
+
end
|
|
36
40
|
|
|
41
|
+
module ClassMethods
|
|
37
42
|
def initialize_generated_modules # :nodoc:
|
|
38
43
|
@generated_attribute_methods = const_set(:GeneratedAttributeMethods, GeneratedAttributeMethods.new)
|
|
39
44
|
private_constant :GeneratedAttributeMethods
|
|
40
45
|
@attribute_methods_generated = false
|
|
46
|
+
@alias_attributes_mass_generated = false
|
|
41
47
|
include @generated_attribute_methods
|
|
42
48
|
|
|
43
49
|
super
|
|
44
50
|
end
|
|
45
51
|
|
|
52
|
+
# Allows you to make aliases for attributes.
|
|
53
|
+
#
|
|
54
|
+
# class Person < ActiveRecord::Base
|
|
55
|
+
# alias_attribute :nickname, :name
|
|
56
|
+
# end
|
|
57
|
+
#
|
|
58
|
+
# person = Person.create(name: 'Bob')
|
|
59
|
+
# person.name # => "Bob"
|
|
60
|
+
# person.nickname # => "Bob"
|
|
61
|
+
#
|
|
62
|
+
# The alias can also be used for querying:
|
|
63
|
+
#
|
|
64
|
+
# Person.where(nickname: "Bob")
|
|
65
|
+
# # SELECT "people".* FROM "people" WHERE "people"."name" = "Bob"
|
|
66
|
+
def alias_attribute(new_name, old_name)
|
|
67
|
+
super
|
|
68
|
+
|
|
69
|
+
if @alias_attributes_mass_generated
|
|
70
|
+
ActiveSupport::CodeGenerator.batch(generated_attribute_methods, __FILE__, __LINE__) do |code_generator|
|
|
71
|
+
generate_alias_attribute_methods(code_generator, new_name, old_name)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def eagerly_generate_alias_attribute_methods(_new_name, _old_name) # :nodoc:
|
|
77
|
+
# alias attributes in Active Record are lazily generated
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def generate_alias_attribute_methods(code_generator, new_name, old_name) # :nodoc:
|
|
81
|
+
attribute_method_patterns.each do |pattern|
|
|
82
|
+
alias_attribute_method_definition(code_generator, pattern, new_name, old_name)
|
|
83
|
+
end
|
|
84
|
+
attribute_method_patterns_cache.clear
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def alias_attribute_method_definition(code_generator, pattern, new_name, old_name) # :nodoc:
|
|
88
|
+
old_name = old_name.to_s
|
|
89
|
+
|
|
90
|
+
if !abstract_class? && !has_attribute?(old_name)
|
|
91
|
+
raise ArgumentError, "#{self.name} model aliases `#{old_name}`, but `#{old_name}` is not an attribute. " \
|
|
92
|
+
"Use `alias_method :#{new_name}, :#{old_name}` or define the method manually."
|
|
93
|
+
else
|
|
94
|
+
define_attribute_method_pattern(pattern, old_name, owner: code_generator, as: new_name, override: true)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def attribute_methods_generated? # :nodoc:
|
|
99
|
+
@attribute_methods_generated
|
|
100
|
+
end
|
|
101
|
+
|
|
46
102
|
# Generates all the attribute related methods for columns in the database
|
|
47
103
|
# accessors, mutators and query methods.
|
|
48
104
|
def define_attribute_methods # :nodoc:
|
|
49
105
|
return false if @attribute_methods_generated
|
|
50
106
|
# Use a mutex; we don't want two threads simultaneously trying to define
|
|
51
107
|
# attribute methods.
|
|
52
|
-
|
|
108
|
+
GeneratedAttributeMethods::LOCK.synchronize do
|
|
53
109
|
return false if @attribute_methods_generated
|
|
110
|
+
|
|
54
111
|
superclass.define_attribute_methods unless base_class?
|
|
55
|
-
|
|
112
|
+
|
|
113
|
+
unless abstract_class?
|
|
114
|
+
load_schema
|
|
115
|
+
super(attribute_names)
|
|
116
|
+
alias_attribute :id_value, :id if _has_attribute?("id") && !_has_attribute?("id_value")
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
generate_alias_attributes
|
|
120
|
+
|
|
56
121
|
@attribute_methods_generated = true
|
|
57
122
|
end
|
|
123
|
+
|
|
124
|
+
true
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def generate_alias_attributes # :nodoc:
|
|
128
|
+
superclass.generate_alias_attributes unless superclass == Base
|
|
129
|
+
|
|
130
|
+
return if @alias_attributes_mass_generated
|
|
131
|
+
|
|
132
|
+
ActiveSupport::CodeGenerator.batch(generated_attribute_methods, __FILE__, __LINE__) do |code_generator|
|
|
133
|
+
aliases_by_attribute_name.each do |old_name, new_names|
|
|
134
|
+
new_names.each do |new_name|
|
|
135
|
+
generate_alias_attribute_methods(code_generator, new_name, old_name)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
@alias_attributes_mass_generated = true
|
|
58
141
|
end
|
|
59
142
|
|
|
60
143
|
def undefine_attribute_methods # :nodoc:
|
|
61
|
-
|
|
62
|
-
super if
|
|
144
|
+
GeneratedAttributeMethods::LOCK.synchronize do
|
|
145
|
+
super if @attribute_methods_generated
|
|
63
146
|
@attribute_methods_generated = false
|
|
147
|
+
@alias_attributes_mass_generated = false
|
|
64
148
|
end
|
|
65
149
|
end
|
|
66
150
|
|
|
@@ -87,7 +171,7 @@ module ActiveRecord
|
|
|
87
171
|
super
|
|
88
172
|
else
|
|
89
173
|
# If ThisClass < ... < SomeSuperClass < ... < Base and SomeSuperClass
|
|
90
|
-
# defines its own attribute method, then we don't want to
|
|
174
|
+
# defines its own attribute method, then we don't want to override that.
|
|
91
175
|
defined = method_defined_within?(method_name, superclass, Base) &&
|
|
92
176
|
! superclass.instance_method(method_name).owner.is_a?(GeneratedAttributeMethods)
|
|
93
177
|
defined || super
|
|
@@ -97,7 +181,7 @@ module ActiveRecord
|
|
|
97
181
|
# A method name is 'dangerous' if it is already (re)defined by Active Record, but
|
|
98
182
|
# not by any ancestors. (So 'puts' is not dangerous but 'save' is.)
|
|
99
183
|
def dangerous_attribute_method?(name) # :nodoc:
|
|
100
|
-
|
|
184
|
+
::ActiveRecord::AttributeMethods.dangerous_attribute_methods.include?(name.to_s)
|
|
101
185
|
end
|
|
102
186
|
|
|
103
187
|
def method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc:
|
|
@@ -115,13 +199,11 @@ module ActiveRecord
|
|
|
115
199
|
# A class method is 'dangerous' if it is already (re)defined by Active Record, but
|
|
116
200
|
# not by any ancestors. (So 'puts' is not dangerous but 'new' is.)
|
|
117
201
|
def dangerous_class_method?(method_name)
|
|
118
|
-
RESTRICTED_CLASS_METHODS.include?(method_name.to_s)
|
|
119
|
-
end
|
|
202
|
+
return true if RESTRICTED_CLASS_METHODS.include?(method_name.to_s)
|
|
120
203
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
klass.method(name).owner != superklass.method(name).owner
|
|
204
|
+
if Base.respond_to?(method_name, true)
|
|
205
|
+
if Object.respond_to?(method_name, true)
|
|
206
|
+
Base.method(method_name).owner != Object.method(method_name).owner
|
|
125
207
|
else
|
|
126
208
|
true
|
|
127
209
|
end
|
|
@@ -140,7 +222,7 @@ module ActiveRecord
|
|
|
140
222
|
# Person.attribute_method?(:age=) # => true
|
|
141
223
|
# Person.attribute_method?(:nothing) # => false
|
|
142
224
|
def attribute_method?(attribute)
|
|
143
|
-
super || (table_exists? && column_names.include?(attribute.to_s.
|
|
225
|
+
super || (table_exists? && column_names.include?(attribute.to_s.delete_suffix("=")))
|
|
144
226
|
end
|
|
145
227
|
|
|
146
228
|
# Returns an array of column names as strings if it's not an abstract class and
|
|
@@ -156,40 +238,38 @@ module ActiveRecord
|
|
|
156
238
|
attribute_types.keys
|
|
157
239
|
else
|
|
158
240
|
[]
|
|
159
|
-
end
|
|
241
|
+
end.freeze
|
|
160
242
|
end
|
|
161
243
|
|
|
162
244
|
# Returns true if the given attribute exists, otherwise false.
|
|
163
245
|
#
|
|
164
246
|
# class Person < ActiveRecord::Base
|
|
247
|
+
# alias_attribute :new_name, :name
|
|
165
248
|
# end
|
|
166
249
|
#
|
|
167
|
-
# Person.has_attribute?('name')
|
|
168
|
-
# Person.has_attribute?(
|
|
169
|
-
# Person.has_attribute?(:
|
|
250
|
+
# Person.has_attribute?('name') # => true
|
|
251
|
+
# Person.has_attribute?('new_name') # => true
|
|
252
|
+
# Person.has_attribute?(:age) # => true
|
|
253
|
+
# Person.has_attribute?(:nothing) # => false
|
|
170
254
|
def has_attribute?(attr_name)
|
|
171
|
-
|
|
255
|
+
attr_name = attr_name.to_s
|
|
256
|
+
attr_name = attribute_aliases[attr_name] || attr_name
|
|
257
|
+
attribute_types.key?(attr_name)
|
|
172
258
|
end
|
|
173
259
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
# named attribute does not exist.
|
|
177
|
-
#
|
|
178
|
-
# class Person < ActiveRecord::Base
|
|
179
|
-
# end
|
|
180
|
-
#
|
|
181
|
-
# person = Person.new
|
|
182
|
-
# person.column_for_attribute(:name) # the result depends on the ConnectionAdapter
|
|
183
|
-
# # => #<ActiveRecord::ConnectionAdapters::Column:0x007ff4ab083980 @name="name", @sql_type="varchar(255)", @null=true, ...>
|
|
184
|
-
#
|
|
185
|
-
# person.column_for_attribute(:nothing)
|
|
186
|
-
# # => #<ActiveRecord::ConnectionAdapters::NullColumn:0xXXX @name=nil, @sql_type=nil, @cast_type=#<Type::Value>, ...>
|
|
187
|
-
def column_for_attribute(name)
|
|
188
|
-
name = name.to_s
|
|
189
|
-
columns_hash.fetch(name) do
|
|
190
|
-
ConnectionAdapters::NullColumn.new(name)
|
|
191
|
-
end
|
|
260
|
+
def _has_attribute?(attr_name) # :nodoc:
|
|
261
|
+
attribute_types.key?(attr_name)
|
|
192
262
|
end
|
|
263
|
+
|
|
264
|
+
private
|
|
265
|
+
def inherited(child_class)
|
|
266
|
+
super
|
|
267
|
+
child_class.initialize_generated_modules
|
|
268
|
+
child_class.class_eval do
|
|
269
|
+
@alias_attributes_mass_generated = false
|
|
270
|
+
@attribute_names = nil
|
|
271
|
+
end
|
|
272
|
+
end
|
|
193
273
|
end
|
|
194
274
|
|
|
195
275
|
# A Person object with a name attribute can ask <tt>person.respond_to?(:name)</tt>,
|
|
@@ -213,11 +293,9 @@ module ActiveRecord
|
|
|
213
293
|
|
|
214
294
|
# If the result is true then check for the select case.
|
|
215
295
|
# For queries selecting a subset of columns, return false for unselected columns.
|
|
216
|
-
|
|
217
|
-
# have been allocated but not yet initialized.
|
|
218
|
-
if defined?(@attributes)
|
|
296
|
+
if @attributes
|
|
219
297
|
if name = self.class.symbol_column_to_string(name.to_sym)
|
|
220
|
-
return
|
|
298
|
+
return _has_attribute?(name)
|
|
221
299
|
end
|
|
222
300
|
end
|
|
223
301
|
|
|
@@ -227,14 +305,22 @@ module ActiveRecord
|
|
|
227
305
|
# Returns +true+ if the given attribute is in the attributes hash, otherwise +false+.
|
|
228
306
|
#
|
|
229
307
|
# class Person < ActiveRecord::Base
|
|
308
|
+
# alias_attribute :new_name, :name
|
|
230
309
|
# end
|
|
231
310
|
#
|
|
232
311
|
# person = Person.new
|
|
233
|
-
# person.has_attribute?(:name)
|
|
234
|
-
# person.has_attribute?(
|
|
235
|
-
# person.has_attribute?(
|
|
312
|
+
# person.has_attribute?(:name) # => true
|
|
313
|
+
# person.has_attribute?(:new_name) # => true
|
|
314
|
+
# person.has_attribute?('age') # => true
|
|
315
|
+
# person.has_attribute?(:nothing) # => false
|
|
236
316
|
def has_attribute?(attr_name)
|
|
237
|
-
|
|
317
|
+
attr_name = attr_name.to_s
|
|
318
|
+
attr_name = self.class.attribute_aliases[attr_name] || attr_name
|
|
319
|
+
@attributes.key?(attr_name)
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
def _has_attribute?(attr_name) # :nodoc:
|
|
323
|
+
@attributes.key?(attr_name)
|
|
238
324
|
end
|
|
239
325
|
|
|
240
326
|
# Returns an array of names for the attributes available on this object.
|
|
@@ -263,9 +349,8 @@ module ActiveRecord
|
|
|
263
349
|
|
|
264
350
|
# Returns an <tt>#inspect</tt>-like string for the value of the
|
|
265
351
|
# attribute +attr_name+. String attributes are truncated up to 50
|
|
266
|
-
# characters
|
|
267
|
-
#
|
|
268
|
-
# <tt>#inspect</tt> without modification.
|
|
352
|
+
# characters. Other attributes return the value of <tt>#inspect</tt>
|
|
353
|
+
# without modification.
|
|
269
354
|
#
|
|
270
355
|
# person = Person.create!(name: 'David Heinemeier Hansson ' * 3)
|
|
271
356
|
#
|
|
@@ -273,13 +358,15 @@ module ActiveRecord
|
|
|
273
358
|
# # => "\"David Heinemeier Hansson David Heinemeier Hansson ...\""
|
|
274
359
|
#
|
|
275
360
|
# person.attribute_for_inspect(:created_at)
|
|
276
|
-
# # => "\"2012-10-22 00:15:07\""
|
|
361
|
+
# # => "\"2012-10-22 00:15:07.000000000 +0000\""
|
|
277
362
|
#
|
|
278
363
|
# person.attribute_for_inspect(:tag_ids)
|
|
279
364
|
# # => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]"
|
|
280
365
|
def attribute_for_inspect(attr_name)
|
|
366
|
+
attr_name = attr_name.to_s
|
|
367
|
+
attr_name = self.class.attribute_aliases[attr_name] || attr_name
|
|
281
368
|
value = _read_attribute(attr_name)
|
|
282
|
-
format_for_inspect(value)
|
|
369
|
+
format_for_inspect(attr_name, value)
|
|
283
370
|
end
|
|
284
371
|
|
|
285
372
|
# Returns +true+ if the specified +attribute+ has been set by the user or by a
|
|
@@ -297,42 +384,47 @@ module ActiveRecord
|
|
|
297
384
|
# task.is_done = true
|
|
298
385
|
# task.attribute_present?(:title) # => true
|
|
299
386
|
# task.attribute_present?(:is_done) # => true
|
|
300
|
-
def attribute_present?(
|
|
301
|
-
|
|
387
|
+
def attribute_present?(attr_name)
|
|
388
|
+
attr_name = attr_name.to_s
|
|
389
|
+
attr_name = self.class.attribute_aliases[attr_name] || attr_name
|
|
390
|
+
value = _read_attribute(attr_name)
|
|
302
391
|
!value.nil? && !(value.respond_to?(:empty?) && value.empty?)
|
|
303
392
|
end
|
|
304
393
|
|
|
305
|
-
# Returns the value of the attribute identified by
|
|
306
|
-
#
|
|
307
|
-
#
|
|
308
|
-
#
|
|
309
|
-
# Note: +:id+ is always present.
|
|
394
|
+
# Returns the value of the attribute identified by +attr_name+ after it has
|
|
395
|
+
# been type cast. (For information about specific type casting behavior, see
|
|
396
|
+
# the types under ActiveModel::Type.)
|
|
310
397
|
#
|
|
311
398
|
# class Person < ActiveRecord::Base
|
|
312
399
|
# belongs_to :organization
|
|
313
400
|
# end
|
|
314
401
|
#
|
|
315
|
-
# person = Person.new(name:
|
|
316
|
-
# person[:name]
|
|
317
|
-
# person[:
|
|
402
|
+
# person = Person.new(name: "Francesco", date_of_birth: "2004-12-12")
|
|
403
|
+
# person[:name] # => "Francesco"
|
|
404
|
+
# person[:date_of_birth] # => Date.new(2004, 12, 12)
|
|
405
|
+
# person[:organization_id] # => nil
|
|
406
|
+
#
|
|
407
|
+
# Raises ActiveModel::MissingAttributeError if the attribute is missing.
|
|
408
|
+
# Note, however, that the +id+ attribute will never be considered missing.
|
|
318
409
|
#
|
|
319
|
-
# person = Person.select(
|
|
320
|
-
# person[:name] # =>
|
|
321
|
-
# person[:
|
|
410
|
+
# person = Person.select(:name).first
|
|
411
|
+
# person[:name] # => "Francesco"
|
|
412
|
+
# person[:date_of_birth] # => ActiveModel::MissingAttributeError: missing attribute 'date_of_birth' for Person
|
|
413
|
+
# person[:organization_id] # => ActiveModel::MissingAttributeError: missing attribute 'organization_id' for Person
|
|
414
|
+
# person[:id] # => nil
|
|
322
415
|
def [](attr_name)
|
|
323
416
|
read_attribute(attr_name) { |n| missing_attribute(n, caller) }
|
|
324
417
|
end
|
|
325
418
|
|
|
326
|
-
# Updates the attribute identified by
|
|
327
|
-
#
|
|
419
|
+
# Updates the attribute identified by +attr_name+ using the specified
|
|
420
|
+
# +value+. The attribute value will be type cast upon being read.
|
|
328
421
|
#
|
|
329
422
|
# class Person < ActiveRecord::Base
|
|
330
423
|
# end
|
|
331
424
|
#
|
|
332
425
|
# person = Person.new
|
|
333
|
-
# person[:
|
|
334
|
-
# person[:
|
|
335
|
-
# person[:age].class # => Integer
|
|
426
|
+
# person[:date_of_birth] = "2004-12-12"
|
|
427
|
+
# person[:date_of_birth] # => Date.new(2004, 12, 12)
|
|
336
428
|
def []=(attr_name, value)
|
|
337
429
|
write_attribute(attr_name, value)
|
|
338
430
|
end
|
|
@@ -353,10 +445,9 @@ module ActiveRecord
|
|
|
353
445
|
# end
|
|
354
446
|
#
|
|
355
447
|
# private
|
|
356
|
-
#
|
|
357
|
-
#
|
|
358
|
-
#
|
|
359
|
-
# end
|
|
448
|
+
# def print_accessed_fields
|
|
449
|
+
# p @posts.first.accessed_fields
|
|
450
|
+
# end
|
|
360
451
|
# end
|
|
361
452
|
#
|
|
362
453
|
# Which allows you to quickly change your code to:
|
|
@@ -371,46 +462,82 @@ module ActiveRecord
|
|
|
371
462
|
end
|
|
372
463
|
|
|
373
464
|
private
|
|
465
|
+
def respond_to_missing?(name, include_private = false)
|
|
466
|
+
if self.class.define_attribute_methods
|
|
467
|
+
# Some methods weren't defined yet.
|
|
468
|
+
return true if self.class.method_defined?(name)
|
|
469
|
+
return true if include_private && self.class.private_method_defined?(name)
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
super
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
def method_missing(name, ...)
|
|
476
|
+
# We can't know whether some method was defined or not because
|
|
477
|
+
# multiple thread might be concurrently be in this code path.
|
|
478
|
+
# So the first one would define the methods and the others would
|
|
479
|
+
# appear to already have them.
|
|
480
|
+
self.class.define_attribute_methods
|
|
481
|
+
|
|
482
|
+
# So in all cases we must behave as if the method was just defined.
|
|
483
|
+
method = begin
|
|
484
|
+
self.class.public_instance_method(name)
|
|
485
|
+
rescue NameError
|
|
486
|
+
nil
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
# The method might be explicitly defined in the model, but call a generated
|
|
490
|
+
# method with super. So we must resume the call chain at the right step.
|
|
491
|
+
method = method.super_method while method && !method.owner.is_a?(GeneratedAttributeMethods)
|
|
492
|
+
if method
|
|
493
|
+
method.bind_call(self, ...)
|
|
494
|
+
else
|
|
495
|
+
super
|
|
496
|
+
end
|
|
497
|
+
end
|
|
498
|
+
|
|
374
499
|
def attribute_method?(attr_name)
|
|
375
|
-
|
|
376
|
-
defined?(@attributes) && @attributes.key?(attr_name)
|
|
500
|
+
@attributes&.key?(attr_name)
|
|
377
501
|
end
|
|
378
502
|
|
|
379
503
|
def attributes_with_values(attribute_names)
|
|
380
|
-
attribute_names.
|
|
381
|
-
attrs[name] = _read_attribute(name)
|
|
382
|
-
end
|
|
504
|
+
attribute_names.index_with { |name| @attributes[name] }
|
|
383
505
|
end
|
|
384
506
|
|
|
385
|
-
# Filters the primary keys
|
|
507
|
+
# Filters the primary keys, readonly attributes and virtual columns from the attribute names.
|
|
386
508
|
def attributes_for_update(attribute_names)
|
|
387
509
|
attribute_names &= self.class.column_names
|
|
388
510
|
attribute_names.delete_if do |name|
|
|
389
|
-
readonly_attribute?(name)
|
|
511
|
+
self.class.readonly_attribute?(name) ||
|
|
512
|
+
self.class.counter_cache_column?(name) ||
|
|
513
|
+
column_for_attribute(name).virtual?
|
|
390
514
|
end
|
|
391
515
|
end
|
|
392
516
|
|
|
393
|
-
# Filters out the primary keys, from the attribute names, when the primary
|
|
517
|
+
# Filters out the virtual columns and also primary keys, from the attribute names, when the primary
|
|
394
518
|
# key is to be generated (e.g. the id attribute has no value).
|
|
395
519
|
def attributes_for_create(attribute_names)
|
|
396
520
|
attribute_names &= self.class.column_names
|
|
397
521
|
attribute_names.delete_if do |name|
|
|
398
|
-
pk_attribute?(name) && id.nil?
|
|
522
|
+
(pk_attribute?(name) && id.nil?) ||
|
|
523
|
+
column_for_attribute(name).virtual?
|
|
399
524
|
end
|
|
400
525
|
end
|
|
401
526
|
|
|
402
|
-
def format_for_inspect(value)
|
|
403
|
-
if value.
|
|
404
|
-
"#{value[0, 50]}...".inspect
|
|
405
|
-
elsif value.is_a?(Date) || value.is_a?(Time)
|
|
406
|
-
%("#{value.to_s(:db)}")
|
|
407
|
-
else
|
|
527
|
+
def format_for_inspect(name, value)
|
|
528
|
+
if value.nil?
|
|
408
529
|
value.inspect
|
|
409
|
-
|
|
410
|
-
|
|
530
|
+
else
|
|
531
|
+
inspected_value = if value.is_a?(String) && value.length > 50
|
|
532
|
+
"#{value[0, 50]}...".inspect
|
|
533
|
+
elsif value.is_a?(Date) || value.is_a?(Time)
|
|
534
|
+
%("#{value.to_fs(:inspect)}")
|
|
535
|
+
else
|
|
536
|
+
value.inspect
|
|
537
|
+
end
|
|
411
538
|
|
|
412
|
-
|
|
413
|
-
|
|
539
|
+
inspection_filter.filter_param(name, inspected_value)
|
|
540
|
+
end
|
|
414
541
|
end
|
|
415
542
|
|
|
416
543
|
def pk_attribute?(name)
|