ibm_db 5.6.1 → 5.7.0
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/ext/Makefile +13 -9
- data/ext/extconf.rb +176 -110
- data/ext/ibm_db.c +60 -0
- data/ext/ibm_db.o +0 -0
- data/ext/ibm_db.so +0 -0
- data/ext/mkmf.log +6 -6
- data/ext/ruby_ibm_db_cli.c +14 -10
- data/ext/ruby_ibm_db_cli.h +4 -0
- data/ext/ruby_ibm_db_cli.o +0 -0
- data/lib/IBM_DB.rb +2 -2
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1254 -277
- data/test/active_record/connection_adapters/fake_legacy_adapter.rb +17 -0
- data/test/active_record/connection_adapters/fake_misleading_legacy_adapter.rb +8 -0
- data/test/activejob/destroy_association_async_job_test.rb +62 -0
- data/test/activejob/destroy_association_async_test.rb +147 -11
- data/test/activejob/job_runtime_test.rb +41 -0
- data/test/activejob/unloadable_base_job.rb +3 -0
- data/test/cases/active_record_schema_test.rb +196 -0
- data/test/cases/active_record_test.rb +21 -0
- data/test/cases/adapter_prevent_writes_test.rb +26 -202
- data/test/cases/adapter_test.rb +592 -82
- data/test/cases/adapters/abstract_mysql_adapter/active_schema_test.rb +210 -0
- data/test/cases/adapters/abstract_mysql_adapter/adapter_prevent_writes_test.rb +111 -0
- data/test/cases/adapters/abstract_mysql_adapter/auto_increment_test.rb +48 -0
- data/test/cases/adapters/abstract_mysql_adapter/bind_parameter_test.rb +91 -0
- data/test/cases/adapters/abstract_mysql_adapter/case_sensitivity_test.rb +65 -0
- data/test/cases/adapters/abstract_mysql_adapter/charset_collation_test.rb +85 -0
- data/test/cases/adapters/abstract_mysql_adapter/connection_test.rb +267 -0
- data/test/cases/adapters/abstract_mysql_adapter/count_deleted_rows_with_lock_test.rb +29 -0
- data/test/cases/adapters/abstract_mysql_adapter/json_test.rb +24 -0
- data/test/cases/adapters/abstract_mysql_adapter/mysql_boolean_test.rb +102 -0
- data/test/cases/adapters/abstract_mysql_adapter/mysql_enum_test.rb +47 -0
- data/test/cases/adapters/abstract_mysql_adapter/mysql_explain_test.rb +71 -0
- data/test/cases/adapters/abstract_mysql_adapter/nested_deadlock_test.rb +191 -0
- data/test/cases/adapters/abstract_mysql_adapter/optimizer_hints_test.rb +69 -0
- data/test/cases/adapters/abstract_mysql_adapter/quoting_test.rb +49 -0
- data/test/cases/adapters/abstract_mysql_adapter/schema_migrations_test.rb +68 -0
- data/test/cases/adapters/abstract_mysql_adapter/schema_test.rb +130 -0
- data/test/cases/adapters/abstract_mysql_adapter/set_test.rb +32 -0
- data/test/cases/adapters/abstract_mysql_adapter/sp_test.rb +39 -0
- data/test/cases/adapters/abstract_mysql_adapter/sql_types_test.rb +16 -0
- data/test/cases/adapters/abstract_mysql_adapter/table_options_test.rb +125 -0
- data/test/cases/adapters/abstract_mysql_adapter/transaction_test.rb +204 -0
- data/test/cases/adapters/abstract_mysql_adapter/unsigned_type_test.rb +77 -0
- data/test/cases/adapters/abstract_mysql_adapter/virtual_column_test.rb +69 -0
- data/test/cases/adapters/abstract_mysql_adapter/warnings_test.rb +109 -0
- data/test/cases/adapters/mysql2/check_constraint_quoting_test.rb +35 -0
- data/test/cases/adapters/mysql2/dbconsole_test.rb +87 -0
- data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +136 -10
- data/test/cases/adapters/mysql2/mysql2_rake_test.rb +433 -0
- data/test/cases/adapters/postgresql/active_schema_test.rb +8 -4
- data/test/cases/adapters/postgresql/array_test.rb +6 -6
- data/test/cases/adapters/postgresql/bind_parameter_test.rb +52 -0
- data/test/cases/adapters/postgresql/bit_string_test.rb +2 -2
- data/test/cases/adapters/postgresql/bytea_test.rb +3 -3
- data/test/cases/adapters/postgresql/case_insensitive_test.rb +1 -1
- data/test/cases/adapters/postgresql/change_schema_test.rb +32 -1
- data/test/cases/adapters/postgresql/cidr_test.rb +17 -0
- data/test/cases/adapters/postgresql/citext_test.rb +7 -1
- data/test/cases/adapters/postgresql/collation_test.rb +1 -1
- data/test/cases/adapters/postgresql/composite_test.rb +1 -1
- data/test/cases/adapters/postgresql/connection_test.rb +43 -36
- data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +3 -2
- data/test/cases/adapters/postgresql/datatype_test.rb +9 -4
- data/test/cases/adapters/postgresql/date_test.rb +2 -2
- data/test/cases/adapters/postgresql/dbconsole_test.rb +109 -0
- data/test/cases/adapters/postgresql/deferred_constraints_test.rb +55 -0
- data/test/cases/adapters/postgresql/domain_test.rb +1 -1
- data/test/cases/adapters/postgresql/enum_test.rb +208 -8
- data/test/cases/adapters/postgresql/explain_test.rb +25 -6
- data/test/cases/adapters/postgresql/extension_migration_test.rb +51 -9
- data/test/cases/adapters/postgresql/foreign_table_test.rb +3 -3
- data/test/cases/adapters/postgresql/full_text_test.rb +1 -1
- data/test/cases/adapters/postgresql/geometric_test.rb +13 -6
- data/test/cases/adapters/postgresql/hstore_test.rb +22 -32
- data/test/cases/adapters/postgresql/infinity_test.rb +13 -2
- data/test/cases/adapters/postgresql/integer_test.rb +1 -1
- data/test/cases/adapters/postgresql/interval_test.rb +9 -17
- data/test/cases/adapters/postgresql/invertible_migration_test.rb +139 -0
- data/test/cases/adapters/postgresql/json_test.rb +5 -0
- data/test/cases/adapters/postgresql/ltree_test.rb +1 -1
- data/test/cases/adapters/postgresql/money_test.rb +17 -9
- data/test/cases/adapters/postgresql/network_test.rb +13 -1
- data/test/cases/adapters/postgresql/numbers_test.rb +18 -2
- data/test/cases/adapters/postgresql/optimizer_hints_test.rb +9 -9
- data/test/cases/adapters/postgresql/partitions_test.rb +5 -2
- data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +7 -110
- data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +403 -20
- data/test/cases/adapters/postgresql/postgresql_rake_test.rb +637 -0
- data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +1 -1
- data/test/cases/adapters/postgresql/quoting_test.rb +60 -1
- data/test/cases/adapters/postgresql/range_test.rb +185 -21
- data/test/cases/adapters/postgresql/referential_integrity_test.rb +29 -5
- data/test/cases/adapters/postgresql/rename_table_test.rb +35 -8
- data/test/cases/adapters/postgresql/schema_authorization_test.rb +2 -2
- data/test/cases/adapters/postgresql/schema_test.rb +270 -20
- data/test/cases/adapters/postgresql/serial_test.rb +5 -5
- data/test/cases/adapters/postgresql/statement_pool_test.rb +6 -2
- data/test/cases/adapters/postgresql/timestamp_test.rb +122 -5
- data/test/cases/adapters/postgresql/transaction_nested_test.rb +130 -6
- data/test/cases/adapters/postgresql/transaction_test.rb +37 -11
- data/test/cases/adapters/postgresql/type_lookup_test.rb +1 -1
- data/test/cases/adapters/postgresql/uuid_test.rb +77 -9
- data/test/cases/adapters/postgresql/virtual_column_test.rb +114 -0
- data/test/cases/adapters/postgresql/xml_test.rb +1 -1
- data/test/cases/adapters/sqlite3/bind_parameter_test.rb +52 -0
- data/test/cases/adapters/sqlite3/collation_test.rb +1 -1
- data/test/cases/adapters/sqlite3/copy_table_test.rb +28 -7
- data/test/cases/adapters/sqlite3/dbconsole_test.rb +81 -0
- data/test/cases/adapters/sqlite3/explain_test.rb +3 -3
- data/test/cases/adapters/sqlite3/quoting_test.rb +34 -3
- data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +9 -102
- data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +727 -72
- data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +6 -3
- data/test/cases/adapters/sqlite3/sqlite_rake_test.rb +264 -0
- data/test/cases/adapters/sqlite3/statement_pool_test.rb +1 -1
- data/test/cases/adapters/sqlite3/transaction_test.rb +6 -3
- data/test/cases/adapters/sqlite3/virtual_column_test.rb +138 -0
- data/test/cases/adapters/sqlite3/virtual_table_test.rb +51 -0
- data/test/cases/adapters/trilogy/dbconsole_test.rb +76 -0
- data/test/cases/adapters/trilogy/trilogy_adapter_test.rb +473 -0
- data/test/cases/adapters/trilogy/trilogy_rake_test.rb +433 -0
- data/test/cases/aggregations_test.rb +16 -0
- data/test/cases/annotate_test.rb +14 -12
- data/test/cases/arel/attributes/attribute_test.rb +86 -47
- data/test/cases/arel/collectors/bind_test.rb +1 -1
- data/test/cases/arel/collectors/composite_test.rb +11 -1
- data/test/cases/arel/collectors/sql_string_test.rb +1 -1
- data/test/cases/arel/collectors/substitute_bind_collector_test.rb +1 -1
- data/test/cases/arel/delete_manager_test.rb +0 -6
- data/test/cases/arel/factory_methods_test.rb +45 -0
- data/test/cases/arel/insert_manager_test.rb +1 -7
- data/test/cases/arel/nodes/as_test.rb +12 -0
- data/test/cases/arel/nodes/ascending_test.rb +1 -1
- data/test/cases/arel/nodes/bin_test.rb +1 -1
- data/test/cases/arel/nodes/bound_sql_literal_test.rb +31 -0
- data/test/cases/arel/nodes/cte_test.rb +46 -0
- data/test/cases/arel/nodes/descending_test.rb +1 -1
- data/test/cases/arel/nodes/equality_test.rb +3 -3
- data/test/cases/arel/nodes/filter_test.rb +37 -0
- data/test/cases/arel/nodes/fragments_test.rb +38 -0
- data/test/cases/arel/nodes/homogeneous_in_test.rb +52 -0
- data/test/cases/arel/nodes/infix_operation_test.rb +1 -1
- data/test/cases/arel/nodes/node_test.rb +1 -1
- data/test/cases/arel/nodes/or_test.rb +2 -2
- data/test/cases/arel/nodes/sql_literal_test.rb +18 -1
- data/test/cases/arel/nodes/table_alias_test.rb +12 -0
- data/test/cases/arel/nodes/unary_operation_test.rb +1 -1
- data/test/cases/arel/nodes/update_statement_test.rb +4 -0
- data/test/cases/arel/nodes_test.rb +3 -2
- data/test/cases/arel/select_manager_test.rb +12 -12
- data/test/cases/arel/support/fake_record.rb +22 -17
- data/test/cases/arel/table_test.rb +15 -25
- data/test/cases/arel/update_manager_test.rb +51 -6
- data/test/cases/arel/visitors/dispatch_contamination_test.rb +1 -1
- data/test/cases/arel/visitors/dot_test.rb +177 -2
- data/test/cases/arel/visitors/mysql_test.rb +49 -1
- data/test/cases/arel/visitors/postgres_test.rb +1 -31
- data/test/cases/arel/visitors/sqlite_test.rb +1 -1
- data/test/cases/arel/visitors/to_sql_test.rb +330 -20
- data/test/cases/assertions/query_assertions_test.rb +136 -0
- data/test/cases/associations/belongs_to_associations_test.rb +502 -41
- data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +1 -1
- data/test/cases/associations/cascaded_eager_loading_test.rb +26 -15
- data/test/cases/associations/eager_load_nested_include_test.rb +1 -1
- data/test/cases/associations/eager_singularization_test.rb +1 -1
- data/test/cases/associations/eager_test.rb +255 -93
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +25 -53
- data/test/cases/associations/has_many_associations_test.rb +282 -72
- data/test/cases/associations/has_many_through_associations_test.rb +172 -45
- data/test/cases/associations/has_many_through_disable_joins_associations_test.rb +197 -0
- data/test/cases/associations/has_one_associations_test.rb +160 -29
- data/test/cases/associations/has_one_through_associations_test.rb +64 -15
- data/test/cases/associations/has_one_through_disable_joins_associations_test.rb +82 -0
- data/test/cases/associations/inner_join_association_test.rb +36 -6
- data/test/cases/associations/inverse_associations_test.rb +177 -40
- data/test/cases/associations/join_model_test.rb +17 -12
- data/test/cases/associations/left_outer_join_association_test.rb +14 -3
- data/test/cases/associations/nested_error_test.rb +116 -0
- data/test/cases/associations/nested_through_associations_test.rb +54 -19
- data/test/cases/associations/required_test.rb +1 -1
- data/test/cases/associations_test.rb +1278 -21
- data/test/cases/asynchronous_queries_test.rb +310 -0
- data/test/cases/attribute_methods/read_test.rb +6 -0
- data/test/cases/attribute_methods/time_zone_converter_test.rb +21 -0
- data/test/cases/attribute_methods_test.rb +565 -46
- data/test/cases/attributes_test.rb +42 -1
- data/test/cases/autosave_association_test.rb +645 -92
- data/test/cases/base_prevent_writes_test.rb +28 -159
- data/test/cases/base_test.rb +434 -209
- data/test/cases/batches_test.rb +441 -57
- data/test/cases/binary_test.rb +31 -0
- data/test/cases/bind_parameter_test.rb +107 -16
- data/test/cases/cache_key_test.rb +7 -7
- data/test/cases/calculations_test.rb +541 -110
- data/test/cases/callbacks_test.rb +0 -1
- data/test/cases/clone_test.rb +5 -4
- data/test/cases/coders/yaml_column_test.rb +97 -2
- data/test/cases/collection_cache_key_test.rb +24 -16
- data/test/cases/column_alias_test.rb +2 -8
- data/test/cases/column_definition_test.rb +12 -3
- data/test/cases/comment_test.rb +23 -26
- data/test/cases/connection_adapters/adapter_leasing_test.rb +9 -9
- data/test/cases/connection_adapters/connection_handler_test.rb +145 -99
- data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +79 -55
- data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +17 -20
- data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +146 -55
- data/test/cases/connection_adapters/connection_swapping_nested_test.rb +136 -23
- data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +96 -27
- data/test/cases/connection_adapters/mysql_type_lookup_test.rb +5 -5
- data/test/cases/connection_adapters/registration_test.rb +98 -0
- data/test/cases/connection_adapters/schema_cache_test.rb +288 -135
- data/test/cases/connection_adapters/standalone_connection_test.rb +38 -0
- data/test/cases/connection_adapters/statement_pool_test.rb +29 -0
- data/test/cases/connection_adapters/type_lookup_test.rb +12 -24
- data/test/cases/connection_handling_test.rb +210 -0
- data/test/cases/connection_management_test.rb +44 -7
- data/test/cases/connection_pool_test.rb +466 -99
- data/test/cases/core_test.rb +167 -9
- data/test/cases/counter_cache_test.rb +129 -2
- data/test/cases/custom_locking_test.rb +3 -3
- data/test/cases/database_configurations/hash_config_test.rb +149 -13
- data/test/cases/database_configurations/resolver_test.rb +14 -10
- data/test/cases/database_configurations/url_config_test.rb +53 -0
- data/test/cases/database_configurations_test.rb +86 -43
- data/test/cases/database_selector_test.rb +30 -8
- data/test/cases/database_statements_test.rb +10 -14
- data/test/cases/date_time_precision_test.rb +141 -11
- data/test/cases/date_time_test.rb +19 -1
- data/test/cases/defaults_test.rb +107 -41
- data/test/cases/delegated_type_test.rb +69 -9
- data/test/cases/dirty_test.rb +82 -25
- data/test/cases/disconnected_test.rb +10 -9
- data/test/cases/dup_test.rb +26 -6
- data/test/cases/encryption/cipher/aes256_gcm_test.rb +50 -0
- data/test/cases/encryption/cipher_test.rb +65 -0
- data/test/cases/encryption/concurrency_test.rb +27 -0
- data/test/cases/encryption/config_test.rb +21 -0
- data/test/cases/encryption/configurable_test.rb +93 -0
- data/test/cases/encryption/contexts_test.rb +105 -0
- data/test/cases/encryption/derived_secret_key_provider_test.rb +31 -0
- data/test/cases/encryption/deterministic_key_provider_test.rb +11 -0
- data/test/cases/encryption/encryptable_record_api_test.rb +175 -0
- data/test/cases/encryption/encryptable_record_message_pack_serialized_test.rb +42 -0
- data/test/cases/encryption/encryptable_record_test.rb +470 -0
- data/test/cases/encryption/encrypted_fixtures_test.rb +22 -0
- data/test/cases/encryption/encrypting_only_encryptor_test.rb +20 -0
- data/test/cases/encryption/encryption_schemes_test.rb +240 -0
- data/test/cases/encryption/encryptor_test.rb +113 -0
- data/test/cases/encryption/envelope_encryption_key_provider_test.rb +49 -0
- data/test/cases/encryption/extended_deterministic_queries_test.rb +81 -0
- data/test/cases/encryption/helper.rb +152 -0
- data/test/cases/encryption/key_generator_test.rb +55 -0
- data/test/cases/encryption/key_provider_test.rb +57 -0
- data/test/cases/encryption/key_test.rb +17 -0
- data/test/cases/encryption/message_pack_message_serializer_test.rb +70 -0
- data/test/cases/encryption/message_serializer_test.rb +82 -0
- data/test/cases/encryption/message_test.rb +43 -0
- data/test/cases/encryption/null_encryptor_test.rb +21 -0
- data/test/cases/encryption/properties_test.rb +69 -0
- data/test/cases/encryption/read_only_null_encryptor_test.rb +19 -0
- data/test/cases/encryption/scheme_test.rb +58 -0
- data/test/cases/encryption/unencrypted_attributes_test.rb +27 -0
- data/test/cases/encryption/uniqueness_validations_test.rb +65 -0
- data/test/cases/enum_test.rb +374 -72
- data/test/cases/errors_test.rb +7 -4
- data/test/cases/excluding_test.rb +116 -0
- data/test/cases/explain_subscriber_test.rb +6 -1
- data/test/cases/explain_test.rb +119 -10
- data/test/cases/filter_attributes_test.rb +7 -14
- data/test/cases/finder_respond_to_test.rb +3 -3
- data/test/cases/finder_test.rb +357 -72
- data/test/cases/fixture_set/file_test.rb +9 -0
- data/test/cases/fixtures_test.rb +426 -190
- data/test/cases/helper.rb +66 -192
- data/test/cases/hot_compatibility_test.rb +10 -10
- data/test/cases/inheritance_test.rb +51 -61
- data/test/cases/inherited_test.rb +40 -0
- data/test/cases/insert_all_test.rb +419 -9
- data/test/cases/instrumentation_test.rb +202 -30
- data/test/cases/integration_test.rb +25 -7
- data/test/cases/invalid_connection_test.rb +5 -5
- data/test/cases/invertible_migration_test.rb +108 -24
- data/test/cases/json_attribute_test.rb +1 -0
- data/test/cases/json_serialization_test.rb +5 -5
- data/test/cases/json_shared_test_cases.rb +5 -9
- data/test/cases/locking_test.rb +67 -31
- data/test/cases/log_subscriber_test.rb +17 -15
- data/test/cases/marshal_serialization_test.rb +78 -5
- data/test/cases/message_pack_test.rb +91 -0
- data/test/cases/migration/change_schema_test.rb +77 -46
- data/test/cases/migration/change_table_test.rb +129 -114
- data/test/cases/migration/check_constraint_test.rb +192 -10
- data/test/cases/migration/column_attributes_test.rb +4 -9
- data/test/cases/migration/column_positioning_test.rb +2 -2
- data/test/cases/migration/columns_test.rb +118 -4
- data/test/cases/migration/command_recorder_test.rb +181 -14
- data/test/cases/migration/compatibility_test.rb +883 -196
- data/test/cases/migration/create_join_table_test.rb +8 -1
- data/test/cases/migration/exclusion_constraint_test.rb +192 -0
- data/test/cases/migration/foreign_key_test.rb +356 -14
- data/test/cases/migration/helper.rb +4 -1
- data/test/cases/migration/index_test.rb +67 -2
- data/test/cases/migration/invalid_options_test.rb +129 -0
- data/test/cases/migration/logger_test.rb +7 -4
- data/test/cases/migration/pending_migrations_test.rb +103 -60
- data/test/cases/migration/references_foreign_key_test.rb +73 -4
- data/test/cases/migration/references_index_test.rb +25 -27
- data/test/cases/migration/references_statements_test.rb +27 -3
- data/test/cases/migration/rename_table_test.rb +39 -54
- data/test/cases/migration/schema_definitions_test.rb +109 -0
- data/test/cases/migration/unique_constraint_test.rb +248 -0
- data/test/cases/migration_test.rb +677 -220
- data/test/cases/migrator_test.rb +102 -75
- data/test/cases/multi_db_migrator_test.rb +55 -34
- data/test/cases/multiparameter_attributes_test.rb +26 -29
- data/test/cases/multiple_db_test.rb +42 -19
- data/test/cases/nested_attributes_test.rb +124 -6
- data/test/cases/nested_attributes_with_callbacks_test.rb +2 -2
- data/test/cases/normalized_attribute_test.rb +117 -0
- data/test/cases/null_relation_test.rb +35 -2
- data/test/cases/persistence/reload_association_cache_test.rb +20 -0
- data/test/cases/persistence_test.rb +629 -22
- data/test/cases/pooled_connections_test.rb +57 -56
- data/test/cases/prepared_statement_status_test.rb +8 -3
- data/test/cases/primary_class_test.rb +134 -0
- data/test/cases/primary_keys_test.rb +171 -55
- data/test/cases/query_cache_test.rb +558 -263
- data/test/cases/query_logs_test.rb +293 -0
- data/test/cases/quoting_test.rb +39 -72
- data/test/cases/readonly_test.rb +50 -12
- data/test/cases/reaper_test.rb +22 -6
- data/test/cases/reflection_test.rb +207 -9
- data/test/cases/relation/and_test.rb +43 -0
- data/test/cases/relation/delegation_test.rb +32 -5
- data/test/cases/relation/delete_all_test.rb +27 -6
- data/test/cases/relation/field_ordered_values_test.rb +128 -0
- data/test/cases/relation/load_async_test.rb +650 -0
- data/test/cases/relation/merging_test.rb +80 -109
- data/test/cases/relation/mutation_test.rb +12 -7
- data/test/cases/relation/or_test.rb +11 -8
- data/test/cases/relation/order_test.rb +90 -0
- data/test/cases/relation/predicate_builder_test.rb +21 -6
- data/test/cases/relation/select_test.rb +162 -3
- data/test/cases/relation/structural_compatibility_test.rb +38 -0
- data/test/cases/relation/update_all_test.rb +81 -27
- data/test/cases/relation/where_chain_test.rb +190 -3
- data/test/cases/relation/where_clause_test.rb +43 -1
- data/test/cases/relation/where_test.rb +95 -7
- data/test/cases/relation/with_test.rb +165 -0
- data/test/cases/relation_test.rb +42 -37
- data/test/cases/relations_test.rb +436 -138
- data/test/cases/reload_models_test.rb +18 -14
- data/test/cases/reserved_word_test.rb +2 -1
- data/test/cases/result_test.rb +14 -22
- data/test/cases/sanitize_test.rb +89 -27
- data/test/cases/schema_dumper_test.rb +535 -62
- data/test/cases/scoping/default_scoping_test.rb +219 -35
- data/test/cases/scoping/named_scoping_test.rb +25 -46
- data/test/cases/scoping/relation_scoping_test.rb +112 -4
- data/test/cases/secure_password_test.rb +108 -0
- data/test/cases/secure_token_test.rb +72 -0
- data/test/cases/serialization_test.rb +1 -1
- data/test/cases/serialized_attribute_test.rb +305 -60
- data/test/cases/shard_keys_test.rb +125 -0
- data/test/cases/shard_selector_test.rb +45 -0
- data/test/cases/signed_id_test.rb +57 -5
- data/test/cases/statement_cache_test.rb +31 -30
- data/test/cases/statement_invalid_test.rb +8 -4
- data/test/cases/store_test.rb +73 -9
- data/test/cases/strict_loading_test.rb +327 -13
- data/test/cases/table_metadata_test.rb +16 -0
- data/test/cases/tasks/database_tasks_test.rb +517 -244
- data/test/cases/test_case.rb +254 -60
- data/test/cases/test_case_test.rb +69 -0
- data/test/cases/test_databases_test.rb +7 -3
- data/test/cases/test_fixtures_test.rb +19 -40
- data/test/cases/time_precision_test.rb +17 -5
- data/test/cases/timestamp_test.rb +124 -16
- data/test/cases/token_for_test.rb +165 -0
- data/test/cases/touch_later_test.rb +43 -1
- data/test/cases/transaction_callbacks_test.rb +325 -8
- data/test/cases/transaction_instrumentation_test.rb +453 -0
- data/test/cases/transaction_isolation_test.rb +12 -8
- data/test/cases/transactions_test.rb +629 -112
- data/test/cases/type/date_time_test.rb +7 -1
- data/test/cases/type/time_test.rb +9 -0
- data/test/cases/type/type_map_test.rb +108 -73
- data/test/cases/type/unsigned_integer_test.rb +12 -0
- data/test/cases/type_caster/connection_test.rb +19 -0
- data/test/cases/type_test.rb +1 -1
- data/test/cases/unconnected_test.rb +7 -7
- data/test/cases/unsafe_raw_sql_test.rb +39 -8
- data/test/cases/validations/absence_validation_test.rb +1 -1
- data/test/cases/validations/association_validation_test.rb +25 -3
- data/test/cases/validations/numericality_validation_test.rb +3 -9
- data/test/cases/validations/presence_validation_test.rb +1 -1
- data/test/cases/validations/uniqueness_validation_test.rb +280 -40
- data/test/cases/validations_test.rb +2 -2
- data/test/cases/view_test.rb +33 -22
- data/test/cases/yaml_serialization_test.rb +23 -17
- data/test/config.example.yml +58 -56
- data/test/config.rb +1 -0
- data/test/fixtures/1_need_quoting.yml +2 -0
- data/test/fixtures/accounts.yml +5 -0
- data/test/fixtures/aircrafts.yml +7 -0
- data/test/fixtures/book_identifiers.yml +11 -0
- data/test/fixtures/books.yml +5 -4
- data/test/fixtures/cake_designers.yml +5 -0
- data/test/fixtures/cars.yml +6 -0
- data/test/fixtures/chefs.yml +5 -0
- data/test/fixtures/clothing_items.yml +23 -0
- data/test/fixtures/clubs.yml +1 -1
- data/test/fixtures/comments.yml +2 -1
- data/test/fixtures/cpk_authors.yml +8 -0
- data/test/fixtures/cpk_books.yml +21 -0
- data/test/fixtures/cpk_order_agreements.yml +13 -0
- data/test/fixtures/cpk_order_tags.yml +15 -0
- data/test/fixtures/cpk_orders.yml +11 -0
- data/test/fixtures/cpk_posts.yml +12 -0
- data/test/fixtures/cpk_reviews.yml +13 -0
- data/test/fixtures/cpk_tags.yml +11 -0
- data/test/fixtures/drink_designers.yml +5 -0
- data/test/fixtures/encrypted_book_that_ignores_cases.yml +4 -0
- data/test/fixtures/encrypted_books.yml +4 -0
- data/test/fixtures/fk_object_to_point_to.yml +2 -0
- data/test/fixtures/memberships.yml +15 -15
- data/test/fixtures/paragraphs.yml +5 -0
- data/test/fixtures/parrots.yml +4 -0
- data/test/fixtures/people.yml +2 -0
- data/test/fixtures/pirates.yml +2 -2
- data/test/fixtures/primary_key_error/primary_key_error.yml +6 -0
- data/test/fixtures/references.yml +3 -3
- data/test/fixtures/sharded_blog_posts.yml +14 -0
- data/test/fixtures/sharded_blog_posts_tags.yml +27 -0
- data/test/fixtures/sharded_blogs.yml +8 -0
- data/test/fixtures/sharded_comments.yml +22 -0
- data/test/fixtures/sharded_tags.yml +34 -0
- data/test/fixtures/sponsors.yml +2 -2
- data/test/fixtures/topics.yml +1 -0
- data/test/fixtures/treasures.yml +4 -0
- data/test/fixtures/virtual_columns.yml +5 -0
- data/test/fixtures/warehouse_things.yml +1 -1
- data/test/migrations/old_and_new_versions/20210716122844_add_people_description.rb +5 -0
- data/test/migrations/old_and_new_versions/20210716123013_add_people_number_of_legs.rb +5 -0
- data/test/migrations/old_and_new_versions/230_add_people_hobby.rb +5 -0
- data/test/migrations/old_and_new_versions/231_add_people_last_name.rb +5 -0
- data/test/migrations/scope/1_unscoped.rb +7 -0
- data/test/migrations/scope/2_mysql_only.mysql.rb +7 -0
- data/test/models/admin/user.rb +2 -0
- data/test/models/admin/user_json.rb +48 -0
- data/test/models/attachment.rb +7 -0
- data/test/models/author.rb +70 -3
- data/test/models/author_encrypted.rb +16 -0
- data/test/models/bird.rb +1 -1
- data/test/models/book.rb +18 -11
- data/test/models/book_destroy_async.rb +1 -1
- data/test/models/book_encrypted.rb +106 -0
- data/test/models/book_identifier.rb +5 -0
- data/test/models/branch.rb +11 -0
- data/test/models/bulb.rb +1 -1
- data/test/models/car.rb +8 -1
- data/test/models/cat.rb +1 -1
- data/test/models/category.rb +3 -1
- data/test/models/chat_message.rb +8 -0
- data/test/models/chef.rb +52 -0
- data/test/models/clothing_item.rb +12 -0
- data/test/models/club.rb +4 -1
- data/test/models/comment.rb +7 -4
- data/test/models/comment_overlapping_counter_cache.rb +15 -0
- data/test/models/company.rb +16 -2
- data/test/models/computer.rb +1 -0
- data/test/models/contact.rb +3 -3
- data/test/models/contract.rb +5 -1
- data/test/models/cpk/author.rb +9 -0
- data/test/models/cpk/book.rb +55 -0
- data/test/models/cpk/book_destroy_async.rb +9 -0
- data/test/models/cpk/car.rb +9 -0
- data/test/models/cpk/car_review.rb +9 -0
- data/test/models/cpk/chapter.rb +16 -0
- data/test/models/cpk/chapter_destroy_async.rb +10 -0
- data/test/models/cpk/comment.rb +9 -0
- data/test/models/cpk/order.rb +55 -0
- data/test/models/cpk/order_agreement.rb +10 -0
- data/test/models/cpk/order_tag.rb +10 -0
- data/test/models/cpk/post.rb +10 -0
- data/test/models/cpk/posts_tag.rb +10 -0
- data/test/models/cpk/review.rb +9 -0
- data/test/models/cpk/tag.rb +10 -0
- data/test/models/cpk.rb +15 -0
- data/test/models/customer.rb +3 -1
- data/test/models/destroy_async_parent.rb +1 -1
- data/test/models/developer.rb +44 -3
- data/test/models/discount.rb +4 -0
- data/test/models/drink_designer.rb +1 -0
- data/test/models/editor.rb +8 -0
- data/test/models/editorship.rb +6 -0
- data/test/models/entry.rb +5 -0
- data/test/models/essay.rb +6 -1
- data/test/models/essay_destroy_async.rb +1 -0
- data/test/models/eye.rb +87 -21
- data/test/models/face.rb +1 -1
- data/test/models/friendship.rb +3 -0
- data/test/models/hardback.rb +7 -0
- data/test/models/hotel.rb +2 -0
- data/test/models/human.rb +2 -2
- data/test/models/invoice.rb +2 -1
- data/test/models/invokes_an_undefined_method.rb +5 -0
- data/test/models/line_item.rb +6 -0
- data/test/models/member.rb +9 -4
- data/test/models/membership.rb +2 -2
- data/test/models/message.rb +2 -1
- data/test/models/need_quoting.rb +5 -0
- data/test/models/paragraph.rb +5 -0
- data/test/models/parrot.rb +6 -3
- data/test/models/person.rb +7 -4
- data/test/models/pirate.rb +4 -1
- data/test/models/pk_autopopulated_by_a_trigger_record.rb +5 -0
- data/test/models/post.rb +65 -2
- data/test/models/post_encrypted.rb +15 -0
- data/test/models/post_with_prefetched_pk.rb +15 -0
- data/test/models/project.rb +1 -0
- data/test/models/publication.rb +16 -0
- data/test/models/raises_argument_error.rb +5 -0
- data/test/models/raises_no_method_error.rb +5 -0
- data/test/models/recipient.rb +5 -0
- data/test/models/reference.rb +1 -1
- data/test/models/reply.rb +1 -1
- data/test/models/room.rb +3 -0
- data/test/models/sharded/blog.rb +12 -0
- data/test/models/sharded/blog_post.rb +17 -0
- data/test/models/sharded/blog_post_destroy_async.rb +14 -0
- data/test/models/sharded/blog_post_tag.rb +11 -0
- data/test/models/sharded/blog_post_with_revision.rb +11 -0
- data/test/models/sharded/comment.rb +12 -0
- data/test/models/sharded/comment_destroy_async.rb +12 -0
- data/test/models/sharded/tag.rb +11 -0
- data/test/models/sharded.rb +8 -0
- data/test/models/ship.rb +1 -1
- data/test/models/shipping_line.rb +11 -0
- data/test/models/subscriber.rb +1 -0
- data/test/models/subscription.rb +3 -1
- data/test/models/too_long_table_name.rb +5 -0
- data/test/models/topic.rb +3 -1
- data/test/models/traffic_light.rb +2 -2
- data/test/models/traffic_light_encrypted.rb +21 -0
- data/test/models/translation.rb +9 -0
- data/test/models/treasure.rb +1 -1
- data/test/models/tyre.rb +1 -1
- data/test/models/user.rb +16 -0
- data/test/models/user_with_invalid_relation.rb +28 -0
- data/test/models/uuid_comment.rb +5 -0
- data/test/models/uuid_entry.rb +5 -0
- data/test/models/uuid_message.rb +5 -0
- data/test/models/zine.rb +2 -1
- data/test/schema/mysql2_specific_schema.rb +26 -12
- data/test/schema/postgresql_specific_schema.rb +121 -13
- data/test/schema/schema.rb +361 -103
- data/test/schema/sqlite_specific_schema.rb +17 -6
- data/test/schema/trilogy_specific_schema.rb +96 -0
- data/test/support/adapter_helper.rb +104 -0
- data/test/support/async_helper.rb +15 -0
- data/test/support/config.rb +1 -1
- data/test/support/connection.rb +14 -2
- data/test/support/ddl_helper.rb +1 -1
- data/test/support/fake_adapter.rb +42 -0
- data/test/support/load_schema_helper.rb +22 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic_associations.dump +0 -0
- data/test/support/schema_dumping_helper.rb +15 -9
- data/test/support/tools.rb +37 -0
- data/test/support/yaml_compatibility_fixtures/rails_4_1_no_symbol.yml +22 -0
- metadata +247 -15
|
@@ -19,6 +19,7 @@ require "models/order"
|
|
|
19
19
|
require "models/parrot"
|
|
20
20
|
require "models/pirate"
|
|
21
21
|
require "models/project"
|
|
22
|
+
require "models/price_estimate"
|
|
22
23
|
require "models/ship"
|
|
23
24
|
require "models/ship_part"
|
|
24
25
|
require "models/squeak"
|
|
@@ -34,6 +35,14 @@ require "models/organization"
|
|
|
34
35
|
require "models/guitar"
|
|
35
36
|
require "models/tuning_peg"
|
|
36
37
|
require "models/reply"
|
|
38
|
+
require "models/attachment"
|
|
39
|
+
require "models/translation"
|
|
40
|
+
require "models/chef"
|
|
41
|
+
require "models/cake_designer"
|
|
42
|
+
require "models/drink_designer"
|
|
43
|
+
require "models/cpk"
|
|
44
|
+
require "models/human"
|
|
45
|
+
require "models/face"
|
|
37
46
|
|
|
38
47
|
class TestAutosaveAssociationsInGeneral < ActiveRecord::TestCase
|
|
39
48
|
def test_autosave_works_even_when_other_callbacks_update_the_parent_model
|
|
@@ -87,6 +96,56 @@ class TestAutosaveAssociationsInGeneral < ActiveRecord::TestCase
|
|
|
87
96
|
assert_predicate r, :valid?
|
|
88
97
|
end
|
|
89
98
|
|
|
99
|
+
def test_autosave_collection_association_callbacks_get_called_once
|
|
100
|
+
ship_with_saving_stack = Class.new(Ship) do
|
|
101
|
+
def save_collection_association(reflection)
|
|
102
|
+
@count ||= 0
|
|
103
|
+
@count += 1 if reflection.name == :parts
|
|
104
|
+
super
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
ship = ship_with_saving_stack.new(name: "Nights Dirty Lightning")
|
|
109
|
+
ship.parts.build(name: "part")
|
|
110
|
+
ship.save!
|
|
111
|
+
assert_equal 1, ship.instance_variable_get(:@count)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def test_autosave_has_one_association_callbacks_get_called_once
|
|
115
|
+
# a bidirectional autosave is required to trigger multiple calls to
|
|
116
|
+
# save_has_one_association
|
|
117
|
+
assert Ship.reflect_on_association(:pirate).options[:autosave]
|
|
118
|
+
assert Pirate.reflect_on_association(:ship).options[:autosave]
|
|
119
|
+
|
|
120
|
+
pirate_with_saving_stack = Class.new(Pirate) do
|
|
121
|
+
def save_has_one_association(reflection)
|
|
122
|
+
@count ||= 0
|
|
123
|
+
@count += 1 if reflection.name == :ship
|
|
124
|
+
super
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
pirate = pirate_with_saving_stack.new(catchphrase: "Aye")
|
|
129
|
+
pirate.build_ship(name: "Nights Dirty Lightning")
|
|
130
|
+
pirate.save!
|
|
131
|
+
assert_equal 1, pirate.instance_variable_get(:@count)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def test_autosave_belongs_to_association_callbacks_get_called_once
|
|
135
|
+
ship_with_saving_stack = Class.new(Ship) do
|
|
136
|
+
def save_belongs_to_association(reflection)
|
|
137
|
+
@count ||= 0
|
|
138
|
+
@count += 1 if reflection.name == :pirate
|
|
139
|
+
super
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
ship = ship_with_saving_stack.new(name: "Nights Dirty Lightning")
|
|
144
|
+
ship.build_pirate(catchphrase: "Aye")
|
|
145
|
+
ship.save!
|
|
146
|
+
assert_equal 1, ship.instance_variable_get(:@count)
|
|
147
|
+
end
|
|
148
|
+
|
|
90
149
|
def test_should_not_add_the_same_callbacks_multiple_times_for_has_one
|
|
91
150
|
assert_no_difference_when_adding_callbacks_twice_for Pirate, :ship
|
|
92
151
|
end
|
|
@@ -114,6 +173,7 @@ class TestAutosaveAssociationsInGeneral < ActiveRecord::TestCase
|
|
|
114
173
|
private
|
|
115
174
|
def assert_no_difference_when_adding_callbacks_twice_for(model, association_name)
|
|
116
175
|
reflection = model.reflect_on_association(association_name)
|
|
176
|
+
assert_not_nil reflection
|
|
117
177
|
assert_no_difference "callbacks_for_model(#{model.name}).length" do
|
|
118
178
|
model.send(:add_autosave_association_callbacks, reflection)
|
|
119
179
|
end
|
|
@@ -213,19 +273,25 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
|
|
|
213
273
|
def test_not_resaved_when_unchanged
|
|
214
274
|
firm = Firm.all.merge!(includes: :account).first
|
|
215
275
|
firm.name += "-changed"
|
|
216
|
-
|
|
276
|
+
assert_queries_count(3) { firm.save! }
|
|
217
277
|
|
|
218
278
|
firm = Firm.first
|
|
219
279
|
firm.account = Account.first
|
|
220
|
-
|
|
280
|
+
assert_queries_count(Firm.partial_updates? ? 0 : 1) { firm.save! }
|
|
221
281
|
|
|
222
282
|
firm = Firm.first.dup
|
|
223
283
|
firm.account = Account.first
|
|
224
|
-
|
|
284
|
+
assert_queries_count(4) { firm.save! }
|
|
225
285
|
|
|
226
286
|
firm = Firm.first.dup
|
|
227
287
|
firm.account = Account.first.dup
|
|
228
|
-
|
|
288
|
+
assert_queries_count(4) { firm.save! }
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def test_should_not_load_the_associated_model
|
|
292
|
+
firm = companies(:first_firm)
|
|
293
|
+
firm.reset_unvalidated_account
|
|
294
|
+
assert_no_queries { firm.save! }
|
|
229
295
|
end
|
|
230
296
|
|
|
231
297
|
def test_callbacks_firing_order_on_create
|
|
@@ -246,6 +312,75 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
|
|
|
246
312
|
eye.update(iris_attributes: { color: "blue" })
|
|
247
313
|
assert_equal [false, false, false, false], eye.after_save_callbacks_stack
|
|
248
314
|
end
|
|
315
|
+
|
|
316
|
+
def test_callbacks_on_child_when_parent_autosaves_child
|
|
317
|
+
eye = Eye.create!(iris: Iris.new)
|
|
318
|
+
assert_equal 1, eye.iris.before_validation_callbacks_counter
|
|
319
|
+
assert_equal 1, eye.iris.before_create_callbacks_counter
|
|
320
|
+
assert_equal 1, eye.iris.before_save_callbacks_counter
|
|
321
|
+
assert_equal 1, eye.iris.after_validation_callbacks_counter
|
|
322
|
+
assert_equal 1, eye.iris.after_create_callbacks_counter
|
|
323
|
+
assert_equal 1, eye.iris.after_save_callbacks_counter
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
def test_callbacks_on_child_when_parent_autosaves_child_twice
|
|
327
|
+
eye = Eye.create!(iris: Iris.new)
|
|
328
|
+
eye.update!(iris: Iris.new)
|
|
329
|
+
assert_equal 1, eye.iris.before_validation_callbacks_counter
|
|
330
|
+
assert_equal 1, eye.iris.before_create_callbacks_counter
|
|
331
|
+
assert_equal 1, eye.iris.before_save_callbacks_counter
|
|
332
|
+
assert_equal 1, eye.iris.after_validation_callbacks_counter
|
|
333
|
+
assert_equal 1, eye.iris.after_create_callbacks_counter
|
|
334
|
+
assert_equal 1, eye.iris.after_save_callbacks_counter
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
def test_callbacks_on_child_when_parent_autosaves_polymorphic_child_with_inverse_of
|
|
338
|
+
drink_designer = DrinkDesigner.create!(chef: ChefWithPolymorphicInverseOf.new)
|
|
339
|
+
assert_equal 1, drink_designer.chef.before_validation_callbacks_counter
|
|
340
|
+
assert_equal 1, drink_designer.chef.before_create_callbacks_counter
|
|
341
|
+
assert_equal 1, drink_designer.chef.before_save_callbacks_counter
|
|
342
|
+
assert_equal 1, drink_designer.chef.after_validation_callbacks_counter
|
|
343
|
+
assert_equal 1, drink_designer.chef.after_create_callbacks_counter
|
|
344
|
+
assert_equal 1, drink_designer.chef.after_save_callbacks_counter
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
def test_callbacks_on_child_when_child_autosaves_parent
|
|
348
|
+
iris = Iris.create!(eye: Eye.new)
|
|
349
|
+
assert_equal 1, iris.before_validation_callbacks_counter
|
|
350
|
+
assert_equal 1, iris.before_create_callbacks_counter
|
|
351
|
+
assert_equal 1, iris.before_save_callbacks_counter
|
|
352
|
+
assert_equal 1, iris.after_validation_callbacks_counter
|
|
353
|
+
assert_equal 1, iris.after_create_callbacks_counter
|
|
354
|
+
assert_equal 1, iris.after_save_callbacks_counter
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
def test_callbacks_on_child_when_child_autosaves_parent_twice
|
|
358
|
+
iris = Iris.create!(eye: Eye.new)
|
|
359
|
+
iris.update!(eye: Eye.new)
|
|
360
|
+
assert_equal 2, iris.before_validation_callbacks_counter
|
|
361
|
+
assert_equal 1, iris.before_create_callbacks_counter
|
|
362
|
+
assert_equal 2, iris.before_save_callbacks_counter
|
|
363
|
+
assert_equal 2, iris.after_validation_callbacks_counter
|
|
364
|
+
assert_equal 1, iris.after_create_callbacks_counter
|
|
365
|
+
assert_equal 2, iris.after_save_callbacks_counter
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
def test_callbacks_on_child_when_polymorphic_child_with_inverse_of_autosaves_parent
|
|
369
|
+
chef = ChefWithPolymorphicInverseOf.create!(employable: DrinkDesigner.new)
|
|
370
|
+
assert_equal 1, chef.before_validation_callbacks_counter
|
|
371
|
+
assert_equal 1, chef.before_create_callbacks_counter
|
|
372
|
+
assert_equal 1, chef.before_save_callbacks_counter
|
|
373
|
+
assert_equal 1, chef.after_validation_callbacks_counter
|
|
374
|
+
assert_equal 1, chef.after_create_callbacks_counter
|
|
375
|
+
assert_equal 1, chef.after_save_callbacks_counter
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
def test_foreign_key_attribute_is_not_set_unless_changed
|
|
379
|
+
eye = Eye.create!(iris_with_read_only_foreign_key_attributes: { color: "honey" })
|
|
380
|
+
assert_nothing_raised do
|
|
381
|
+
eye.update!(override_iris_with_read_only_foreign_key_color: true)
|
|
382
|
+
end
|
|
383
|
+
end
|
|
249
384
|
end
|
|
250
385
|
|
|
251
386
|
class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase
|
|
@@ -430,6 +565,18 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test
|
|
|
430
565
|
assert_equal true, squeak.mouse.present?
|
|
431
566
|
assert_equal true, squeak.valid?
|
|
432
567
|
end
|
|
568
|
+
|
|
569
|
+
test "composite primary key autosave" do
|
|
570
|
+
assert_nothing_raised do
|
|
571
|
+
Cpk::Order.create!(id: [1, 2], book: Cpk::Book.new(title: "Book", id: [3, 4]))
|
|
572
|
+
end
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
def test_should_not_load_the_associated_model
|
|
576
|
+
tagging = taggings(:welcome_general)
|
|
577
|
+
tagging.reset_tag
|
|
578
|
+
assert_no_queries { tagging.save! }
|
|
579
|
+
end
|
|
433
580
|
end
|
|
434
581
|
|
|
435
582
|
class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttributes < ActiveRecord::TestCase
|
|
@@ -462,8 +609,8 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttrib
|
|
|
462
609
|
end
|
|
463
610
|
|
|
464
611
|
def test_errors_should_be_indexed_when_global_flag_is_set
|
|
465
|
-
old_attribute_config = ActiveRecord
|
|
466
|
-
ActiveRecord
|
|
612
|
+
old_attribute_config = ActiveRecord.index_nested_attribute_errors
|
|
613
|
+
ActiveRecord.index_nested_attribute_errors = true
|
|
467
614
|
|
|
468
615
|
molecule = Molecule.new
|
|
469
616
|
valid_electron = Electron.new(name: "electron")
|
|
@@ -477,7 +624,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttrib
|
|
|
477
624
|
assert_equal ["can't be blank"], molecule.errors["electrons[1].name"]
|
|
478
625
|
assert_not_equal ["can't be blank"], molecule.errors["electrons.name"]
|
|
479
626
|
ensure
|
|
480
|
-
ActiveRecord
|
|
627
|
+
ActiveRecord.index_nested_attribute_errors = old_attribute_config
|
|
481
628
|
end
|
|
482
629
|
|
|
483
630
|
def test_errors_details_should_be_set
|
|
@@ -508,9 +655,138 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttrib
|
|
|
508
655
|
assert_equal [], guitar.errors.details[:"tuning_pegs.pitch"]
|
|
509
656
|
end
|
|
510
657
|
|
|
658
|
+
def test_errors_details_with_error_on_base_should_be_indexed_when_passed_as_array
|
|
659
|
+
reference = Class.new(ActiveRecord::Base) do
|
|
660
|
+
self.table_name = "references"
|
|
661
|
+
def self.name; "Reference"; end
|
|
662
|
+
|
|
663
|
+
validate :should_be_favorite
|
|
664
|
+
|
|
665
|
+
private
|
|
666
|
+
def should_be_favorite
|
|
667
|
+
errors.add(:base, "should be favorite") unless favorite?
|
|
668
|
+
end
|
|
669
|
+
end
|
|
670
|
+
|
|
671
|
+
person = Class.new(ActiveRecord::Base) do
|
|
672
|
+
self.table_name = "people"
|
|
673
|
+
has_many :references, autosave: true, index_errors: true, anonymous_class: reference
|
|
674
|
+
def self.name; "Person"; end
|
|
675
|
+
end
|
|
676
|
+
|
|
677
|
+
p = person.new
|
|
678
|
+
reference_valid = reference.new(favorite: true)
|
|
679
|
+
reference_invalid = reference.new(favorite: false)
|
|
680
|
+
p.references = [reference_valid, reference_invalid]
|
|
681
|
+
|
|
682
|
+
assert_predicate reference_valid, :valid?
|
|
683
|
+
assert_not_predicate reference_invalid, :valid?
|
|
684
|
+
assert_not_predicate p, :valid?
|
|
685
|
+
assert_equal [{ error: "should be favorite" }], p.errors.details[:"references[1].base"]
|
|
686
|
+
assert_equal "should be favorite", p.errors[:"references[1].base"].first
|
|
687
|
+
assert_equal ["References[1] should be favorite"], p.errors.full_messages
|
|
688
|
+
end
|
|
689
|
+
|
|
690
|
+
def test_indexed_errors_should_be_properly_translated
|
|
691
|
+
old_i18n_customize_full_message = ActiveModel::Error.i18n_customize_full_message
|
|
692
|
+
ActiveModel::Error.i18n_customize_full_message = true
|
|
693
|
+
I18n.backend.store_translations(
|
|
694
|
+
:en,
|
|
695
|
+
activerecord: {
|
|
696
|
+
errors: {
|
|
697
|
+
models: {
|
|
698
|
+
"person/references": {
|
|
699
|
+
format: "%{message}"
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
)
|
|
705
|
+
reference = Class.new(ActiveRecord::Base) do
|
|
706
|
+
self.table_name = "references"
|
|
707
|
+
def self.name; "Reference"; end
|
|
708
|
+
|
|
709
|
+
validate :should_be_favorite
|
|
710
|
+
validates_presence_of :job_id
|
|
711
|
+
|
|
712
|
+
private
|
|
713
|
+
def should_be_favorite
|
|
714
|
+
errors.add(:base, "should be favorite") unless favorite?
|
|
715
|
+
end
|
|
716
|
+
end
|
|
717
|
+
|
|
718
|
+
person = Class.new(ActiveRecord::Base) do
|
|
719
|
+
self.table_name = "people"
|
|
720
|
+
has_many :references, autosave: true, index_errors: true, anonymous_class: reference
|
|
721
|
+
def self.name; "Person"; end
|
|
722
|
+
end
|
|
723
|
+
|
|
724
|
+
p = person.new
|
|
725
|
+
reference_valid = reference.new(favorite: true, job_id: 1)
|
|
726
|
+
reference_invalid = reference.new(favorite: false)
|
|
727
|
+
p.references = [reference_valid, reference_invalid]
|
|
728
|
+
|
|
729
|
+
assert_predicate reference_valid, :valid?
|
|
730
|
+
assert_not_predicate reference_invalid, :valid?
|
|
731
|
+
assert_not_predicate p, :valid?
|
|
732
|
+
assert_equal ["should be favorite", "can't be blank"], p.errors.full_messages
|
|
733
|
+
ensure
|
|
734
|
+
ActiveModel::Error.i18n_customize_full_message = old_i18n_customize_full_message
|
|
735
|
+
I18n.backend = I18n::Backend::Simple.new
|
|
736
|
+
end
|
|
737
|
+
|
|
738
|
+
def test_indexed_errors_on_base_attribute_should_be_properly_translated
|
|
739
|
+
I18n.backend.store_translations(
|
|
740
|
+
:en,
|
|
741
|
+
activerecord: {
|
|
742
|
+
attributes: {
|
|
743
|
+
person: {
|
|
744
|
+
reference: "Super reference",
|
|
745
|
+
},
|
|
746
|
+
reference: {
|
|
747
|
+
base: ""
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
)
|
|
752
|
+
reference = Class.new(ActiveRecord::Base) do
|
|
753
|
+
self.table_name = "references"
|
|
754
|
+
def self.name; "Reference"; end
|
|
755
|
+
|
|
756
|
+
validate :should_be_favorite
|
|
757
|
+
validates_presence_of :job_id
|
|
758
|
+
|
|
759
|
+
private
|
|
760
|
+
def should_be_favorite
|
|
761
|
+
errors.add(:base, "should be favorite") unless favorite?
|
|
762
|
+
end
|
|
763
|
+
end
|
|
764
|
+
|
|
765
|
+
person = Class.new(ActiveRecord::Base) do
|
|
766
|
+
self.table_name = "people"
|
|
767
|
+
def self.name; "Person"; end
|
|
768
|
+
|
|
769
|
+
has_one :reference, autosave: true, anonymous_class: reference
|
|
770
|
+
validates :reference, presence: true
|
|
771
|
+
end
|
|
772
|
+
|
|
773
|
+
p = person.new
|
|
774
|
+
assert_not_predicate p, :valid?
|
|
775
|
+
assert_equal ["Super reference can't be blank"], p.errors.full_messages
|
|
776
|
+
|
|
777
|
+
reference_invalid = reference.new(favorite: false)
|
|
778
|
+
p.reference = reference_invalid
|
|
779
|
+
|
|
780
|
+
assert_not_predicate reference_invalid, :valid?
|
|
781
|
+
assert_not_predicate p, :valid?
|
|
782
|
+
assert_equal [" should be favorite", "Reference job can't be blank"], p.errors.full_messages
|
|
783
|
+
ensure
|
|
784
|
+
I18n.backend = I18n::Backend::Simple.new
|
|
785
|
+
end
|
|
786
|
+
|
|
511
787
|
def test_errors_details_should_be_indexed_when_global_flag_is_set
|
|
512
|
-
old_attribute_config = ActiveRecord
|
|
513
|
-
ActiveRecord
|
|
788
|
+
old_attribute_config = ActiveRecord.index_nested_attribute_errors
|
|
789
|
+
ActiveRecord.index_nested_attribute_errors = true
|
|
514
790
|
|
|
515
791
|
molecule = Molecule.new
|
|
516
792
|
valid_electron = Electron.new(name: "electron")
|
|
@@ -524,7 +800,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttrib
|
|
|
524
800
|
assert_equal [{ error: :blank }], molecule.errors.details[:"electrons[1].name"]
|
|
525
801
|
assert_equal [], molecule.errors.details[:"electrons.name"]
|
|
526
802
|
ensure
|
|
527
|
-
ActiveRecord
|
|
803
|
+
ActiveRecord.index_nested_attribute_errors = old_attribute_config
|
|
528
804
|
end
|
|
529
805
|
|
|
530
806
|
def test_valid_adding_with_nested_attributes
|
|
@@ -541,7 +817,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttrib
|
|
|
541
817
|
end
|
|
542
818
|
|
|
543
819
|
class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCase
|
|
544
|
-
fixtures :companies, :developers
|
|
820
|
+
fixtures :companies, :developers, :cpk_order_agreements, :cpk_orders, :cpk_books
|
|
545
821
|
|
|
546
822
|
def test_invalid_adding
|
|
547
823
|
firm = Firm.find(1)
|
|
@@ -603,6 +879,37 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
|
|
|
603
879
|
assert_equal no_of_clients + 1, Client.count
|
|
604
880
|
end
|
|
605
881
|
|
|
882
|
+
def test_circular_autosave_does_not_validate_children
|
|
883
|
+
skip "DB2 limitation: circular autosave self-reference can trigger unbounded memory growth" if current_adapter?(:IBM_DBAdapter)
|
|
884
|
+
|
|
885
|
+
person = Class.new(ActiveRecord::Base) {
|
|
886
|
+
self.table_name = "readers"
|
|
887
|
+
validate :should_be_funny
|
|
888
|
+
def self.name; "Reader"; end
|
|
889
|
+
|
|
890
|
+
attribute :catch_phrase, :string
|
|
891
|
+
attribute :reader_id
|
|
892
|
+
|
|
893
|
+
has_many :children, autosave: true, anonymous_class: self
|
|
894
|
+
belongs_to :parent, autosave: true, anonymous_class: self
|
|
895
|
+
|
|
896
|
+
private
|
|
897
|
+
def should_be_funny
|
|
898
|
+
unless catch_phrase == "funny"
|
|
899
|
+
errors.add :base, "not funny"
|
|
900
|
+
end
|
|
901
|
+
end
|
|
902
|
+
}
|
|
903
|
+
c = person.new(catch_phrase: "boring")
|
|
904
|
+
c.children << c
|
|
905
|
+
c.post_id = 0
|
|
906
|
+
c.person_id = 0
|
|
907
|
+
c.save
|
|
908
|
+
|
|
909
|
+
assert_not_predicate c, :persisted?
|
|
910
|
+
assert_not_predicate c, :valid?
|
|
911
|
+
end
|
|
912
|
+
|
|
606
913
|
def test_parent_should_save_children_record_with_foreign_key_validation_set_in_before_save_callback
|
|
607
914
|
company = NewlyContractedCompany.new(name: "test")
|
|
608
915
|
|
|
@@ -675,6 +982,44 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
|
|
|
675
982
|
assert_includes firm.clients, companies(:second_client)
|
|
676
983
|
end
|
|
677
984
|
|
|
985
|
+
def test_assign_ids_with_belongs_to_cpk_model
|
|
986
|
+
order_agreements = [cpk_order_agreements(:order_agreement_one).id, cpk_order_agreements(:order_agreement_two).id]
|
|
987
|
+
order = cpk_orders(:cpk_groceries_order_1)
|
|
988
|
+
|
|
989
|
+
assert_empty order.order_agreements
|
|
990
|
+
|
|
991
|
+
order.order_agreement_ids = order_agreements
|
|
992
|
+
order.save
|
|
993
|
+
order.reload
|
|
994
|
+
|
|
995
|
+
assert_equal order_agreements, order.order_agreement_ids
|
|
996
|
+
assert_equal 2, order.order_agreements.length
|
|
997
|
+
assert_includes order.order_agreements, cpk_order_agreements(:order_agreement_two)
|
|
998
|
+
end
|
|
999
|
+
|
|
1000
|
+
def test_assign_ids_with_cpk_for_two_models
|
|
1001
|
+
book_ids = [cpk_books(:cpk_great_author_first_book).id, cpk_books(:cpk_great_author_second_book).id]
|
|
1002
|
+
order = cpk_orders(:cpk_groceries_order_1)
|
|
1003
|
+
|
|
1004
|
+
assert_empty order.books
|
|
1005
|
+
|
|
1006
|
+
order.book_ids = book_ids
|
|
1007
|
+
order.save
|
|
1008
|
+
order.reload
|
|
1009
|
+
|
|
1010
|
+
assert_equal book_ids, order.book_ids
|
|
1011
|
+
assert_equal 2, order.books.length
|
|
1012
|
+
assert_includes order.books, cpk_books(:cpk_great_author_first_book)
|
|
1013
|
+
assert_includes order.books, cpk_books(:cpk_great_author_second_book)
|
|
1014
|
+
end
|
|
1015
|
+
|
|
1016
|
+
def test_has_one_cpk_has_one_autosave_with_id
|
|
1017
|
+
book = Cpk::Book.create!(id: [1, 3], shop_id: 2)
|
|
1018
|
+
order = Cpk::OrderWithPrimaryKeyAssociatedBook.create!(book: book, shop_id: 2)
|
|
1019
|
+
|
|
1020
|
+
assert_equal(book.order.id, order.id)
|
|
1021
|
+
end
|
|
1022
|
+
|
|
678
1023
|
def test_assign_ids_for_through_a_belongs_to
|
|
679
1024
|
firm = Firm.new("name" => "Apple")
|
|
680
1025
|
firm.developer_ids = [developers(:david).id, developers(:jamis).id]
|
|
@@ -687,11 +1032,11 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
|
|
|
687
1032
|
def test_build_before_save
|
|
688
1033
|
company = companies(:first_firm)
|
|
689
1034
|
|
|
690
|
-
new_client =
|
|
1035
|
+
new_client = assert_queries_count(0) { company.clients_of_firm.build("name" => "Another Client") }
|
|
691
1036
|
assert_not_predicate company.clients_of_firm, :loaded?
|
|
692
1037
|
|
|
693
1038
|
company.name += "-changed"
|
|
694
|
-
|
|
1039
|
+
assert_queries_count(4) { assert company.save }
|
|
695
1040
|
assert_predicate new_client, :persisted?
|
|
696
1041
|
assert_equal 3, company.clients_of_firm.reload.size
|
|
697
1042
|
end
|
|
@@ -699,21 +1044,21 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
|
|
|
699
1044
|
def test_build_many_before_save
|
|
700
1045
|
company = companies(:first_firm)
|
|
701
1046
|
|
|
702
|
-
|
|
1047
|
+
assert_queries_count(0) { company.clients_of_firm.build([{ "name" => "Another Client" }, { "name" => "Another Client II" }]) }
|
|
703
1048
|
|
|
704
1049
|
company.name += "-changed"
|
|
705
|
-
|
|
1050
|
+
assert_queries_count(5) { assert company.save }
|
|
706
1051
|
assert_equal 4, company.clients_of_firm.reload.size
|
|
707
1052
|
end
|
|
708
1053
|
|
|
709
1054
|
def test_build_via_block_before_save
|
|
710
1055
|
company = companies(:first_firm)
|
|
711
1056
|
|
|
712
|
-
new_client =
|
|
1057
|
+
new_client = assert_queries_count(0) { company.clients_of_firm.build { |client| client.name = "Another Client" } }
|
|
713
1058
|
assert_not_predicate company.clients_of_firm, :loaded?
|
|
714
1059
|
|
|
715
1060
|
company.name += "-changed"
|
|
716
|
-
|
|
1061
|
+
assert_queries_count(4) { assert company.save }
|
|
717
1062
|
assert_predicate new_client, :persisted?
|
|
718
1063
|
assert_equal 3, company.clients_of_firm.reload.size
|
|
719
1064
|
end
|
|
@@ -721,14 +1066,14 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
|
|
|
721
1066
|
def test_build_many_via_block_before_save
|
|
722
1067
|
company = companies(:first_firm)
|
|
723
1068
|
|
|
724
|
-
|
|
1069
|
+
assert_queries_count(0) do
|
|
725
1070
|
company.clients_of_firm.build([{ "name" => "Another Client" }, { "name" => "Another Client II" }]) do |client|
|
|
726
1071
|
client.name = "changed"
|
|
727
1072
|
end
|
|
728
1073
|
end
|
|
729
1074
|
|
|
730
1075
|
company.name += "-changed"
|
|
731
|
-
|
|
1076
|
+
assert_queries_count(5) { assert company.save }
|
|
732
1077
|
assert_equal 4, company.clients_of_firm.reload.size
|
|
733
1078
|
end
|
|
734
1079
|
|
|
@@ -749,6 +1094,12 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
|
|
|
749
1094
|
assert_equal 2, firm.clients.length
|
|
750
1095
|
assert_includes firm.clients, Client.find_by_name("New Client")
|
|
751
1096
|
end
|
|
1097
|
+
|
|
1098
|
+
def test_should_not_load_the_associated_model
|
|
1099
|
+
firm = companies(:first_firm)
|
|
1100
|
+
firm.clients.reset
|
|
1101
|
+
assert_no_queries { firm.save! }
|
|
1102
|
+
end
|
|
752
1103
|
end
|
|
753
1104
|
|
|
754
1105
|
class TestDefaultAutosaveAssociationOnNewRecord < ActiveRecord::TestCase
|
|
@@ -846,6 +1197,8 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase
|
|
|
846
1197
|
Parrot.delete_all
|
|
847
1198
|
@ship.delete
|
|
848
1199
|
@pirate.delete
|
|
1200
|
+
Cpk::Book.delete_all
|
|
1201
|
+
Cpk::Order.delete_all
|
|
849
1202
|
end
|
|
850
1203
|
|
|
851
1204
|
# reload
|
|
@@ -935,6 +1288,18 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase
|
|
|
935
1288
|
assert_nil Pirate.find_by_id(id)
|
|
936
1289
|
end
|
|
937
1290
|
|
|
1291
|
+
# belongs_to for CPK
|
|
1292
|
+
def test_autosave_cpk_association_should_destroy_parent_association_when_marked_for_destruction
|
|
1293
|
+
book = Cpk::Book.new(title: "Book", id: [1, 2])
|
|
1294
|
+
Cpk::Order.create!(id: [3, 4], book: book)
|
|
1295
|
+
|
|
1296
|
+
book.order.mark_for_destruction
|
|
1297
|
+
|
|
1298
|
+
assert book.save
|
|
1299
|
+
assert_nil book.reload.order
|
|
1300
|
+
assert_nil Cpk::Order.find_by(id: 4, shop_id: 3)
|
|
1301
|
+
end
|
|
1302
|
+
|
|
938
1303
|
def test_should_skip_validation_on_a_parent_association_if_marked_for_destruction
|
|
939
1304
|
@ship.pirate.catchphrase = ""
|
|
940
1305
|
assert_not_predicate @ship, :valid?
|
|
@@ -1068,7 +1433,7 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase
|
|
|
1068
1433
|
end
|
|
1069
1434
|
|
|
1070
1435
|
def test_should_save_new_record_that_has_same_value_as_existing_record_marked_for_destruction_on_field_that_has_unique_index
|
|
1071
|
-
Bird.
|
|
1436
|
+
Bird.lease_connection.add_index :birds, :name, unique: true
|
|
1072
1437
|
|
|
1073
1438
|
3.times { |i| @pirate.birds.create(name: "unique_birds_#{i}") }
|
|
1074
1439
|
|
|
@@ -1078,7 +1443,7 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase
|
|
|
1078
1443
|
|
|
1079
1444
|
assert_equal 3, @pirate.birds.reload.length
|
|
1080
1445
|
ensure
|
|
1081
|
-
Bird.
|
|
1446
|
+
Bird.lease_connection.remove_index :birds, column: :name
|
|
1082
1447
|
end
|
|
1083
1448
|
|
|
1084
1449
|
# Add and remove callbacks tests for association collections.
|
|
@@ -1128,7 +1493,7 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase
|
|
|
1128
1493
|
|
|
1129
1494
|
assert_empty @pirate.reload.parrots
|
|
1130
1495
|
|
|
1131
|
-
join_records = Pirate.
|
|
1496
|
+
join_records = Pirate.lease_connection.select_all("SELECT * FROM parrots_pirates WHERE pirate_id = #{@pirate.id}")
|
|
1132
1497
|
assert_empty join_records
|
|
1133
1498
|
end
|
|
1134
1499
|
|
|
@@ -1159,6 +1524,86 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase
|
|
|
1159
1524
|
assert_predicate @pirate, :valid?
|
|
1160
1525
|
end
|
|
1161
1526
|
|
|
1527
|
+
def test_should_be_valid_on_habtm_if_persisted_and_unchanged
|
|
1528
|
+
skip "DB2 limitation: HABTM autosave validates unchanged persisted associated records" if current_adapter?(:IBM_DBAdapter)
|
|
1529
|
+
|
|
1530
|
+
parrot = @pirate.parrots.create!(name: "parrots_1")
|
|
1531
|
+
parrot.update_column(:name, "")
|
|
1532
|
+
parrot.reload
|
|
1533
|
+
assert_not_predicate parrot, :valid?
|
|
1534
|
+
|
|
1535
|
+
new_pirate = Pirate.new(catchphrase: "Arr")
|
|
1536
|
+
new_pirate.parrots = @pirate.parrots
|
|
1537
|
+
new_pirate.save!
|
|
1538
|
+
end
|
|
1539
|
+
|
|
1540
|
+
def test_should_be_invalid_on_habtm_when_any_record_in_the_association_chain_is_invalid_and_was_changed
|
|
1541
|
+
treasure = @pirate.treasures.create!(name: "gold")
|
|
1542
|
+
estimate = treasure.price_estimates.create!(price: 1)
|
|
1543
|
+
estimate.update_columns(price: "not a number")
|
|
1544
|
+
|
|
1545
|
+
assert_not_predicate estimate, :valid?
|
|
1546
|
+
|
|
1547
|
+
treasures = @pirate.treasures.eager_load(:price_estimates).to_a
|
|
1548
|
+
treasures.first.price_estimates.first.price = "not a price"
|
|
1549
|
+
new_pirate = Pirate.new(
|
|
1550
|
+
catchphrase: "Arr",
|
|
1551
|
+
treasures: treasures,
|
|
1552
|
+
)
|
|
1553
|
+
|
|
1554
|
+
assert_raises(ActiveRecord::RecordInvalid) do
|
|
1555
|
+
new_pirate.save!
|
|
1556
|
+
end
|
|
1557
|
+
assert_equal(["Treasures is invalid"], new_pirate.errors.full_messages)
|
|
1558
|
+
end
|
|
1559
|
+
|
|
1560
|
+
def test_should_be_invalid_on_habtm_when_any_record_in_the_association_chain_is_invalid_and_was_changed_with_autosave
|
|
1561
|
+
super_pirate = Class.new(Pirate) do
|
|
1562
|
+
self.table_name = "pirates"
|
|
1563
|
+
has_many :great_treasures, class_name: "Treasure", foreign_key: "looter_id", autosave: true
|
|
1564
|
+
|
|
1565
|
+
def self.name
|
|
1566
|
+
"SuperPirate"
|
|
1567
|
+
end
|
|
1568
|
+
end
|
|
1569
|
+
@pirate = super_pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?")
|
|
1570
|
+
treasure = @pirate.great_treasures.create!(name: "gold")
|
|
1571
|
+
estimate = treasure.price_estimates.create!(price: 1)
|
|
1572
|
+
estimate.update_columns(price: "not a number")
|
|
1573
|
+
|
|
1574
|
+
assert_not_predicate estimate, :valid?
|
|
1575
|
+
|
|
1576
|
+
treasures = @pirate.great_treasures.eager_load(:price_estimates).to_a
|
|
1577
|
+
treasures.first.price_estimates.first.price = "not a price"
|
|
1578
|
+
new_pirate = super_pirate.new(
|
|
1579
|
+
catchphrase: "Arr",
|
|
1580
|
+
great_treasures: treasures,
|
|
1581
|
+
)
|
|
1582
|
+
|
|
1583
|
+
assert_raises(ActiveRecord::RecordInvalid) do
|
|
1584
|
+
new_pirate.save!
|
|
1585
|
+
end
|
|
1586
|
+
assert_equal(["Great treasures price estimates price is not a number"], new_pirate.errors.full_messages)
|
|
1587
|
+
end
|
|
1588
|
+
|
|
1589
|
+
def test_should_be_valid_on_habtm_when_any_record_in_the_association_chain_is_invalid_but_was_not_changed
|
|
1590
|
+
treasure = @pirate.treasures.create!(name: "gold")
|
|
1591
|
+
estimate = treasure.price_estimates.create!(price: 1)
|
|
1592
|
+
estimate.update_columns(price: "not a number")
|
|
1593
|
+
|
|
1594
|
+
assert_not_predicate estimate, :valid?
|
|
1595
|
+
|
|
1596
|
+
treasures = @pirate.treasures.eager_load(:price_estimates).to_a
|
|
1597
|
+
new_pirate = Pirate.new(
|
|
1598
|
+
catchphrase: "Arr",
|
|
1599
|
+
treasures: treasures,
|
|
1600
|
+
)
|
|
1601
|
+
|
|
1602
|
+
assert_nothing_raised do
|
|
1603
|
+
new_pirate.save!
|
|
1604
|
+
end
|
|
1605
|
+
end
|
|
1606
|
+
|
|
1162
1607
|
def test_a_child_marked_for_destruction_should_not_be_destroyed_twice_while_saving_habtm
|
|
1163
1608
|
@pirate.parrots.create!(name: "parrots_1")
|
|
1164
1609
|
|
|
@@ -1224,7 +1669,7 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase
|
|
|
1224
1669
|
end
|
|
1225
1670
|
|
|
1226
1671
|
class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase
|
|
1227
|
-
|
|
1672
|
+
fixtures :chefs, :cake_designers, :drink_designers
|
|
1228
1673
|
|
|
1229
1674
|
def setup
|
|
1230
1675
|
super
|
|
@@ -1240,9 +1685,9 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase
|
|
|
1240
1685
|
end
|
|
1241
1686
|
|
|
1242
1687
|
def test_should_automatically_save_the_associated_model
|
|
1243
|
-
@pirate.ship.name = "The Vile
|
|
1688
|
+
@pirate.ship.name = "The Vile Serpent"
|
|
1244
1689
|
@pirate.save
|
|
1245
|
-
assert_equal "The Vile
|
|
1690
|
+
assert_equal "The Vile Serpent", @pirate.reload.ship.name
|
|
1246
1691
|
end
|
|
1247
1692
|
|
|
1248
1693
|
def test_changed_for_autosave_should_handle_cycles
|
|
@@ -1251,14 +1696,22 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase
|
|
|
1251
1696
|
|
|
1252
1697
|
@parrot = @pirate.parrots.create(name: "some_name")
|
|
1253
1698
|
@parrot.name = "changed_name"
|
|
1254
|
-
|
|
1699
|
+
assert_queries_count(3) { @ship.save! }
|
|
1255
1700
|
assert_no_queries { @ship.save! }
|
|
1256
1701
|
end
|
|
1257
1702
|
|
|
1258
1703
|
def test_should_automatically_save_bang_the_associated_model
|
|
1259
|
-
@pirate.ship.name = "The Vile
|
|
1704
|
+
@pirate.ship.name = "The Vile Serpent"
|
|
1260
1705
|
@pirate.save!
|
|
1261
|
-
assert_equal "The Vile
|
|
1706
|
+
assert_equal "The Vile Serpent", @pirate.reload.ship.name
|
|
1707
|
+
end
|
|
1708
|
+
|
|
1709
|
+
def test_should_automatically_save_bang_the_associated_model_if_it_sets_the_inverse_record
|
|
1710
|
+
pirate = Pirate.new(catchphrase: "Savvy?")
|
|
1711
|
+
ship = Ship.new(name: "Black Pearl")
|
|
1712
|
+
ship.pirate = pirate
|
|
1713
|
+
pirate.save!
|
|
1714
|
+
assert_equal "Black Pearl", pirate.reload.ship.name
|
|
1262
1715
|
end
|
|
1263
1716
|
|
|
1264
1717
|
def test_should_automatically_validate_the_associated_model
|
|
@@ -1292,12 +1745,7 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase
|
|
|
1292
1745
|
@pirate.catchphrase = ""
|
|
1293
1746
|
@pirate.ship.name = ""
|
|
1294
1747
|
@pirate.save(validate: false)
|
|
1295
|
-
|
|
1296
|
-
if current_adapter?(:OracleAdapter)
|
|
1297
|
-
assert_equal [nil, nil], [@pirate.reload.catchphrase, @pirate.ship.name]
|
|
1298
|
-
else
|
|
1299
|
-
assert_equal ["", ""], [@pirate.reload.catchphrase, @pirate.ship.name]
|
|
1300
|
-
end
|
|
1748
|
+
assert_equal ["", ""], [@pirate.reload.catchphrase, @pirate.ship.name]
|
|
1301
1749
|
end
|
|
1302
1750
|
|
|
1303
1751
|
def test_should_allow_to_bypass_validations_on_associated_models_at_any_depth
|
|
@@ -1309,12 +1757,7 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase
|
|
|
1309
1757
|
@pirate.save(validate: false)
|
|
1310
1758
|
|
|
1311
1759
|
values = [@pirate.reload.catchphrase, @pirate.ship.name, *@pirate.ship.parts.map(&:name)]
|
|
1312
|
-
|
|
1313
|
-
if current_adapter?(:OracleAdapter)
|
|
1314
|
-
assert_equal [nil, nil, nil, nil], values
|
|
1315
|
-
else
|
|
1316
|
-
assert_equal ["", "", "", ""], values
|
|
1317
|
-
end
|
|
1760
|
+
assert_equal ["", "", "", ""], values
|
|
1318
1761
|
end
|
|
1319
1762
|
|
|
1320
1763
|
def test_should_still_raise_an_ActiveRecordRecord_Invalid_exception_if_we_want_that
|
|
@@ -1326,7 +1769,7 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase
|
|
|
1326
1769
|
|
|
1327
1770
|
def test_should_not_save_and_return_false_if_a_callback_cancelled_saving
|
|
1328
1771
|
pirate = Pirate.new(catchphrase: "Arr")
|
|
1329
|
-
ship = pirate.build_ship(name: "The Vile
|
|
1772
|
+
ship = pirate.build_ship(name: "The Vile Serpent")
|
|
1330
1773
|
ship.cancel_save_from_callback = true
|
|
1331
1774
|
|
|
1332
1775
|
assert_no_difference "Pirate.count" do
|
|
@@ -1340,7 +1783,7 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase
|
|
|
1340
1783
|
before = [@pirate.catchphrase, @pirate.ship.name]
|
|
1341
1784
|
|
|
1342
1785
|
@pirate.catchphrase = "Arr"
|
|
1343
|
-
@pirate.ship.name = "The Vile
|
|
1786
|
+
@pirate.ship.name = "The Vile Serpent"
|
|
1344
1787
|
|
|
1345
1788
|
# Stub the save method of the @pirate.ship instance to raise an exception
|
|
1346
1789
|
class << @pirate.ship
|
|
@@ -1355,7 +1798,7 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase
|
|
|
1355
1798
|
end
|
|
1356
1799
|
|
|
1357
1800
|
def test_should_not_load_the_associated_model
|
|
1358
|
-
|
|
1801
|
+
assert_queries_count(3) { @pirate.catchphrase = "Arr"; @pirate.save! }
|
|
1359
1802
|
end
|
|
1360
1803
|
|
|
1361
1804
|
def test_mark_for_destruction_is_ignored_without_autosave_true
|
|
@@ -1364,11 +1807,74 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase
|
|
|
1364
1807
|
|
|
1365
1808
|
assert_not_predicate ship, :valid?
|
|
1366
1809
|
end
|
|
1810
|
+
|
|
1811
|
+
def test_should_not_saved_for_unchanged_sti_type_on_polymorphic_association
|
|
1812
|
+
skip "DB2 limitation: polymorphic autosave STI type update triggers an extra child save" if current_adapter?(:IBM_DBAdapter)
|
|
1813
|
+
|
|
1814
|
+
face = Class.new(Face) do
|
|
1815
|
+
def self.name; "Face"; end
|
|
1816
|
+
|
|
1817
|
+
after_save :count_saves
|
|
1818
|
+
|
|
1819
|
+
def count_saves
|
|
1820
|
+
@count ||= 0
|
|
1821
|
+
@count += 1
|
|
1822
|
+
end
|
|
1823
|
+
end
|
|
1824
|
+
|
|
1825
|
+
super_human = Class.new(SuperHuman) do
|
|
1826
|
+
self.table_name = "humans"
|
|
1827
|
+
def self.name; "SuperHuman"; end
|
|
1828
|
+
|
|
1829
|
+
attribute :name, :string
|
|
1830
|
+
|
|
1831
|
+
# Polymorphic has_one needs to be defined on the child class
|
|
1832
|
+
has_one :polymorphic_face, class_name: "Face", as: :polymorphic_human, inverse_of: :polymorphic_human
|
|
1833
|
+
end
|
|
1834
|
+
|
|
1835
|
+
face_record = face.create!
|
|
1836
|
+
|
|
1837
|
+
super_human_record = super_human.create!(name: "S. Human", polymorphic_face: face_record)
|
|
1838
|
+
|
|
1839
|
+
super_human_record.update!(name: "Super Human")
|
|
1840
|
+
|
|
1841
|
+
assert_equal "Human", face_record.polymorphic_human_type
|
|
1842
|
+
assert_equal super_human_record.id, face_record.polymorphic_human_id
|
|
1843
|
+
|
|
1844
|
+
# Saves on create of face and create of super human, but not update
|
|
1845
|
+
assert_equal 2, face_record.instance_variable_get(:@count)
|
|
1846
|
+
end
|
|
1847
|
+
|
|
1848
|
+
def test_recognizes_inverse_polymorphic_association_changes_with_same_foreign_key
|
|
1849
|
+
chef_a = chefs(:gordon_ramsay)
|
|
1850
|
+
chef_b = chefs(:marco_pierre_white)
|
|
1851
|
+
|
|
1852
|
+
cake_designer_a = cake_designers(:flora) # id: 1
|
|
1853
|
+
cake_designer_a.update!(chef: chef_a)
|
|
1854
|
+
cake_designer_b = cake_designers(:frosty) # id: 3
|
|
1855
|
+
cake_designer_b.update!(chef: chef_b)
|
|
1856
|
+
|
|
1857
|
+
drink_designer_a = drink_designers(:turner) # id: 1
|
|
1858
|
+
drink_designer_b = drink_designers(:sparrow) # id: 2
|
|
1859
|
+
|
|
1860
|
+
swap_chefs(cake_designer_b, drink_designer_b)
|
|
1861
|
+
assert_predicate cake_designer_b.reload.chef, :present?
|
|
1862
|
+
assert_not_predicate drink_designer_b.reload.chef, :present?
|
|
1863
|
+
|
|
1864
|
+
swap_chefs(cake_designer_a, drink_designer_a)
|
|
1865
|
+
assert_predicate cake_designer_a.reload.chef, :present?
|
|
1866
|
+
assert_not_predicate drink_designer_a.reload.chef, :present?
|
|
1867
|
+
end
|
|
1868
|
+
|
|
1869
|
+
private
|
|
1870
|
+
def swap_chefs(cake_designer, drink_designer)
|
|
1871
|
+
drink_designer.chef = cake_designer.chef
|
|
1872
|
+
drink_designer.save!
|
|
1873
|
+
cake_designer.save!
|
|
1874
|
+
end
|
|
1367
1875
|
end
|
|
1368
1876
|
|
|
1369
1877
|
class TestAutosaveAssociationOnAHasOneThroughAssociation < ActiveRecord::TestCase
|
|
1370
|
-
self.use_transactional_tests = false unless supports_savepoints?
|
|
1371
|
-
|
|
1372
1878
|
def create_member_with_organization
|
|
1373
1879
|
organization = Organization.create
|
|
1374
1880
|
member = Member.create
|
|
@@ -1412,8 +1918,6 @@ class TestAutosaveAssociationOnAHasOneThroughAssociation < ActiveRecord::TestCas
|
|
|
1412
1918
|
end
|
|
1413
1919
|
|
|
1414
1920
|
class TestAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase
|
|
1415
|
-
self.use_transactional_tests = false unless supports_savepoints?
|
|
1416
|
-
|
|
1417
1921
|
def setup
|
|
1418
1922
|
super
|
|
1419
1923
|
@ship = Ship.create(name: "Nights Dirty Lightning")
|
|
@@ -1422,9 +1926,9 @@ class TestAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase
|
|
|
1422
1926
|
|
|
1423
1927
|
def test_should_still_work_without_an_associated_model
|
|
1424
1928
|
@pirate.destroy
|
|
1425
|
-
@ship.reload.name = "The Vile
|
|
1929
|
+
@ship.reload.name = "The Vile Serpent"
|
|
1426
1930
|
@ship.save
|
|
1427
|
-
assert_equal "The Vile
|
|
1931
|
+
assert_equal "The Vile Serpent", @ship.reload.name
|
|
1428
1932
|
end
|
|
1429
1933
|
|
|
1430
1934
|
def test_should_automatically_save_the_associated_model
|
|
@@ -1457,12 +1961,7 @@ class TestAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase
|
|
|
1457
1961
|
@ship.pirate.catchphrase = ""
|
|
1458
1962
|
@ship.name = ""
|
|
1459
1963
|
@ship.save(validate: false)
|
|
1460
|
-
|
|
1461
|
-
if current_adapter?(:OracleAdapter)
|
|
1462
|
-
assert_equal [nil, nil], [@ship.reload.name, @ship.pirate.catchphrase]
|
|
1463
|
-
else
|
|
1464
|
-
assert_equal ["", ""], [@ship.reload.name, @ship.pirate.catchphrase]
|
|
1465
|
-
end
|
|
1964
|
+
assert_equal ["", ""], [@ship.reload.name, @ship.pirate.catchphrase]
|
|
1466
1965
|
end
|
|
1467
1966
|
|
|
1468
1967
|
def test_should_still_raise_an_ActiveRecordRecord_Invalid_exception_if_we_want_that
|
|
@@ -1473,7 +1972,7 @@ class TestAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase
|
|
|
1473
1972
|
end
|
|
1474
1973
|
|
|
1475
1974
|
def test_should_not_save_and_return_false_if_a_callback_cancelled_saving
|
|
1476
|
-
ship = Ship.new(name: "The Vile
|
|
1975
|
+
ship = Ship.new(name: "The Vile Serpent")
|
|
1477
1976
|
pirate = ship.build_pirate(catchphrase: "Arr")
|
|
1478
1977
|
pirate.cancel_save_from_callback = true
|
|
1479
1978
|
|
|
@@ -1488,7 +1987,7 @@ class TestAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase
|
|
|
1488
1987
|
before = [@ship.pirate.catchphrase, @ship.name]
|
|
1489
1988
|
|
|
1490
1989
|
@ship.pirate.catchphrase = "Arr"
|
|
1491
|
-
@ship.name = "The Vile
|
|
1990
|
+
@ship.name = "The Vile Serpent"
|
|
1492
1991
|
|
|
1493
1992
|
# Stub the save method of the @ship.pirate instance to raise an exception
|
|
1494
1993
|
class << @ship.pirate
|
|
@@ -1503,7 +2002,20 @@ class TestAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase
|
|
|
1503
2002
|
end
|
|
1504
2003
|
|
|
1505
2004
|
def test_should_not_load_the_associated_model
|
|
1506
|
-
|
|
2005
|
+
assert_queries_count(3) { @ship.name = "The Vile Serpent"; @ship.save! }
|
|
2006
|
+
end
|
|
2007
|
+
|
|
2008
|
+
def test_should_save_with_non_nullable_foreign_keys
|
|
2009
|
+
parent = Post.new title: "foo", body: "..."
|
|
2010
|
+
child = parent.comments.build body: "..."
|
|
2011
|
+
child.save!
|
|
2012
|
+
assert_equal child.reload.post, parent.reload
|
|
2013
|
+
end
|
|
2014
|
+
|
|
2015
|
+
def test_should_save_if_previously_saved
|
|
2016
|
+
ship = Ship.create(name: "Nights Dirty Lightning", pirate: Pirate.new(catchphrase: "Arrrr"))
|
|
2017
|
+
ship.create_pirate(catchphrase: "Savvy?")
|
|
2018
|
+
assert_equal "Savvy?", ship.reload.pirate.catchphrase
|
|
1507
2019
|
end
|
|
1508
2020
|
end
|
|
1509
2021
|
|
|
@@ -1587,20 +2099,11 @@ module AutosaveAssociationOnACollectionAssociationTests
|
|
|
1587
2099
|
@pirate.public_send(@association_name).each { |child| child.name = "" }
|
|
1588
2100
|
|
|
1589
2101
|
assert @pirate.save(validate: false)
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
@pirate.public_send(@association_name).last.name
|
|
1596
|
-
]
|
|
1597
|
-
else
|
|
1598
|
-
assert_equal ["", "", ""], [
|
|
1599
|
-
@pirate.reload.catchphrase,
|
|
1600
|
-
@pirate.public_send(@association_name).first.name,
|
|
1601
|
-
@pirate.public_send(@association_name).last.name
|
|
1602
|
-
]
|
|
1603
|
-
end
|
|
2102
|
+
assert_equal ["", "", ""], [
|
|
2103
|
+
@pirate.reload.catchphrase,
|
|
2104
|
+
@pirate.public_send(@association_name).first.name,
|
|
2105
|
+
@pirate.public_send(@association_name).last.name
|
|
2106
|
+
]
|
|
1604
2107
|
end
|
|
1605
2108
|
|
|
1606
2109
|
def test_should_validation_the_associated_models_on_create
|
|
@@ -1664,11 +2167,11 @@ module AutosaveAssociationOnACollectionAssociationTests
|
|
|
1664
2167
|
end
|
|
1665
2168
|
|
|
1666
2169
|
def test_should_not_load_the_associated_models_if_they_were_not_loaded_yet
|
|
1667
|
-
|
|
2170
|
+
assert_queries_count(3) { @pirate.catchphrase = "Arr"; @pirate.save! }
|
|
1668
2171
|
|
|
1669
2172
|
@pirate.public_send(@association_name).load_target
|
|
1670
2173
|
|
|
1671
|
-
|
|
2174
|
+
assert_queries_count(5) do
|
|
1672
2175
|
@pirate.catchphrase = "Yarr"
|
|
1673
2176
|
new_names = ["Grace OMalley", "Privateers Greed"]
|
|
1674
2177
|
@pirate.public_send(@association_name).each_with_index { |child, i| child.name = new_names[i] }
|
|
@@ -1678,8 +2181,6 @@ module AutosaveAssociationOnACollectionAssociationTests
|
|
|
1678
2181
|
end
|
|
1679
2182
|
|
|
1680
2183
|
class TestAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCase
|
|
1681
|
-
self.use_transactional_tests = false unless supports_savepoints?
|
|
1682
|
-
|
|
1683
2184
|
def setup
|
|
1684
2185
|
super
|
|
1685
2186
|
@association_name = :birds
|
|
@@ -1694,8 +2195,6 @@ class TestAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCase
|
|
|
1694
2195
|
end
|
|
1695
2196
|
|
|
1696
2197
|
class TestAutosaveAssociationOnAHasAndBelongsToManyAssociation < ActiveRecord::TestCase
|
|
1697
|
-
self.use_transactional_tests = false unless supports_savepoints?
|
|
1698
|
-
|
|
1699
2198
|
def setup
|
|
1700
2199
|
super
|
|
1701
2200
|
@association_name = :autosaved_parrots
|
|
@@ -1711,8 +2210,6 @@ class TestAutosaveAssociationOnAHasAndBelongsToManyAssociation < ActiveRecord::T
|
|
|
1711
2210
|
end
|
|
1712
2211
|
|
|
1713
2212
|
class TestAutosaveAssociationOnAHasAndBelongsToManyAssociationWithAcceptsNestedAttributes < ActiveRecord::TestCase
|
|
1714
|
-
self.use_transactional_tests = false unless supports_savepoints?
|
|
1715
|
-
|
|
1716
2213
|
def setup
|
|
1717
2214
|
super
|
|
1718
2215
|
@association_name = :parrots
|
|
@@ -1728,8 +2225,6 @@ class TestAutosaveAssociationOnAHasAndBelongsToManyAssociationWithAcceptsNestedA
|
|
|
1728
2225
|
end
|
|
1729
2226
|
|
|
1730
2227
|
class TestAutosaveAssociationValidationsOnAHasManyAssociation < ActiveRecord::TestCase
|
|
1731
|
-
self.use_transactional_tests = false unless supports_savepoints?
|
|
1732
|
-
|
|
1733
2228
|
def setup
|
|
1734
2229
|
super
|
|
1735
2230
|
@pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?")
|
|
@@ -1787,14 +2282,12 @@ class TestAutosaveAssociationValidationsOnAHasManyAssociation < ActiveRecord::Te
|
|
|
1787
2282
|
pirate = FamousPirate.create!(catchphrase: "Avast Ye!")
|
|
1788
2283
|
pirate.famous_ships.create!
|
|
1789
2284
|
|
|
1790
|
-
|
|
2285
|
+
assert_predicate pirate, :valid?
|
|
1791
2286
|
assert_not pirate.valid?(:conference)
|
|
1792
2287
|
end
|
|
1793
2288
|
end
|
|
1794
2289
|
|
|
1795
2290
|
class TestAutosaveAssociationValidationsOnAHasOneAssociation < ActiveRecord::TestCase
|
|
1796
|
-
self.use_transactional_tests = false unless supports_savepoints?
|
|
1797
|
-
|
|
1798
2291
|
def setup
|
|
1799
2292
|
super
|
|
1800
2293
|
@pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?")
|
|
@@ -1816,8 +2309,6 @@ class TestAutosaveAssociationValidationsOnAHasOneAssociation < ActiveRecord::Tes
|
|
|
1816
2309
|
end
|
|
1817
2310
|
|
|
1818
2311
|
class TestAutosaveAssociationValidationsOnABelongsToAssociation < ActiveRecord::TestCase
|
|
1819
|
-
self.use_transactional_tests = false unless supports_savepoints?
|
|
1820
|
-
|
|
1821
2312
|
def setup
|
|
1822
2313
|
super
|
|
1823
2314
|
@pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?")
|
|
@@ -1838,14 +2329,12 @@ class TestAutosaveAssociationValidationsOnABelongsToAssociation < ActiveRecord::
|
|
|
1838
2329
|
def test_validations_still_fire_on_unchanged_association_with_custom_validation_context
|
|
1839
2330
|
firm_with_low_credit = Firm.create!(name: "Something", account: Account.new(credit_limit: 50))
|
|
1840
2331
|
|
|
1841
|
-
|
|
2332
|
+
assert_predicate firm_with_low_credit, :valid?
|
|
1842
2333
|
assert_not firm_with_low_credit.valid?(:bank_loan)
|
|
1843
2334
|
end
|
|
1844
2335
|
end
|
|
1845
2336
|
|
|
1846
2337
|
class TestAutosaveAssociationValidationsOnAHABTMAssociation < ActiveRecord::TestCase
|
|
1847
|
-
self.use_transactional_tests = false unless supports_savepoints?
|
|
1848
|
-
|
|
1849
2338
|
def setup
|
|
1850
2339
|
super
|
|
1851
2340
|
@pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?")
|
|
@@ -1867,8 +2356,6 @@ class TestAutosaveAssociationValidationsOnAHABTMAssociation < ActiveRecord::Test
|
|
|
1867
2356
|
end
|
|
1868
2357
|
|
|
1869
2358
|
class TestAutosaveAssociationValidationMethodsGeneration < ActiveRecord::TestCase
|
|
1870
|
-
self.use_transactional_tests = false unless supports_savepoints?
|
|
1871
|
-
|
|
1872
2359
|
def setup
|
|
1873
2360
|
super
|
|
1874
2361
|
@pirate = Pirate.new
|
|
@@ -1951,3 +2438,69 @@ class TestAutosaveAssociationOnAHasManyAssociationDefinedInSubclassWithAcceptsNe
|
|
|
1951
2438
|
assert_equal "Updated", valid_project.name
|
|
1952
2439
|
end
|
|
1953
2440
|
end
|
|
2441
|
+
|
|
2442
|
+
class TestAutosaveAssociationOnABelongsToAssociationDefinedAsRecord < ActiveRecord::TestCase
|
|
2443
|
+
def test_should_not_raise_error
|
|
2444
|
+
translation = Translation.create(locale: "fr", key: "bread", value: "Baguette 🥖")
|
|
2445
|
+
author = Author.create(name: "Dorian Marié")
|
|
2446
|
+
translation.build_attachment(record: author)
|
|
2447
|
+
assert_nothing_raised do
|
|
2448
|
+
translation.save!
|
|
2449
|
+
end
|
|
2450
|
+
end
|
|
2451
|
+
end
|
|
2452
|
+
|
|
2453
|
+
class TestAutosaveAssociationWithNestedAttributes < ActiveRecord::TestCase
|
|
2454
|
+
class Part < ActiveRecord::Base
|
|
2455
|
+
self.table_name = "ship_parts"
|
|
2456
|
+
end
|
|
2457
|
+
|
|
2458
|
+
class Ship < ActiveRecord::Base
|
|
2459
|
+
self.table_name = "ships"
|
|
2460
|
+
has_many :parts, class_name: Part.name
|
|
2461
|
+
accepts_nested_attributes_for :parts, allow_destroy: true
|
|
2462
|
+
|
|
2463
|
+
validate :has_at_least_two_parts
|
|
2464
|
+
def has_at_least_two_parts
|
|
2465
|
+
current_parts = parts.select { |p| !p.marked_for_destruction? }
|
|
2466
|
+
errors.add(:parts, "must have at least two parts") if current_parts.size < 2
|
|
2467
|
+
end
|
|
2468
|
+
end
|
|
2469
|
+
|
|
2470
|
+
class Pirate < ActiveRecord::Base
|
|
2471
|
+
self.table_name = "pirates"
|
|
2472
|
+
has_many :ships, class_name: Ship.name
|
|
2473
|
+
accepts_nested_attributes_for :ships, allow_destroy: true
|
|
2474
|
+
end
|
|
2475
|
+
|
|
2476
|
+
def test_should_be_invalid_when_nested_attributes_deletion_breaks_validation
|
|
2477
|
+
pirate = Pirate.create!
|
|
2478
|
+
ship = pirate.ships.new
|
|
2479
|
+
2.times do |i|
|
|
2480
|
+
ship.parts.build
|
|
2481
|
+
end
|
|
2482
|
+
part = ship.parts.first
|
|
2483
|
+
ship.save!
|
|
2484
|
+
|
|
2485
|
+
deletion_params = {
|
|
2486
|
+
"ships_attributes" => {
|
|
2487
|
+
"0" => {
|
|
2488
|
+
"id" => ship.id,
|
|
2489
|
+
"parts_attributes" => {
|
|
2490
|
+
"0" => {
|
|
2491
|
+
"id" => part.id,
|
|
2492
|
+
"_destroy" => "1",
|
|
2493
|
+
},
|
|
2494
|
+
}
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2497
|
+
}
|
|
2498
|
+
|
|
2499
|
+
assert_not pirate.update(deletion_params)
|
|
2500
|
+
assert_nothing_raised do
|
|
2501
|
+
part.reload
|
|
2502
|
+
end
|
|
2503
|
+
assert_includes pirate.errors[:"ships.parts"], "must have at least two parts"
|
|
2504
|
+
assert_includes ship.errors[:parts], "must have at least two parts"
|
|
2505
|
+
end
|
|
2506
|
+
end
|