activerecord 4.2.11.1 → 6.0.3.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +721 -1522
- data/MIT-LICENSE +4 -2
- data/README.rdoc +14 -13
- data/examples/performance.rb +33 -32
- data/examples/simple.rb +5 -4
- data/lib/active_record/advisory_lock_base.rb +18 -0
- data/lib/active_record/aggregations.rb +266 -251
- data/lib/active_record/association_relation.rb +20 -13
- data/lib/active_record/associations/alias_tracker.rb +29 -36
- data/lib/active_record/associations/association.rb +128 -57
- data/lib/active_record/associations/association_scope.rb +103 -132
- data/lib/active_record/associations/belongs_to_association.rb +65 -60
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
- data/lib/active_record/associations/builder/association.rb +27 -40
- data/lib/active_record/associations/builder/belongs_to.rb +69 -55
- data/lib/active_record/associations/builder/collection_association.rb +10 -33
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +50 -66
- data/lib/active_record/associations/builder/has_many.rb +8 -4
- data/lib/active_record/associations/builder/has_one.rb +46 -5
- data/lib/active_record/associations/builder/singular_association.rb +16 -10
- data/lib/active_record/associations/collection_association.rb +136 -288
- data/lib/active_record/associations/collection_proxy.rb +241 -147
- data/lib/active_record/associations/foreign_association.rb +10 -1
- data/lib/active_record/associations/has_many_association.rb +34 -98
- data/lib/active_record/associations/has_many_through_association.rb +60 -87
- data/lib/active_record/associations/has_one_association.rb +61 -49
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency/join_association.rb +38 -86
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
- data/lib/active_record/associations/join_dependency.rb +149 -166
- data/lib/active_record/associations/preloader/association.rb +90 -123
- data/lib/active_record/associations/preloader/through_association.rb +85 -65
- data/lib/active_record/associations/preloader.rb +90 -93
- data/lib/active_record/associations/singular_association.rb +18 -39
- data/lib/active_record/associations/through_association.rb +38 -18
- data/lib/active_record/associations.rb +1737 -1597
- data/lib/active_record/attribute_assignment.rb +57 -185
- data/lib/active_record/attribute_decorators.rb +39 -17
- data/lib/active_record/attribute_methods/before_type_cast.rb +13 -9
- data/lib/active_record/attribute_methods/dirty.rb +174 -144
- data/lib/active_record/attribute_methods/primary_key.rb +90 -84
- data/lib/active_record/attribute_methods/query.rb +6 -5
- data/lib/active_record/attribute_methods/read.rb +20 -77
- data/lib/active_record/attribute_methods/serialization.rb +40 -21
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +57 -37
- data/lib/active_record/attribute_methods/write.rb +32 -55
- data/lib/active_record/attribute_methods.rb +120 -135
- data/lib/active_record/attributes.rb +213 -82
- data/lib/active_record/autosave_association.rb +97 -41
- data/lib/active_record/base.rb +57 -45
- data/lib/active_record/callbacks.rb +101 -76
- data/lib/active_record/coders/json.rb +3 -1
- data/lib/active_record/coders/yaml_column.rb +23 -12
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +804 -297
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +240 -115
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +83 -24
- data/lib/active_record/connection_adapters/abstract/quoting.rb +170 -53
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -47
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +371 -242
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +694 -256
- data/lib/active_record/connection_adapters/abstract/transaction.rb +190 -83
- data/lib/active_record/connection_adapters/abstract_adapter.rb +473 -202
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +507 -639
- data/lib/active_record/connection_adapters/column.rb +56 -43
- data/lib/active_record/connection_adapters/connection_specification.rb +174 -153
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +196 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +71 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +58 -181
- data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +70 -114
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +49 -58
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -22
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -20
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
- data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +51 -34
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +9 -5
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +144 -47
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +462 -296
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +558 -356
- data/lib/active_record/connection_adapters/schema_cache.rb +72 -25
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +299 -349
- data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
- data/lib/active_record/connection_handling.rb +167 -41
- data/lib/active_record/core.rb +252 -230
- data/lib/active_record/counter_cache.rb +70 -49
- data/lib/active_record/database_configurations/database_config.rb +37 -0
- data/lib/active_record/database_configurations/hash_config.rb +50 -0
- data/lib/active_record/database_configurations/url_config.rb +78 -0
- data/lib/active_record/database_configurations.rb +233 -0
- data/lib/active_record/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +87 -106
- data/lib/active_record/enum.rb +163 -86
- data/lib/active_record/errors.rb +188 -53
- data/lib/active_record/explain.rb +22 -11
- data/lib/active_record/explain_registry.rb +4 -2
- data/lib/active_record/explain_subscriber.rb +10 -5
- data/lib/active_record/fixture_set/file.rb +35 -9
- data/lib/active_record/fixture_set/model_metadata.rb +33 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +227 -501
- data/lib/active_record/gem_version.rb +6 -4
- data/lib/active_record/inheritance.rb +158 -115
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +123 -29
- data/lib/active_record/internal_metadata.rb +53 -0
- data/lib/active_record/legacy_yaml_adapter.rb +21 -3
- data/lib/active_record/locale/en.yml +3 -2
- data/lib/active_record/locking/optimistic.rb +86 -96
- data/lib/active_record/locking/pessimistic.rb +18 -6
- data/lib/active_record/log_subscriber.rb +76 -33
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
- data/lib/active_record/middleware/database_selector.rb +74 -0
- data/lib/active_record/migration/command_recorder.rb +166 -91
- data/lib/active_record/migration/compatibility.rb +244 -0
- data/lib/active_record/migration/join_table.rb +8 -7
- data/lib/active_record/migration.rb +623 -305
- data/lib/active_record/model_schema.rb +313 -112
- data/lib/active_record/nested_attributes.rb +263 -223
- data/lib/active_record/no_touching.rb +15 -2
- data/lib/active_record/null_relation.rb +24 -38
- data/lib/active_record/persistence.rb +557 -126
- data/lib/active_record/query_cache.rb +19 -23
- data/lib/active_record/querying.rb +44 -30
- data/lib/active_record/railtie.rb +143 -44
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +34 -33
- data/lib/active_record/railties/databases.rake +331 -185
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +430 -281
- data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
- data/lib/active_record/relation/batches.rb +206 -55
- data/lib/active_record/relation/calculations.rb +268 -254
- data/lib/active_record/relation/delegation.rb +75 -84
- data/lib/active_record/relation/finder_methods.rb +285 -241
- data/lib/active_record/relation/from_clause.rb +30 -0
- data/lib/active_record/relation/merger.rb +78 -88
- data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -26
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
- data/lib/active_record/relation/predicate_builder.rb +110 -119
- data/lib/active_record/relation/query_attribute.rb +50 -0
- data/lib/active_record/relation/query_methods.rb +603 -397
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +11 -14
- data/lib/active_record/relation/where_clause.rb +189 -0
- data/lib/active_record/relation/where_clause_factory.rb +33 -0
- data/lib/active_record/relation.rb +530 -341
- data/lib/active_record/result.rb +79 -43
- data/lib/active_record/runtime_registry.rb +6 -4
- data/lib/active_record/sanitization.rb +144 -121
- data/lib/active_record/schema.rb +21 -24
- data/lib/active_record/schema_dumper.rb +112 -93
- data/lib/active_record/schema_migration.rb +24 -17
- data/lib/active_record/scoping/default.rb +98 -83
- data/lib/active_record/scoping/named.rb +86 -33
- data/lib/active_record/scoping.rb +45 -27
- data/lib/active_record/secure_token.rb +40 -0
- data/lib/active_record/serialization.rb +5 -5
- data/lib/active_record/statement_cache.rb +73 -36
- data/lib/active_record/store.rb +127 -42
- data/lib/active_record/suppressor.rb +61 -0
- data/lib/active_record/table_metadata.rb +90 -0
- data/lib/active_record/tasks/database_tasks.rb +307 -100
- data/lib/active_record/tasks/mysql_database_tasks.rb +55 -100
- data/lib/active_record/tasks/postgresql_database_tasks.rb +80 -41
- data/lib/active_record/tasks/sqlite_database_tasks.rb +37 -16
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +225 -0
- data/lib/active_record/timestamp.rb +86 -41
- data/lib/active_record/touch_later.rb +65 -0
- data/lib/active_record/transactions.rb +223 -157
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type/adapter_specific_registry.rb +126 -0
- data/lib/active_record/type/date.rb +4 -45
- data/lib/active_record/type/date_time.rb +4 -49
- data/lib/active_record/type/decimal_without_scale.rb +6 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
- data/lib/active_record/type/internal/timezone.rb +17 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +23 -15
- data/lib/active_record/type/text.rb +2 -2
- data/lib/active_record/type/time.rb +11 -16
- data/lib/active_record/type/type_map.rb +16 -19
- data/lib/active_record/type/unsigned_integer.rb +9 -8
- data/lib/active_record/type.rb +77 -23
- data/lib/active_record/type_caster/connection.rb +34 -0
- data/lib/active_record/type_caster/map.rb +20 -0
- data/lib/active_record/type_caster.rb +9 -0
- data/lib/active_record/validations/absence.rb +25 -0
- data/lib/active_record/validations/associated.rb +12 -4
- data/lib/active_record/validations/length.rb +26 -0
- data/lib/active_record/validations/presence.rb +14 -13
- data/lib/active_record/validations/uniqueness.rb +42 -55
- data/lib/active_record/validations.rb +38 -35
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +42 -22
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +37 -0
- data/lib/arel/attributes.rb +22 -0
- data/lib/arel/collectors/bind.rb +24 -0
- data/lib/arel/collectors/composite.rb +31 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +20 -0
- data/lib/arel/collectors/substitute_binds.rb +28 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -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/insert_manager.rb +49 -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 +52 -0
- data/lib/arel/nodes/bind_param.rb +36 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +50 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +18 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +8 -0
- data/lib/arel/nodes/in.rb +8 -0
- data/lib/arel/nodes/infix_operation.rb +80 -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 +50 -0
- data/lib/arel/nodes/node_expression.rb +13 -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 +16 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +27 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +45 -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 +41 -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 +68 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +256 -0
- data/lib/arel/select_manager.rb +271 -0
- data/lib/arel/table.rb +110 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors/depth_first.rb +203 -0
- data/lib/arel/visitors/dot.rb +296 -0
- data/lib/arel/visitors/ibm_db.rb +34 -0
- data/lib/arel/visitors/informix.rb +62 -0
- data/lib/arel/visitors/mssql.rb +156 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +158 -0
- data/lib/arel/visitors/oracle12.rb +65 -0
- data/lib/arel/visitors/postgresql.rb +109 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +888 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/visitors/where_sql.rb +22 -0
- data/lib/arel/visitors.rb +20 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +62 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -2
- data/lib/rails/generators/active_record/migration.rb +30 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +18 -22
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +168 -59
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -24
- data/lib/active_record/associations/preloader/has_many.rb +0 -17
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -23
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -21
- data/lib/active_record/attribute.rb +0 -163
- data/lib/active_record/attribute_set/builder.rb +0 -106
- data/lib/active_record/attribute_set.rb +0 -81
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
- data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
- data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/serializers/xml_serializer.rb +0 -193
- data/lib/active_record/type/big_integer.rb +0 -13
- data/lib/active_record/type/binary.rb +0 -50
- data/lib/active_record/type/boolean.rb +0 -31
- data/lib/active_record/type/decimal.rb +0 -64
- data/lib/active_record/type/decorator.rb +0 -14
- data/lib/active_record/type/float.rb +0 -19
- data/lib/active_record/type/integer.rb +0 -59
- data/lib/active_record/type/mutable.rb +0 -16
- data/lib/active_record/type/numeric.rb +0 -36
- data/lib/active_record/type/string.rb +0 -40
- data/lib/active_record/type/time_value.rb +0 -38
- data/lib/active_record/type/value.rb +0 -110
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
- data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
data/lib/active_record/core.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/hash/indifferent_access"
|
4
|
+
require "active_support/core_ext/string/filters"
|
5
|
+
require "active_support/parameter_filter"
|
6
|
+
require "concurrent/map"
|
5
7
|
|
6
8
|
module ActiveRecord
|
7
9
|
module Core
|
@@ -16,9 +18,16 @@ module ActiveRecord
|
|
16
18
|
# retrieved on both a class and instance level by calling +logger+.
|
17
19
|
mattr_accessor :logger, instance_writer: false
|
18
20
|
|
21
|
+
##
|
22
|
+
# :singleton-method:
|
23
|
+
#
|
24
|
+
# Specifies if the methods calling database queries should be logged below
|
25
|
+
# their relevant queries. Defaults to false.
|
26
|
+
mattr_accessor :verbose_query_logs, instance_writer: false, default: false
|
27
|
+
|
19
28
|
##
|
20
29
|
# Contains the database configuration - as is typically stored in config/database.yml -
|
21
|
-
# as
|
30
|
+
# as an ActiveRecord::DatabaseConfigurations object.
|
22
31
|
#
|
23
32
|
# For example, the following database.yml...
|
24
33
|
#
|
@@ -32,22 +41,18 @@ module ActiveRecord
|
|
32
41
|
#
|
33
42
|
# ...would result in ActiveRecord::Base.configurations to look like this:
|
34
43
|
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
# 'adapter' => 'sqlite3',
|
42
|
-
# 'database' => 'db/production.sqlite3'
|
43
|
-
# }
|
44
|
-
# }
|
44
|
+
# #<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[
|
45
|
+
# #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
|
46
|
+
# @spec_name="primary", @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>,
|
47
|
+
# #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90 @env_name="production",
|
48
|
+
# @spec_name="primary", @config={"adapter"=>"mysql2", "database"=>"db/production.sqlite3"}>
|
49
|
+
# ]>
|
45
50
|
def self.configurations=(config)
|
46
|
-
@@configurations = ActiveRecord::
|
51
|
+
@@configurations = ActiveRecord::DatabaseConfigurations.new(config)
|
47
52
|
end
|
48
53
|
self.configurations = {}
|
49
54
|
|
50
|
-
# Returns fully resolved
|
55
|
+
# Returns fully resolved ActiveRecord::DatabaseConfigurations object
|
51
56
|
def self.configurations
|
52
57
|
@@configurations
|
53
58
|
end
|
@@ -56,8 +61,7 @@ module ActiveRecord
|
|
56
61
|
# :singleton-method:
|
57
62
|
# Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling
|
58
63
|
# dates and times from the database. This is set to :utc by default.
|
59
|
-
mattr_accessor :default_timezone, instance_writer: false
|
60
|
-
self.default_timezone = :utc
|
64
|
+
mattr_accessor :default_timezone, instance_writer: false, default: :utc
|
61
65
|
|
62
66
|
##
|
63
67
|
# :singleton-method:
|
@@ -67,58 +71,85 @@ module ActiveRecord
|
|
67
71
|
# ActiveRecord::Schema file which can be loaded into any database that
|
68
72
|
# supports migrations. Use :ruby if you want to have different database
|
69
73
|
# adapters for, e.g., your development and test environments.
|
70
|
-
mattr_accessor :schema_format, instance_writer: false
|
71
|
-
|
74
|
+
mattr_accessor :schema_format, instance_writer: false, default: :ruby
|
75
|
+
|
76
|
+
##
|
77
|
+
# :singleton-method:
|
78
|
+
# Specifies if an error should be raised if the query has an order being
|
79
|
+
# ignored when doing batch queries. Useful in applications where the
|
80
|
+
# scope being ignored is error-worthy, rather than a warning.
|
81
|
+
mattr_accessor :error_on_ignored_order, instance_writer: false, default: false
|
82
|
+
|
83
|
+
# :singleton-method:
|
84
|
+
# Specify the behavior for unsafe raw query methods. Values are as follows
|
85
|
+
# deprecated - Warnings are logged when unsafe raw SQL is passed to
|
86
|
+
# query methods.
|
87
|
+
# disabled - Unsafe raw SQL passed to query methods results in
|
88
|
+
# UnknownAttributeReference exception.
|
89
|
+
mattr_accessor :allow_unsafe_raw_sql, instance_writer: false, default: :deprecated
|
72
90
|
|
73
91
|
##
|
74
92
|
# :singleton-method:
|
75
93
|
# Specify whether or not to use timestamps for migration versions
|
76
|
-
mattr_accessor :timestamped_migrations, instance_writer: false
|
77
|
-
self.timestamped_migrations = true
|
94
|
+
mattr_accessor :timestamped_migrations, instance_writer: false, default: true
|
78
95
|
|
79
96
|
##
|
80
97
|
# :singleton-method:
|
81
98
|
# Specify whether schema dump should happen at the end of the
|
82
|
-
# db:migrate
|
99
|
+
# db:migrate rails command. This is true by default, which is useful for the
|
83
100
|
# development environment. This should ideally be false in the production
|
84
101
|
# environment where dumping schema is rarely needed.
|
85
|
-
mattr_accessor :dump_schema_after_migration, instance_writer: false
|
86
|
-
|
102
|
+
mattr_accessor :dump_schema_after_migration, instance_writer: false, default: true
|
103
|
+
|
104
|
+
##
|
105
|
+
# :singleton-method:
|
106
|
+
# Specifies which database schemas to dump when calling db:structure:dump.
|
107
|
+
# If the value is :schema_search_path (the default), any schemas listed in
|
108
|
+
# schema_search_path are dumped. Use :all to dump all schemas regardless
|
109
|
+
# of schema_search_path, or a string of comma separated schemas for a
|
110
|
+
# custom list.
|
111
|
+
mattr_accessor :dump_schemas, instance_writer: false, default: :schema_search_path
|
112
|
+
|
113
|
+
##
|
114
|
+
# :singleton-method:
|
115
|
+
# Specify a threshold for the size of query result sets. If the number of
|
116
|
+
# records in the set exceeds the threshold, a warning is logged. This can
|
117
|
+
# be used to identify queries which load thousands of records and
|
118
|
+
# potentially cause memory bloat.
|
119
|
+
mattr_accessor :warn_on_records_fetched_greater_than, instance_writer: false
|
87
120
|
|
88
121
|
mattr_accessor :maintain_test_schema, instance_accessor: false
|
89
122
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
123
|
+
mattr_accessor :belongs_to_required_by_default, instance_accessor: false
|
124
|
+
|
125
|
+
mattr_accessor :connection_handlers, instance_accessor: false, default: {}
|
126
|
+
|
127
|
+
mattr_accessor :writing_role, instance_accessor: false, default: :writing
|
128
|
+
|
129
|
+
mattr_accessor :reading_role, instance_accessor: false, default: :reading
|
96
130
|
|
97
131
|
class_attribute :default_connection_handler, instance_writer: false
|
98
|
-
|
132
|
+
|
133
|
+
self.filter_attributes = []
|
99
134
|
|
100
135
|
def self.connection_handler
|
101
|
-
|
136
|
+
Thread.current.thread_variable_get("ar_connection_handler") || default_connection_handler
|
102
137
|
end
|
103
138
|
|
104
139
|
def self.connection_handler=(handler)
|
105
|
-
|
140
|
+
Thread.current.thread_variable_set("ar_connection_handler", handler)
|
106
141
|
end
|
107
142
|
|
108
143
|
self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
|
109
144
|
end
|
110
145
|
|
111
146
|
module ClassMethods
|
112
|
-
def allocate
|
113
|
-
define_attribute_methods
|
114
|
-
super
|
115
|
-
end
|
116
|
-
|
117
147
|
def initialize_find_by_cache # :nodoc:
|
118
|
-
|
148
|
+
@find_by_statement_cache = { true => Concurrent::Map.new, false => Concurrent::Map.new }
|
119
149
|
end
|
120
150
|
|
121
151
|
def inherited(child_class) # :nodoc:
|
152
|
+
# initialize cache at class definition for thread safety
|
122
153
|
child_class.initialize_find_by_cache
|
123
154
|
super
|
124
155
|
end
|
@@ -126,90 +157,88 @@ module ActiveRecord
|
|
126
157
|
def find(*ids) # :nodoc:
|
127
158
|
# We don't have cache keys for this stuff yet
|
128
159
|
return super unless ids.length == 1
|
129
|
-
# Allow symbols to super to maintain compatibility for deprecated finders until Rails 5
|
130
|
-
return super if ids.first.kind_of?(Symbol)
|
131
160
|
return super if block_given? ||
|
132
161
|
primary_key.nil? ||
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
id = id.id
|
141
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
142
|
-
You are passing an instance of ActiveRecord::Base to `find`.
|
143
|
-
Please pass the id of the object by calling `.id`
|
144
|
-
MSG
|
145
|
-
end
|
162
|
+
scope_attributes? ||
|
163
|
+
columns_hash.key?(inheritance_column) && !base_class?
|
164
|
+
|
165
|
+
id = ids.first
|
166
|
+
|
167
|
+
return super if StatementCache.unsupported_value?(id)
|
168
|
+
|
146
169
|
key = primary_key
|
147
170
|
|
148
|
-
|
149
|
-
|
150
|
-
where(key => params.bind).limit(1)
|
151
|
-
}
|
171
|
+
statement = cached_find_by_statement(key) { |params|
|
172
|
+
where(key => params.bind).limit(1)
|
152
173
|
}
|
153
|
-
|
174
|
+
|
175
|
+
record = statement.execute([id], connection)&.first
|
154
176
|
unless record
|
155
|
-
raise RecordNotFound
|
177
|
+
raise RecordNotFound.new("Couldn't find #{name} with '#{key}'=#{id}", name, key, id)
|
156
178
|
end
|
157
179
|
record
|
158
|
-
rescue RangeError
|
159
|
-
raise RecordNotFound, "Couldn't find #{name} with an out of range value for '#{primary_key}'"
|
160
180
|
end
|
161
181
|
|
162
182
|
def find_by(*args) # :nodoc:
|
163
|
-
return super if
|
164
|
-
|
183
|
+
return super if scope_attributes? || reflect_on_all_aggregations.any? ||
|
184
|
+
columns_hash.key?(inheritance_column) && !base_class?
|
165
185
|
|
166
186
|
hash = args.first
|
167
187
|
|
168
|
-
return super if hash.values.any? { |v|
|
169
|
-
|
188
|
+
return super if !(Hash === hash) || hash.values.any? { |v|
|
189
|
+
StatementCache.unsupported_value?(v)
|
170
190
|
}
|
171
191
|
|
172
192
|
# We can't cache Post.find_by(author: david) ...yet
|
173
193
|
return super unless hash.keys.all? { |k| columns_hash.has_key?(k.to_s) }
|
174
194
|
|
175
|
-
|
195
|
+
keys = hash.keys
|
176
196
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
wheres = key.each_with_object({}) { |param,o|
|
181
|
-
o[param] = params.bind
|
182
|
-
}
|
183
|
-
klass.where(wheres).limit(1)
|
197
|
+
statement = cached_find_by_statement(keys) { |params|
|
198
|
+
wheres = keys.each_with_object({}) { |param, o|
|
199
|
+
o[param] = params.bind
|
184
200
|
}
|
201
|
+
where(wheres).limit(1)
|
185
202
|
}
|
186
203
|
begin
|
187
|
-
|
188
|
-
rescue TypeError
|
189
|
-
raise ActiveRecord::StatementInvalid
|
190
|
-
rescue RangeError
|
191
|
-
nil
|
204
|
+
statement.execute(hash.values, connection)&.first
|
205
|
+
rescue TypeError
|
206
|
+
raise ActiveRecord::StatementInvalid
|
192
207
|
end
|
193
208
|
end
|
194
209
|
|
195
210
|
def find_by!(*args) # :nodoc:
|
196
|
-
find_by(*args)
|
211
|
+
find_by(*args) || raise(RecordNotFound.new("Couldn't find #{name}", name))
|
197
212
|
end
|
198
213
|
|
199
214
|
def initialize_generated_modules # :nodoc:
|
200
215
|
generated_association_methods
|
201
216
|
end
|
202
217
|
|
203
|
-
def generated_association_methods
|
218
|
+
def generated_association_methods # :nodoc:
|
204
219
|
@generated_association_methods ||= begin
|
205
220
|
mod = const_set(:GeneratedAssociationMethods, Module.new)
|
221
|
+
private_constant :GeneratedAssociationMethods
|
206
222
|
include mod
|
223
|
+
|
207
224
|
mod
|
208
225
|
end
|
209
226
|
end
|
210
227
|
|
228
|
+
# Returns columns which shouldn't be exposed while calling +#inspect+.
|
229
|
+
def filter_attributes
|
230
|
+
if defined?(@filter_attributes)
|
231
|
+
@filter_attributes
|
232
|
+
else
|
233
|
+
superclass.filter_attributes
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
# Specifies columns which shouldn't be exposed while calling +#inspect+.
|
238
|
+
attr_writer :filter_attributes
|
239
|
+
|
211
240
|
# Returns a string like 'Post(id:integer, title:string, body:text)'
|
212
|
-
def inspect
|
241
|
+
def inspect # :nodoc:
|
213
242
|
if self == Base
|
214
243
|
super
|
215
244
|
elsif abstract_class?
|
@@ -217,48 +246,65 @@ module ActiveRecord
|
|
217
246
|
elsif !connected?
|
218
247
|
"#{super} (call '#{super}.connection' to establish a connection)"
|
219
248
|
elsif table_exists?
|
220
|
-
attr_list =
|
249
|
+
attr_list = attribute_types.map { |name, type| "#{name}: #{type.type}" } * ", "
|
221
250
|
"#{super}(#{attr_list})"
|
222
251
|
else
|
223
252
|
"#{super}(Table doesn't exist)"
|
224
253
|
end
|
225
254
|
end
|
226
255
|
|
227
|
-
# Overwrite the default class equality method to provide support for
|
228
|
-
def ===(object)
|
256
|
+
# Overwrite the default class equality method to provide support for decorated models.
|
257
|
+
def ===(object) # :nodoc:
|
229
258
|
object.is_a?(self)
|
230
259
|
end
|
231
260
|
|
232
261
|
# Returns an instance of <tt>Arel::Table</tt> loaded with the current table name.
|
233
262
|
#
|
234
263
|
# class Post < ActiveRecord::Base
|
235
|
-
# scope :published_and_commented, -> { published.and(
|
264
|
+
# scope :published_and_commented, -> { published.and(arel_table[:comments_count].gt(0)) }
|
236
265
|
# end
|
237
266
|
def arel_table # :nodoc:
|
238
|
-
@arel_table ||= Arel::Table.new(table_name,
|
267
|
+
@arel_table ||= Arel::Table.new(table_name, type_caster: type_caster)
|
239
268
|
end
|
240
269
|
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
270
|
+
def arel_attribute(name, table = arel_table) # :nodoc:
|
271
|
+
name = name.to_s
|
272
|
+
name = attribute_aliases[name] || name
|
273
|
+
table[name]
|
274
|
+
end
|
275
|
+
|
276
|
+
def predicate_builder # :nodoc:
|
277
|
+
@predicate_builder ||= PredicateBuilder.new(table_metadata)
|
278
|
+
end
|
279
|
+
|
280
|
+
def type_caster # :nodoc:
|
281
|
+
TypeCaster::Map.new(self)
|
282
|
+
end
|
283
|
+
|
284
|
+
def _internal? # :nodoc:
|
285
|
+
false
|
249
286
|
end
|
250
287
|
|
251
288
|
private
|
289
|
+
def cached_find_by_statement(key, &block)
|
290
|
+
cache = @find_by_statement_cache[connection.prepared_statements]
|
291
|
+
cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
|
292
|
+
end
|
252
293
|
|
253
|
-
|
254
|
-
|
294
|
+
def relation
|
295
|
+
relation = Relation.create(self)
|
255
296
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
297
|
+
if finder_needs_type_condition? && !ignore_default_scope?
|
298
|
+
relation.where!(type_condition)
|
299
|
+
relation.create_with!(inheritance_column.to_s => sti_name)
|
300
|
+
else
|
301
|
+
relation
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
def table_metadata
|
306
|
+
TableMetadata.new(self, arel_table)
|
260
307
|
end
|
261
|
-
end
|
262
308
|
end
|
263
309
|
|
264
310
|
# New objects can be instantiated as either empty (pass no construction parameter) or pre-set with
|
@@ -269,16 +315,14 @@ module ActiveRecord
|
|
269
315
|
# ==== Example:
|
270
316
|
# # Instantiates a single new object
|
271
317
|
# User.new(first_name: 'Jamie')
|
272
|
-
def initialize(attributes = nil
|
273
|
-
@
|
274
|
-
self.class.
|
318
|
+
def initialize(attributes = nil)
|
319
|
+
@new_record = true
|
320
|
+
@attributes = self.class._default_attributes.deep_dup
|
275
321
|
|
276
322
|
init_internals
|
277
323
|
initialize_internals_callback
|
278
324
|
|
279
|
-
|
280
|
-
# Remove it when we drop support to this gem.
|
281
|
-
init_attributes(attributes, options) if attributes
|
325
|
+
assign_attributes(attributes) if attributes
|
282
326
|
|
283
327
|
yield self if block_given?
|
284
328
|
_run_initialize_callbacks
|
@@ -286,7 +330,7 @@ module ActiveRecord
|
|
286
330
|
|
287
331
|
# Initialize an empty model object from +coder+. +coder+ should be
|
288
332
|
# the result of previously encoding an Active Record model, using
|
289
|
-
#
|
333
|
+
# #encode_with.
|
290
334
|
#
|
291
335
|
# class Post < ActiveRecord::Base
|
292
336
|
# end
|
@@ -298,15 +342,23 @@ module ActiveRecord
|
|
298
342
|
# post = Post.allocate
|
299
343
|
# post.init_with(coder)
|
300
344
|
# post.title # => 'hello world'
|
301
|
-
def init_with(coder)
|
345
|
+
def init_with(coder, &block)
|
302
346
|
coder = LegacyYamlAdapter.convert(self.class, coder)
|
303
|
-
|
347
|
+
attributes = self.class.yaml_encoder.decode(coder)
|
348
|
+
init_with_attributes(attributes, coder["new_record"], &block)
|
349
|
+
end
|
304
350
|
|
305
|
-
|
351
|
+
##
|
352
|
+
# Initialize an empty model object from +attributes+.
|
353
|
+
# +attributes+ should be an attributes object, and unlike the
|
354
|
+
# `initialize` method, no assignment calls are made per attribute.
|
355
|
+
def init_with_attributes(attributes, new_record = false) # :nodoc:
|
356
|
+
@new_record = new_record
|
357
|
+
@attributes = attributes
|
306
358
|
|
307
|
-
|
359
|
+
init_internals
|
308
360
|
|
309
|
-
self
|
361
|
+
yield self if block_given?
|
310
362
|
|
311
363
|
_run_find_callbacks
|
312
364
|
_run_initialize_callbacks
|
@@ -342,23 +394,22 @@ module ActiveRecord
|
|
342
394
|
|
343
395
|
##
|
344
396
|
def initialize_dup(other) # :nodoc:
|
345
|
-
@attributes = @attributes.
|
346
|
-
@attributes.reset(
|
397
|
+
@attributes = @attributes.deep_dup
|
398
|
+
@attributes.reset(@primary_key)
|
347
399
|
|
348
400
|
_run_initialize_callbacks
|
349
401
|
|
350
|
-
@
|
351
|
-
@
|
352
|
-
|
353
|
-
@
|
354
|
-
@destroyed = false
|
402
|
+
@new_record = true
|
403
|
+
@destroyed = false
|
404
|
+
@_start_transaction_state = nil
|
405
|
+
@transaction_state = nil
|
355
406
|
|
356
407
|
super
|
357
408
|
end
|
358
409
|
|
359
410
|
# Populate +coder+ with attributes about this record that should be
|
360
411
|
# serialized. The structure of +coder+ defined in this method is
|
361
|
-
# guaranteed to match the structure of +coder+ passed to the
|
412
|
+
# guaranteed to match the structure of +coder+ passed to the #init_with
|
362
413
|
# method.
|
363
414
|
#
|
364
415
|
# Example:
|
@@ -369,11 +420,9 @@ module ActiveRecord
|
|
369
420
|
# Post.new.encode_with(coder)
|
370
421
|
# coder # => {"attributes" => {"id" => nil, ... }}
|
371
422
|
def encode_with(coder)
|
372
|
-
|
373
|
-
coder[
|
374
|
-
coder[
|
375
|
-
coder['new_record'] = new_record?
|
376
|
-
coder['active_record_yaml_version'] = 0
|
423
|
+
self.class.yaml_encoder.encode(@attributes, coder)
|
424
|
+
coder["new_record"] = new_record?
|
425
|
+
coder["active_record_yaml_version"] = 2
|
377
426
|
end
|
378
427
|
|
379
428
|
# Returns true if +comparison_object+ is the same exact object, or +comparison_object+
|
@@ -397,7 +446,7 @@ module ActiveRecord
|
|
397
446
|
# [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
|
398
447
|
def hash
|
399
448
|
if id
|
400
|
-
id.hash
|
449
|
+
self.class.hash ^ id.hash
|
401
450
|
else
|
402
451
|
super
|
403
452
|
end
|
@@ -413,18 +462,27 @@ module ActiveRecord
|
|
413
462
|
|
414
463
|
# Returns +true+ if the attributes hash has been frozen.
|
415
464
|
def frozen?
|
465
|
+
sync_with_transaction_state if @transaction_state&.finalized?
|
416
466
|
@attributes.frozen?
|
417
467
|
end
|
418
468
|
|
419
469
|
# Allows sort on objects
|
420
470
|
def <=>(other_object)
|
421
471
|
if other_object.is_a?(self.class)
|
422
|
-
|
472
|
+
to_key <=> other_object.to_key
|
423
473
|
else
|
424
474
|
super
|
425
475
|
end
|
426
476
|
end
|
427
477
|
|
478
|
+
def present? # :nodoc:
|
479
|
+
true
|
480
|
+
end
|
481
|
+
|
482
|
+
def blank? # :nodoc:
|
483
|
+
false
|
484
|
+
end
|
485
|
+
|
428
486
|
# Returns +true+ if the record is read only. Records loaded through joins with piggy-back
|
429
487
|
# attributes will be marked as read only since they cannot be saved.
|
430
488
|
def readonly?
|
@@ -445,135 +503,99 @@ module ActiveRecord
|
|
445
503
|
# We check defined?(@attributes) not to issue warnings if the object is
|
446
504
|
# allocated but not initialized.
|
447
505
|
inspection = if defined?(@attributes) && @attributes
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
506
|
+
self.class.attribute_names.collect do |name|
|
507
|
+
if has_attribute?(name)
|
508
|
+
attr = _read_attribute(name)
|
509
|
+
value = if attr.nil?
|
510
|
+
attr.inspect
|
511
|
+
else
|
512
|
+
attr = format_for_inspect(attr)
|
513
|
+
inspection_filter.filter_param(name, attr)
|
514
|
+
end
|
515
|
+
"#{name}: #{value}"
|
516
|
+
end
|
517
|
+
end.compact.join(", ")
|
518
|
+
else
|
519
|
+
"not initialized"
|
520
|
+
end
|
521
|
+
|
456
522
|
"#<#{self.class} #{inspection}>"
|
457
523
|
end
|
458
524
|
|
459
|
-
# Takes a PP and prettily prints this record to it, allowing you to get a nice result from
|
525
|
+
# Takes a PP and prettily prints this record to it, allowing you to get a nice result from <tt>pp record</tt>
|
460
526
|
# when pp is required.
|
461
527
|
def pretty_print(pp)
|
462
528
|
return super if custom_inspect_method_defined?
|
463
529
|
pp.object_address_group(self) do
|
464
530
|
if defined?(@attributes) && @attributes
|
465
|
-
|
466
|
-
pp.seplist(
|
467
|
-
|
468
|
-
pp.breakable ' '
|
531
|
+
attr_names = self.class.attribute_names.select { |name| has_attribute?(name) }
|
532
|
+
pp.seplist(attr_names, proc { pp.text "," }) do |attr_name|
|
533
|
+
pp.breakable " "
|
469
534
|
pp.group(1) do
|
470
|
-
pp.text
|
471
|
-
pp.text
|
535
|
+
pp.text attr_name
|
536
|
+
pp.text ":"
|
472
537
|
pp.breakable
|
473
|
-
|
538
|
+
value = _read_attribute(attr_name)
|
539
|
+
value = inspection_filter.filter_param(attr_name, value) unless value.nil?
|
540
|
+
pp.pp value
|
474
541
|
end
|
475
542
|
end
|
476
543
|
else
|
477
|
-
pp.breakable
|
478
|
-
pp.text
|
544
|
+
pp.breakable " "
|
545
|
+
pp.text "not initialized"
|
479
546
|
end
|
480
547
|
end
|
481
548
|
end
|
482
549
|
|
483
550
|
# Returns a hash of the given methods with their names as keys and returned values as values.
|
484
551
|
def slice(*methods)
|
485
|
-
Hash[methods.map! { |method| [method, public_send(method)] }].with_indifferent_access
|
552
|
+
Hash[methods.flatten.map! { |method| [method, public_send(method)] }].with_indifferent_access
|
486
553
|
end
|
487
554
|
|
488
555
|
private
|
556
|
+
# +Array#flatten+ will call +#to_ary+ (recursively) on each of the elements of
|
557
|
+
# the array, and then rescues from the possible +NoMethodError+. If those elements are
|
558
|
+
# +ActiveRecord::Base+'s, then this triggers the various +method_missing+'s that we have,
|
559
|
+
# which significantly impacts upon performance.
|
560
|
+
#
|
561
|
+
# So we can avoid the +method_missing+ hit by explicitly defining +#to_ary+ as +nil+ here.
|
562
|
+
#
|
563
|
+
# See also https://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary.html
|
564
|
+
def to_ary
|
565
|
+
nil
|
566
|
+
end
|
489
567
|
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
568
|
+
def init_internals
|
569
|
+
@primary_key = self.class.primary_key
|
570
|
+
@readonly = false
|
571
|
+
@destroyed = false
|
572
|
+
@marked_for_destruction = false
|
573
|
+
@destroyed_by_association = nil
|
574
|
+
@_start_transaction_state = nil
|
575
|
+
@transaction_state = nil
|
497
576
|
|
498
|
-
|
499
|
-
|
500
|
-
# will be updated to reflect the current state of the transaction
|
501
|
-
#
|
502
|
-
# The @transaction_state variable stores the states of the associated
|
503
|
-
# transaction. This relies on the fact that a transaction can only be in
|
504
|
-
# one rollback or commit (otherwise a list of states would be required)
|
505
|
-
# Each AR object inside of a transaction carries that transaction's
|
506
|
-
# TransactionState.
|
507
|
-
#
|
508
|
-
# This method checks to see if the ActiveRecord object's state reflects
|
509
|
-
# the TransactionState, and rolls back or commits the ActiveRecord object
|
510
|
-
# as appropriate.
|
511
|
-
#
|
512
|
-
# Since ActiveRecord objects can be inside multiple transactions, this
|
513
|
-
# method recursively goes through the parent of the TransactionState and
|
514
|
-
# checks if the ActiveRecord object reflects the state of the object.
|
515
|
-
def sync_with_transaction_state
|
516
|
-
update_attributes_from_transaction_state(@transaction_state, 0)
|
517
|
-
end
|
577
|
+
self.class.define_attribute_methods
|
578
|
+
end
|
518
579
|
|
519
|
-
|
520
|
-
|
580
|
+
def initialize_internals_callback
|
581
|
+
end
|
521
582
|
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
clear_transaction_record_state
|
526
|
-
@reflects_state[depth] = true
|
527
|
-
end
|
583
|
+
def custom_inspect_method_defined?
|
584
|
+
self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner
|
585
|
+
end
|
528
586
|
|
529
|
-
|
530
|
-
|
587
|
+
class InspectionMask < DelegateClass(::String)
|
588
|
+
def pretty_print(pp)
|
589
|
+
pp.text __getobj__
|
531
590
|
end
|
532
591
|
end
|
533
|
-
|
534
|
-
|
535
|
-
# Under Ruby 1.9, Array#flatten will call #to_ary (recursively) on each of the elements
|
536
|
-
# of the array, and then rescues from the possible NoMethodError. If those elements are
|
537
|
-
# ActiveRecord::Base's, then this triggers the various method_missing's that we have,
|
538
|
-
# which significantly impacts upon performance.
|
539
|
-
#
|
540
|
-
# So we can avoid the method_missing hit by explicitly defining #to_ary as nil here.
|
541
|
-
#
|
542
|
-
# See also http://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary.html
|
543
|
-
def to_ary # :nodoc:
|
544
|
-
nil
|
545
|
-
end
|
592
|
+
private_constant :InspectionMask
|
546
593
|
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
@marked_for_destruction = false
|
553
|
-
@destroyed_by_association = nil
|
554
|
-
@new_record = true
|
555
|
-
@txn = nil
|
556
|
-
@_start_transaction_state = {}
|
557
|
-
@transaction_state = nil
|
558
|
-
end
|
559
|
-
|
560
|
-
def initialize_internals_callback
|
561
|
-
end
|
562
|
-
|
563
|
-
# This method is needed to make protected_attributes gem easier to hook.
|
564
|
-
# Remove it when we drop support to this gem.
|
565
|
-
def init_attributes(attributes, options)
|
566
|
-
assign_attributes(attributes)
|
567
|
-
end
|
568
|
-
|
569
|
-
def thaw
|
570
|
-
if frozen?
|
571
|
-
@attributes = @attributes.dup
|
594
|
+
def inspection_filter
|
595
|
+
@inspection_filter ||= begin
|
596
|
+
mask = InspectionMask.new(ActiveSupport::ParameterFilter::FILTERED)
|
597
|
+
ActiveSupport::ParameterFilter.new(self.class.filter_attributes, mask: mask)
|
598
|
+
end
|
572
599
|
end
|
573
|
-
end
|
574
|
-
|
575
|
-
def custom_inspect_method_defined?
|
576
|
-
self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner
|
577
|
-
end
|
578
600
|
end
|
579
601
|
end
|