ibm_db 5.2.0-x86-mingw32 → 5.4.0-x86-mingw32
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/CHANGES +9 -0
 - data/LICENSE +55 -18
 - data/README +1 -1
 - data/debug.log +1 -0
 - data/ext/Makefile +28 -24
 - data/ext/ibm_db.c +66 -65
 - data/ext/ibm_db.o +0 -0
 - data/ext/ibm_db.so +0 -0
 - data/ext/mkmf.log +26 -24
 - data/ext/ruby_ibm_db_cli.c +1 -0
 - data/ext/ruby_ibm_db_cli.o +0 -0
 - data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1520 -1282
 - data/lib/ibm_db.so +1 -0
 - data/lib/mswin32/ibm_db.rb +3 -1
 - data/lib/mswin32/rb3x/i386/ruby30/ibm_db.so +0 -0
 - data/lib/mswin32/rb3x/i386/ruby31/ibm_db.so +0 -0
 - data/test/active_record/connection_adapters/fake_adapter.rb +5 -2
 - data/test/activejob/destroy_association_async_test.rb +305 -0
 - data/test/activejob/destroy_async_job_not_present_test.rb +31 -0
 - data/test/activejob/helper.rb +15 -0
 - data/test/assets/schema_dump_5_1.yml +345 -0
 - data/test/cases/adapter_prevent_writes_test.rb +334 -0
 - data/test/cases/adapter_test.rb +432 -218
 - data/test/cases/adapters/mysql2/active_schema_test.rb +85 -75
 - data/test/cases/adapters/mysql2/auto_increment_test.rb +34 -0
 - data/test/cases/adapters/mysql2/bind_parameter_test.rb +5 -3
 - data/test/cases/adapters/mysql2/boolean_test.rb +6 -4
 - data/test/cases/adapters/mysql2/case_sensitivity_test.rb +26 -24
 - data/test/cases/adapters/mysql2/charset_collation_test.rb +20 -17
 - data/test/cases/adapters/mysql2/connection_test.rb +48 -50
 - data/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb +28 -0
 - data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +23 -19
 - data/test/cases/adapters/mysql2/enum_test.rb +32 -11
 - data/test/cases/adapters/mysql2/explain_test.rb +13 -11
 - data/test/cases/adapters/mysql2/json_test.rb +17 -188
 - data/test/cases/adapters/mysql2/mysql2_adapter_prevent_writes_test.rb +208 -0
 - data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +183 -28
 - data/test/cases/adapters/mysql2/nested_deadlock_test.rb +75 -0
 - data/test/cases/adapters/mysql2/optimizer_hints_test.rb +69 -0
 - data/test/cases/adapters/mysql2/schema_migrations_test.rb +26 -21
 - data/test/cases/adapters/mysql2/schema_test.rb +24 -22
 - data/test/cases/adapters/mysql2/set_test.rb +32 -0
 - data/test/cases/adapters/mysql2/sp_test.rb +10 -8
 - data/test/cases/adapters/mysql2/sql_types_test.rb +8 -6
 - data/test/cases/adapters/mysql2/table_options_test.rb +93 -10
 - data/test/cases/adapters/mysql2/transaction_test.rb +151 -0
 - data/test/cases/adapters/mysql2/unsigned_type_test.rb +11 -9
 - data/test/cases/adapters/mysql2/virtual_column_test.rb +66 -0
 - data/test/cases/adapters/postgresql/active_schema_test.rb +40 -25
 - data/test/cases/adapters/postgresql/array_test.rb +118 -63
 - data/test/cases/adapters/postgresql/bit_string_test.rb +12 -10
 - data/test/cases/adapters/postgresql/bytea_test.rb +26 -25
 - data/test/cases/adapters/postgresql/case_insensitive_test.rb +10 -9
 - data/test/cases/adapters/postgresql/change_schema_test.rb +7 -5
 - data/test/cases/adapters/postgresql/cidr_test.rb +2 -0
 - data/test/cases/adapters/postgresql/citext_test.rb +58 -58
 - data/test/cases/adapters/postgresql/collation_test.rb +17 -15
 - data/test/cases/adapters/postgresql/composite_test.rb +25 -23
 - data/test/cases/adapters/postgresql/connection_test.rb +73 -85
 - data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +74 -0
 - data/test/cases/adapters/postgresql/datatype_test.rb +19 -22
 - data/test/cases/adapters/postgresql/date_test.rb +42 -0
 - data/test/cases/adapters/postgresql/domain_test.rb +9 -7
 - data/test/cases/adapters/postgresql/enum_test.rb +12 -10
 - data/test/cases/adapters/postgresql/explain_test.rb +10 -8
 - data/test/cases/adapters/postgresql/extension_migration_test.rb +13 -12
 - data/test/cases/adapters/postgresql/foreign_table_test.rb +109 -0
 - data/test/cases/adapters/postgresql/full_text_test.rb +8 -6
 - data/test/cases/adapters/postgresql/geometric_test.rb +57 -63
 - data/test/cases/adapters/postgresql/hstore_test.rb +288 -280
 - data/test/cases/adapters/postgresql/infinity_test.rb +54 -15
 - data/test/cases/adapters/postgresql/integer_test.rb +2 -0
 - data/test/cases/adapters/postgresql/interval_test.rb +99 -0
 - data/test/cases/adapters/postgresql/json_test.rb +16 -201
 - data/test/cases/adapters/postgresql/ltree_test.rb +14 -16
 - data/test/cases/adapters/postgresql/money_test.rb +47 -16
 - data/test/cases/adapters/postgresql/network_test.rb +36 -28
 - data/test/cases/adapters/postgresql/numbers_test.rb +7 -5
 - data/test/cases/adapters/postgresql/optimizer_hints_test.rb +71 -0
 - data/test/cases/adapters/postgresql/partitions_test.rb +22 -0
 - data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +205 -0
 - data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +178 -136
 - data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +27 -0
 - data/test/cases/adapters/postgresql/quoting_test.rb +12 -6
 - data/test/cases/adapters/postgresql/range_test.rb +406 -292
 - data/test/cases/adapters/postgresql/referential_integrity_test.rb +16 -15
 - data/test/cases/adapters/postgresql/rename_table_test.rb +9 -8
 - data/test/cases/adapters/postgresql/schema_authorization_test.rb +14 -23
 - data/test/cases/adapters/postgresql/schema_test.rb +207 -91
 - data/test/cases/adapters/postgresql/serial_test.rb +9 -7
 - data/test/cases/adapters/postgresql/statement_pool_test.rb +26 -6
 - data/test/cases/adapters/postgresql/timestamp_test.rb +17 -15
 - data/test/cases/adapters/postgresql/transaction_nested_test.rb +114 -0
 - data/test/cases/adapters/postgresql/transaction_test.rb +189 -0
 - data/test/cases/adapters/postgresql/type_lookup_test.rb +12 -10
 - data/test/cases/adapters/postgresql/utils_test.rb +11 -9
 - data/test/cases/adapters/postgresql/uuid_test.rb +226 -109
 - data/test/cases/adapters/postgresql/xml_test.rb +10 -14
 - data/test/cases/adapters/sqlite3/collation_test.rb +26 -15
 - data/test/cases/adapters/sqlite3/copy_table_test.rb +31 -28
 - data/test/cases/adapters/sqlite3/explain_test.rb +13 -11
 - data/test/cases/adapters/sqlite3/json_test.rb +29 -0
 - data/test/cases/adapters/sqlite3/quoting_test.rb +35 -57
 - data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +186 -0
 - data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +318 -131
 - data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +11 -11
 - data/test/cases/adapters/sqlite3/statement_pool_test.rb +7 -6
 - data/test/cases/adapters/sqlite3/transaction_test.rb +123 -0
 - data/test/cases/aggregations_test.rb +14 -12
 - data/test/cases/annotate_test.rb +46 -0
 - data/test/cases/ar_schema_test.rb +153 -86
 - data/test/cases/arel/attributes/attribute_test.rb +1145 -0
 - data/test/cases/arel/attributes/math_test.rb +83 -0
 - data/test/cases/arel/attributes_test.rb +27 -0
 - data/test/cases/arel/collectors/bind_test.rb +40 -0
 - data/test/cases/arel/collectors/composite_test.rb +47 -0
 - data/test/cases/arel/collectors/sql_string_test.rb +41 -0
 - data/test/cases/arel/collectors/substitute_bind_collector_test.rb +48 -0
 - data/test/cases/arel/crud_test.rb +65 -0
 - data/test/cases/arel/delete_manager_test.rb +53 -0
 - data/test/cases/arel/factory_methods_test.rb +46 -0
 - data/test/cases/arel/helper.rb +45 -0
 - data/test/cases/arel/insert_manager_test.rb +241 -0
 - data/test/cases/arel/nodes/and_test.rb +30 -0
 - data/test/cases/arel/nodes/as_test.rb +36 -0
 - data/test/cases/arel/nodes/ascending_test.rb +46 -0
 - data/test/cases/arel/nodes/bin_test.rb +35 -0
 - data/test/cases/arel/nodes/binary_test.rb +29 -0
 - data/test/cases/arel/nodes/bind_param_test.rb +22 -0
 - data/test/cases/arel/nodes/case_test.rb +96 -0
 - data/test/cases/arel/nodes/casted_test.rb +18 -0
 - data/test/cases/arel/nodes/comment_test.rb +22 -0
 - data/test/cases/arel/nodes/count_test.rb +35 -0
 - data/test/cases/arel/nodes/delete_statement_test.rb +36 -0
 - data/test/cases/arel/nodes/descending_test.rb +46 -0
 - data/test/cases/arel/nodes/distinct_test.rb +21 -0
 - data/test/cases/arel/nodes/equality_test.rb +62 -0
 - data/test/cases/arel/nodes/extract_test.rb +43 -0
 - data/test/cases/arel/nodes/false_test.rb +21 -0
 - data/test/cases/arel/nodes/grouping_test.rb +26 -0
 - data/test/cases/arel/nodes/infix_operation_test.rb +42 -0
 - data/test/cases/arel/nodes/insert_statement_test.rb +44 -0
 - data/test/cases/arel/nodes/named_function_test.rb +48 -0
 - data/test/cases/arel/nodes/node_test.rb +22 -0
 - data/test/cases/arel/nodes/not_test.rb +31 -0
 - data/test/cases/arel/nodes/or_test.rb +36 -0
 - data/test/cases/arel/nodes/over_test.rb +69 -0
 - data/test/cases/arel/nodes/select_core_test.rb +79 -0
 - data/test/cases/arel/nodes/select_statement_test.rb +51 -0
 - data/test/cases/arel/nodes/sql_literal_test.rb +75 -0
 - data/test/cases/arel/nodes/sum_test.rb +35 -0
 - data/test/cases/arel/nodes/table_alias_test.rb +29 -0
 - data/test/cases/arel/nodes/true_test.rb +21 -0
 - data/test/cases/arel/nodes/unary_operation_test.rb +41 -0
 - data/test/cases/arel/nodes/update_statement_test.rb +60 -0
 - data/test/cases/arel/nodes/window_test.rb +81 -0
 - data/test/cases/arel/nodes_test.rb +34 -0
 - data/test/cases/arel/select_manager_test.rb +1238 -0
 - data/test/cases/arel/support/fake_record.rb +135 -0
 - data/test/cases/arel/table_test.rb +216 -0
 - data/test/cases/arel/update_manager_test.rb +126 -0
 - data/test/cases/arel/visitors/dispatch_contamination_test.rb +78 -0
 - data/test/cases/arel/visitors/dot_test.rb +90 -0
 - data/test/cases/arel/visitors/mysql_test.rb +157 -0
 - data/test/cases/arel/visitors/postgres_test.rb +366 -0
 - data/test/cases/arel/visitors/sqlite_test.rb +75 -0
 - data/test/cases/arel/visitors/to_sql_test.rb +750 -0
 - data/test/cases/associations/belongs_to_associations_test.rb +510 -158
 - data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +4 -2
 - data/test/cases/associations/callbacks_test.rb +56 -38
 - data/test/cases/associations/cascaded_eager_loading_test.rb +118 -61
 - data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +138 -18
 - data/test/cases/associations/eager_load_nested_include_test.rb +38 -37
 - data/test/cases/associations/eager_singularization_test.rb +21 -21
 - data/test/cases/associations/eager_test.rb +559 -415
 - data/test/cases/associations/extension_test.rb +18 -12
 - data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +234 -213
 - data/test/cases/associations/has_many_associations_test.rb +1038 -465
 - data/test/cases/associations/has_many_through_associations_test.rb +558 -249
 - data/test/cases/associations/has_one_associations_test.rb +294 -129
 - data/test/cases/associations/has_one_through_associations_test.rb +121 -75
 - data/test/cases/associations/inner_join_association_test.rb +114 -38
 - data/test/cases/associations/inverse_associations_test.rb +606 -398
 - data/test/cases/associations/join_model_test.rb +158 -148
 - data/test/cases/associations/left_outer_join_association_test.rb +59 -24
 - data/test/cases/associations/nested_through_associations_test.rb +166 -109
 - data/test/cases/associations/required_test.rb +35 -10
 - data/test/cases/associations_test.rb +241 -110
 - data/test/cases/attribute_methods/read_test.rb +11 -11
 - data/test/cases/attribute_methods_test.rb +413 -298
 - data/test/cases/attributes_test.rb +145 -27
 - data/test/cases/autosave_association_test.rb +681 -436
 - data/test/cases/base_prevent_writes_test.rb +229 -0
 - data/test/cases/base_test.rb +599 -542
 - data/test/cases/batches_test.rb +288 -82
 - data/test/cases/binary_test.rb +26 -31
 - data/test/cases/bind_parameter_test.rb +194 -21
 - data/test/cases/boolean_test.rb +52 -0
 - data/test/cases/cache_key_test.rb +110 -5
 - data/test/cases/calculations_test.rb +740 -177
 - data/test/cases/callbacks_test.rb +74 -207
 - data/test/cases/clone_test.rb +15 -10
 - data/test/cases/coders/json_test.rb +2 -0
 - data/test/cases/coders/yaml_column_test.rb +16 -13
 - data/test/cases/collection_cache_key_test.rb +177 -20
 - data/test/cases/column_alias_test.rb +9 -7
 - data/test/cases/column_definition_test.rb +10 -68
 - data/test/cases/comment_test.rb +166 -107
 - data/test/cases/connection_adapters/adapter_leasing_test.rb +14 -10
 - data/test/cases/connection_adapters/connection_handler_test.rb +358 -51
 - data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +400 -0
 - data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +103 -0
 - data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +499 -0
 - data/test/cases/connection_adapters/connection_swapping_nested_test.rb +457 -0
 - data/test/cases/connection_adapters/legacy_connection_handlers_multi_db_test.rb +486 -0
 - data/test/cases/connection_adapters/legacy_connection_handlers_sharding_db_test.rb +586 -0
 - data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +319 -138
 - data/test/cases/connection_adapters/mysql_type_lookup_test.rb +62 -50
 - data/test/cases/connection_adapters/schema_cache_test.rb +259 -26
 - data/test/cases/connection_adapters/type_lookup_test.rb +96 -95
 - data/test/cases/connection_management_test.rb +13 -11
 - data/test/cases/connection_pool_test.rb +316 -83
 - data/test/cases/core_test.rb +82 -58
 - data/test/cases/counter_cache_test.rb +204 -50
 - data/test/cases/custom_locking_test.rb +5 -3
 - data/test/cases/database_configurations/hash_config_test.rb +74 -0
 - data/test/cases/database_configurations/resolver_test.rb +150 -0
 - data/test/cases/database_configurations_test.rb +145 -0
 - data/test/cases/database_selector_test.rb +296 -0
 - data/test/cases/database_statements_test.rb +18 -16
 - data/test/cases/date_test.rb +8 -16
 - data/test/cases/date_time_precision_test.rb +100 -78
 - data/test/cases/date_time_test.rb +23 -8
 - data/test/cases/defaults_test.rb +106 -71
 - data/test/cases/delegated_type_test.rb +57 -0
 - data/test/cases/dirty_test.rb +419 -223
 - data/test/cases/disconnected_test.rb +6 -6
 - data/test/cases/dup_test.rb +54 -27
 - data/test/cases/enum_test.rb +461 -82
 - data/test/cases/errors_test.rb +7 -7
 - data/test/cases/explain_subscriber_test.rb +17 -15
 - data/test/cases/explain_test.rb +11 -19
 - data/test/cases/filter_attributes_test.rb +153 -0
 - data/test/cases/finder_respond_to_test.rb +14 -14
 - data/test/cases/finder_test.rb +669 -287
 - data/test/cases/fixture_set/file_test.rb +34 -38
 - data/test/cases/fixtures_test.rb +833 -176
 - data/test/cases/forbidden_attributes_protection_test.rb +32 -67
 - data/test/cases/habtm_destroy_order_test.rb +25 -25
 - data/test/cases/helper.rb +78 -49
 - data/test/cases/hot_compatibility_test.rb +33 -32
 - data/test/cases/i18n_test.rb +18 -17
 - data/test/cases/inheritance_test.rb +180 -115
 - data/test/cases/insert_all_test.rb +489 -0
 - data/test/cases/instrumentation_test.rb +101 -0
 - data/test/cases/integration_test.rb +119 -31
 - data/test/cases/invalid_connection_test.rb +18 -16
 - data/test/cases/invertible_migration_test.rb +183 -43
 - data/test/cases/json_attribute_test.rb +35 -0
 - data/test/cases/json_serialization_test.rb +57 -58
 - data/test/cases/json_shared_test_cases.rb +290 -0
 - data/test/cases/locking_test.rb +413 -119
 - data/test/cases/log_subscriber_test.rb +68 -26
 - data/test/cases/marshal_serialization_test.rb +39 -0
 - data/test/cases/migration/change_schema_test.rb +118 -72
 - data/test/cases/migration/change_table_test.rb +138 -30
 - data/test/cases/migration/check_constraint_test.rb +162 -0
 - data/test/cases/migration/column_attributes_test.rb +45 -35
 - data/test/cases/migration/column_positioning_test.rb +18 -6
 - data/test/cases/migration/columns_test.rb +93 -77
 - data/test/cases/migration/command_recorder_test.rb +121 -34
 - data/test/cases/migration/compatibility_test.rb +578 -23
 - data/test/cases/migration/create_join_table_test.rb +35 -25
 - data/test/cases/migration/foreign_key_test.rb +503 -284
 - data/test/cases/migration/helper.rb +4 -3
 - data/test/cases/migration/index_test.rb +119 -70
 - data/test/cases/migration/logger_test.rb +9 -6
 - data/test/cases/migration/pending_migrations_test.rb +88 -34
 - data/test/cases/migration/references_foreign_key_test.rb +164 -150
 - data/test/cases/migration/references_index_test.rb +38 -19
 - data/test/cases/migration/references_statements_test.rb +15 -14
 - data/test/cases/migration/rename_table_test.rb +53 -30
 - data/test/cases/migration_test.rb +637 -269
 - data/test/cases/migrator_test.rb +191 -135
 - data/test/cases/mixin_test.rb +7 -11
 - data/test/cases/modules_test.rb +36 -34
 - data/test/cases/multi_db_migrator_test.rb +223 -0
 - data/test/cases/multiparameter_attributes_test.rb +60 -33
 - data/test/cases/multiple_db_test.rb +16 -22
 - data/test/cases/nested_attributes_test.rb +341 -320
 - data/test/cases/nested_attributes_with_callbacks_test.rb +26 -24
 - data/test/cases/null_relation_test.rb +84 -0
 - data/test/cases/numeric_data_test.rb +93 -0
 - data/test/cases/persistence_test.rb +361 -269
 - data/test/cases/pooled_connections_test.rb +18 -26
 - data/test/cases/prepared_statement_status_test.rb +48 -0
 - data/test/cases/primary_keys_test.rb +210 -104
 - data/test/cases/query_cache_test.rb +610 -141
 - data/test/cases/quoting_test.rb +132 -31
 - data/test/cases/readonly_test.rb +49 -48
 - data/test/cases/reaper_test.rb +146 -32
 - data/test/cases/reflection_test.rb +167 -156
 - data/test/cases/relation/delegation_test.rb +49 -36
 - data/test/cases/relation/delete_all_test.rb +117 -0
 - data/test/cases/relation/merging_test.rb +319 -42
 - data/test/cases/relation/mutation_test.rb +55 -93
 - data/test/cases/relation/or_test.rb +129 -29
 - data/test/cases/relation/predicate_builder_test.rb +21 -6
 - data/test/cases/relation/record_fetch_warning_test.rb +5 -3
 - data/test/cases/relation/select_test.rb +67 -0
 - data/test/cases/relation/update_all_test.rb +317 -0
 - data/test/cases/relation/where_chain_test.rb +68 -32
 - data/test/cases/relation/where_clause_test.rb +136 -61
 - data/test/cases/relation/where_test.rb +155 -48
 - data/test/cases/relation_test.rb +266 -112
 - data/test/cases/relations_test.rb +969 -744
 - data/test/cases/reload_models_test.rb +13 -9
 - data/test/cases/reserved_word_test.rb +141 -0
 - data/test/cases/result_test.rb +68 -17
 - data/test/cases/sanitize_test.rb +87 -71
 - data/test/cases/schema_dumper_test.rb +221 -128
 - data/test/cases/schema_loading_test.rb +3 -2
 - data/test/cases/scoping/default_scoping_test.rb +185 -144
 - data/test/cases/scoping/named_scoping_test.rb +177 -89
 - data/test/cases/scoping/relation_scoping_test.rb +197 -75
 - data/test/cases/secure_token_test.rb +18 -3
 - data/test/cases/serialization_test.rb +30 -28
 - data/test/cases/serialized_attribute_test.rb +133 -42
 - data/test/cases/signed_id_test.rb +168 -0
 - data/test/cases/statement_cache_test.rb +41 -24
 - data/test/cases/statement_invalid_test.rb +42 -0
 - data/test/cases/store_test.rb +180 -55
 - data/test/cases/strict_loading_test.rb +473 -0
 - data/test/cases/suppressor_test.rb +26 -12
 - data/test/cases/tasks/database_tasks_test.rb +1258 -194
 - data/test/cases/tasks/mysql_rake_test.rb +370 -298
 - data/test/cases/tasks/postgresql_rake_test.rb +481 -251
 - data/test/cases/tasks/sqlite_rake_test.rb +225 -178
 - data/test/cases/test_case.rb +51 -40
 - data/test/cases/test_databases_test.rb +79 -0
 - data/test/cases/test_fixtures_test.rb +79 -19
 - data/test/cases/time_precision_test.rb +98 -76
 - data/test/cases/timestamp_test.rb +102 -99
 - data/test/cases/touch_later_test.rb +12 -10
 - data/test/cases/transaction_callbacks_test.rb +344 -90
 - data/test/cases/transaction_isolation_test.rb +12 -12
 - data/test/cases/transactions_test.rb +612 -162
 - data/test/cases/type/adapter_specific_registry_test.rb +14 -2
 - data/test/cases/type/date_time_test.rb +4 -2
 - data/test/cases/type/integer_test.rb +4 -2
 - data/test/cases/type/string_test.rb +10 -8
 - data/test/cases/type/time_test.rb +28 -0
 - data/test/cases/type/type_map_test.rb +29 -28
 - data/test/cases/type/unsigned_integer_test.rb +19 -0
 - data/test/cases/type_test.rb +2 -0
 - data/test/cases/types_test.rb +3 -1
 - data/test/cases/unconnected_test.rb +14 -1
 - data/test/cases/unsafe_raw_sql_test.rb +274 -0
 - data/test/cases/validations/absence_validation_test.rb +19 -17
 - data/test/cases/validations/association_validation_test.rb +30 -28
 - data/test/cases/validations/i18n_generate_message_validation_test.rb +34 -16
 - data/test/cases/validations/i18n_validation_test.rb +22 -21
 - data/test/cases/validations/length_validation_test.rb +34 -33
 - data/test/cases/validations/numericality_validation_test.rb +181 -0
 - data/test/cases/validations/presence_validation_test.rb +21 -19
 - data/test/cases/validations/uniqueness_validation_test.rb +156 -86
 - data/test/cases/validations_repair_helper.rb +2 -0
 - data/test/cases/validations_test.rb +61 -26
 - data/test/cases/view_test.rb +122 -116
 - data/test/cases/yaml_serialization_test.rb +79 -34
 - data/test/config.example.yml +19 -19
 - data/test/config.rb +3 -1
 - data/test/config.yml +16 -6
 - data/test/fixtures/all/namespaced/accounts.yml +2 -0
 - data/test/fixtures/author_addresses.yml +1 -8
 - data/test/fixtures/authors.yml +1 -7
 - data/test/fixtures/binaries.yml +4 -0
 - data/test/fixtures/books.yml +9 -2
 - data/test/fixtures/categories_posts.yml +3 -0
 - data/test/fixtures/citations.yml +5 -0
 - data/test/fixtures/comments.yml +7 -0
 - data/test/fixtures/companies.yml +5 -0
 - data/test/fixtures/computers.yml +2 -0
 - data/test/fixtures/customers.yml +10 -1
 - data/test/fixtures/developers.yml +1 -1
 - data/test/fixtures/essays.yml +10 -0
 - data/test/fixtures/faces.yml +3 -3
 - data/test/fixtures/humans.yml +5 -0
 - data/test/fixtures/interests.yml +7 -7
 - data/test/fixtures/memberships.yml +7 -0
 - data/test/fixtures/minimalistics.yml +3 -0
 - data/test/fixtures/mixed_case_monkeys.yml +2 -2
 - data/test/fixtures/naked/yml/courses_with_invalid_key.yml +3 -0
 - data/test/fixtures/naked/yml/parrots.yml +1 -0
 - data/test/fixtures/other_books.yml +26 -0
 - data/test/fixtures/other_posts.yml +1 -0
 - data/test/fixtures/parrots.yml +7 -1
 - data/test/fixtures/pirates.yml +3 -0
 - data/test/fixtures/posts.yml +11 -3
 - data/test/fixtures/readers.yml +6 -0
 - data/test/fixtures/reserved_words/values.yml +2 -2
 - data/test/fixtures/sponsors.yml +3 -0
 - data/test/fixtures/strict_zines.yml +2 -0
 - data/test/fixtures/subscribers.yml +1 -1
 - data/test/fixtures/tasks.yml +1 -1
 - data/test/fixtures/warehouse-things.yml +3 -0
 - data/test/migrations/10_urban/9_add_expressions.rb +2 -0
 - data/test/migrations/decimal/1_give_me_big_numbers.rb +6 -4
 - data/test/migrations/magic/1_currencies_have_symbols.rb +3 -2
 - data/test/migrations/missing/1000_people_have_middle_names.rb +2 -0
 - data/test/migrations/missing/1_people_have_last_names.rb +2 -0
 - data/test/migrations/missing/3_we_need_reminders.rb +2 -0
 - data/test/migrations/missing/4_innocent_jointable.rb +3 -1
 - data/test/migrations/rename/1_we_need_things.rb +2 -0
 - data/test/migrations/rename/2_rename_things.rb +2 -0
 - data/test/migrations/to_copy/1_people_have_hobbies.rb +3 -1
 - data/test/migrations/to_copy/2_people_have_descriptions.rb +3 -1
 - data/test/migrations/to_copy2/1_create_articles.rb +2 -0
 - data/test/migrations/to_copy2/2_create_comments.rb +3 -1
 - data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +3 -1
 - data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +3 -1
 - data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +3 -1
 - data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +2 -0
 - data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +2 -0
 - data/test/migrations/valid/1_valid_people_have_last_names.rb +2 -0
 - data/test/migrations/valid/2_we_need_reminders.rb +2 -0
 - data/test/migrations/valid/3_innocent_jointable.rb +3 -1
 - data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +2 -0
 - data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +2 -0
 - data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +3 -1
 - data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +2 -0
 - data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +2 -0
 - data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +3 -1
 - data/test/migrations/version_check/20131219224947_migration_version_check.rb +2 -0
 - data/test/models/account.rb +46 -0
 - data/test/models/admin/account.rb +3 -1
 - data/test/models/admin/randomly_named_c1.rb +2 -0
 - data/test/models/admin/user.rb +16 -8
 - data/test/models/admin.rb +4 -2
 - data/test/models/aircraft.rb +3 -1
 - data/test/models/arunit2_model.rb +2 -0
 - data/test/models/author.rb +153 -102
 - data/test/models/auto_id.rb +2 -0
 - data/test/models/autoloadable/extra_firm.rb +2 -0
 - data/test/models/binary.rb +3 -1
 - data/test/models/binary_field.rb +6 -0
 - data/test/models/bird.rb +13 -1
 - data/test/models/book.rb +14 -4
 - data/test/models/book_destroy_async.rb +24 -0
 - data/test/models/boolean.rb +5 -0
 - data/test/models/bulb.rb +13 -4
 - data/test/models/cake_designer.rb +2 -0
 - data/test/models/car.rb +17 -10
 - data/test/models/carrier.rb +2 -0
 - data/test/models/cart.rb +5 -0
 - data/test/models/cat.rb +2 -0
 - data/test/models/categorization.rb +8 -6
 - data/test/models/category.rb +28 -16
 - data/test/models/chef.rb +2 -0
 - data/test/models/citation.rb +5 -1
 - data/test/models/club.rb +13 -10
 - data/test/models/college.rb +4 -2
 - data/test/models/column.rb +2 -0
 - data/test/models/column_name.rb +2 -0
 - data/test/models/comment.rb +32 -10
 - data/test/models/company.rb +102 -106
 - data/test/models/company_in_module.rb +27 -26
 - data/test/models/computer.rb +3 -1
 - data/test/models/contact.rb +15 -13
 - data/test/models/content.rb +5 -3
 - data/test/models/contract.rb +21 -3
 - data/test/models/country.rb +2 -4
 - data/test/models/course.rb +3 -1
 - data/test/models/customer.rb +10 -8
 - data/test/models/customer_carrier.rb +2 -0
 - data/test/models/dashboard.rb +2 -0
 - data/test/models/default.rb +2 -0
 - data/test/models/department.rb +2 -0
 - data/test/models/destroy_async_parent.rb +15 -0
 - data/test/models/destroy_async_parent_soft_delete.rb +20 -0
 - data/test/models/developer.rb +152 -85
 - data/test/models/dl_keyed_belongs_to.rb +13 -0
 - data/test/models/dl_keyed_belongs_to_soft_delete.rb +19 -0
 - data/test/models/dl_keyed_has_many.rb +5 -0
 - data/test/models/dl_keyed_has_many_through.rb +5 -0
 - data/test/models/dl_keyed_has_one.rb +5 -0
 - data/test/models/dl_keyed_join.rb +10 -0
 - data/test/models/dog.rb +2 -0
 - data/test/models/dog_lover.rb +2 -0
 - data/test/models/doubloon.rb +3 -1
 - data/test/models/drink_designer.rb +17 -0
 - data/test/models/edge.rb +4 -2
 - data/test/models/electron.rb +2 -0
 - data/test/models/engine.rb +3 -2
 - data/test/models/entrant.rb +2 -0
 - data/test/models/entry.rb +5 -0
 - data/test/models/essay.rb +6 -3
 - data/test/models/essay_destroy_async.rb +12 -0
 - data/test/models/event.rb +3 -1
 - data/test/models/eye.rb +5 -3
 - data/test/models/face.rb +14 -6
 - data/test/models/family.rb +6 -0
 - data/test/models/family_tree.rb +6 -0
 - data/test/models/friendship.rb +5 -3
 - data/test/models/frog.rb +8 -0
 - data/test/models/guid.rb +3 -1
 - data/test/models/guitar.rb +2 -0
 - data/test/models/hotel.rb +5 -3
 - data/test/models/human.rb +39 -0
 - data/test/models/image.rb +3 -1
 - data/test/models/interest.rb +14 -3
 - data/test/models/invoice.rb +4 -2
 - data/test/models/item.rb +3 -1
 - data/test/models/job.rb +5 -3
 - data/test/models/joke.rb +4 -2
 - data/test/models/keyboard.rb +3 -1
 - data/test/models/legacy_thing.rb +2 -0
 - data/test/models/lesson.rb +2 -0
 - data/test/models/line_item.rb +3 -1
 - data/test/models/liquid.rb +2 -0
 - data/test/models/matey.rb +3 -1
 - data/test/models/measurement.rb +4 -0
 - data/test/models/member.rb +23 -20
 - data/test/models/member_detail.rb +3 -0
 - data/test/models/member_type.rb +2 -0
 - data/test/models/membership.rb +4 -1
 - data/test/models/mentor.rb +3 -1
 - data/test/models/message.rb +5 -0
 - data/test/models/minimalistic.rb +2 -0
 - data/test/models/minivan.rb +3 -2
 - data/test/models/mixed_case_monkey.rb +3 -1
 - data/test/models/molecule.rb +2 -0
 - data/test/models/mouse.rb +6 -0
 - data/test/models/movie.rb +2 -0
 - data/test/models/node.rb +4 -2
 - data/test/models/non_primary_key.rb +2 -0
 - data/test/models/notification.rb +2 -0
 - data/test/models/numeric_data.rb +12 -0
 - data/test/models/order.rb +4 -2
 - data/test/models/organization.rb +9 -7
 - data/test/models/other_dog.rb +3 -1
 - data/test/models/owner.rb +6 -4
 - data/test/models/parrot.rb +12 -4
 - data/test/models/person.rb +59 -54
 - data/test/models/personal_legacy_thing.rb +3 -1
 - data/test/models/pet.rb +4 -2
 - data/test/models/pet_treasure.rb +2 -0
 - data/test/models/pirate.rb +67 -43
 - data/test/models/possession.rb +3 -1
 - data/test/models/post.rb +184 -86
 - data/test/models/price_estimate.rb +11 -1
 - data/test/models/professor.rb +3 -1
 - data/test/models/project.rb +14 -12
 - data/test/models/publisher/article.rb +2 -0
 - data/test/models/publisher/magazine.rb +2 -0
 - data/test/models/publisher.rb +2 -0
 - data/test/models/randomly_named_c1.rb +2 -0
 - data/test/models/rating.rb +5 -1
 - data/test/models/reader.rb +7 -5
 - data/test/models/recipe.rb +2 -0
 - data/test/models/record.rb +2 -0
 - data/test/models/reference.rb +6 -3
 - data/test/models/reply.rb +39 -21
 - data/test/models/room.rb +6 -0
 - data/test/models/section.rb +6 -0
 - data/test/models/seminar.rb +6 -0
 - data/test/models/session.rb +6 -0
 - data/test/models/ship.rb +12 -9
 - data/test/models/ship_part.rb +5 -3
 - data/test/models/shop.rb +4 -2
 - data/test/models/shop_account.rb +2 -0
 - data/test/models/speedometer.rb +2 -0
 - data/test/models/sponsor.rb +8 -5
 - data/test/models/squeak.rb +6 -0
 - data/test/models/strict_zine.rb +7 -0
 - data/test/models/string_key_object.rb +2 -0
 - data/test/models/student.rb +2 -0
 - data/test/models/subscriber.rb +4 -2
 - data/test/models/subscription.rb +5 -1
 - data/test/models/tag.rb +6 -3
 - data/test/models/tagging.rb +13 -6
 - data/test/models/task.rb +2 -0
 - data/test/models/topic.rb +54 -19
 - data/test/models/toy.rb +4 -0
 - data/test/models/traffic_light.rb +2 -0
 - data/test/models/treasure.rb +5 -3
 - data/test/models/treaty.rb +2 -4
 - data/test/models/tree.rb +2 -0
 - data/test/models/tuning_peg.rb +2 -0
 - data/test/models/tyre.rb +2 -0
 - data/test/models/user.rb +12 -4
 - data/test/models/uuid_child.rb +2 -0
 - data/test/models/uuid_item.rb +2 -0
 - data/test/models/uuid_parent.rb +2 -0
 - data/test/models/vegetables.rb +12 -3
 - data/test/models/vertex.rb +6 -4
 - data/test/models/warehouse_thing.rb +2 -0
 - data/test/models/wheel.rb +3 -1
 - data/test/models/without_table.rb +3 -1
 - data/test/models/zine.rb +3 -1
 - data/test/schema/mysql2_specific_schema.rb +49 -35
 - data/test/schema/oracle_specific_schema.rb +13 -15
 - data/test/schema/postgresql_specific_schema.rb +51 -40
 - data/test/schema/schema.rb +334 -154
 - data/test/schema/sqlite_specific_schema.rb +9 -16
 - data/test/support/config.rb +26 -26
 - data/test/support/connection.rb +14 -8
 - data/test/support/connection_helper.rb +3 -1
 - data/test/support/ddl_helper.rb +2 -0
 - data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic.dump +0 -0
 - data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic_associations.dump +0 -0
 - data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic.dump +0 -0
 - data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic_associations.dump +0 -0
 - data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic.dump +0 -0
 - data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic_associations.dump +0 -0
 - data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic.dump +0 -0
 - data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic_associations.dump +0 -0
 - data/test/support/marshal_compatibility_fixtures/legacy_6_0_record_mysql.dump +0 -0
 - data/test/support/marshal_compatibility_fixtures/legacy_relation.dump +0 -0
 - data/test/support/schema_dumping_helper.rb +2 -0
 - data/test/support/stubs/strong_parameters.rb +40 -0
 - data/test/support/yaml_compatibility_fixtures/rails_v1_mysql.yml +206 -0
 - data/test/support/yaml_compatibility_fixtures/rails_v2.yml +55 -0
 - metadata +192 -14
 
| 
         @@ -1,56 +1,90 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            require  
     | 
| 
       4 
     | 
    
         
            -
            require  
     | 
| 
       5 
     | 
    
         
            -
            require  
     | 
| 
       6 
     | 
    
         
            -
            require  
     | 
| 
       7 
     | 
    
         
            -
            require  
     | 
| 
       8 
     | 
    
         
            -
            require  
     | 
| 
       9 
     | 
    
         
            -
            require  
     | 
| 
       10 
     | 
    
         
            -
            require  
     | 
| 
       11 
     | 
    
         
            -
            require  
     | 
| 
       12 
     | 
    
         
            -
            require  
     | 
| 
       13 
     | 
    
         
            -
            require  
     | 
| 
       14 
     | 
    
         
            -
            require  
     | 
| 
       15 
     | 
    
         
            -
            require  
     | 
| 
       16 
     | 
    
         
            -
            require  
     | 
| 
       17 
     | 
    
         
            -
            require  
     | 
| 
       18 
     | 
    
         
            -
            require  
     | 
| 
       19 
     | 
    
         
            -
            require  
     | 
| 
       20 
     | 
    
         
            -
            require  
     | 
| 
       21 
     | 
    
         
            -
            require  
     | 
| 
       22 
     | 
    
         
            -
            require  
     | 
| 
       23 
     | 
    
         
            -
            require  
     | 
| 
       24 
     | 
    
         
            -
            require  
     | 
| 
       25 
     | 
    
         
            -
            require  
     | 
| 
       26 
     | 
    
         
            -
            require  
     | 
| 
       27 
     | 
    
         
            -
            require  
     | 
| 
       28 
     | 
    
         
            -
            require  
     | 
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "cases/helper"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "models/author"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "models/book"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "models/bird"
         
     | 
| 
      
 7 
     | 
    
         
            +
            require "models/post"
         
     | 
| 
      
 8 
     | 
    
         
            +
            require "models/comment"
         
     | 
| 
      
 9 
     | 
    
         
            +
            require "models/category"
         
     | 
| 
      
 10 
     | 
    
         
            +
            require "models/company"
         
     | 
| 
      
 11 
     | 
    
         
            +
            require "models/contract"
         
     | 
| 
      
 12 
     | 
    
         
            +
            require "models/customer"
         
     | 
| 
      
 13 
     | 
    
         
            +
            require "models/developer"
         
     | 
| 
      
 14 
     | 
    
         
            +
            require "models/computer"
         
     | 
| 
      
 15 
     | 
    
         
            +
            require "models/invoice"
         
     | 
| 
      
 16 
     | 
    
         
            +
            require "models/line_item"
         
     | 
| 
      
 17 
     | 
    
         
            +
            require "models/mouse"
         
     | 
| 
      
 18 
     | 
    
         
            +
            require "models/order"
         
     | 
| 
      
 19 
     | 
    
         
            +
            require "models/parrot"
         
     | 
| 
      
 20 
     | 
    
         
            +
            require "models/pirate"
         
     | 
| 
      
 21 
     | 
    
         
            +
            require "models/project"
         
     | 
| 
      
 22 
     | 
    
         
            +
            require "models/ship"
         
     | 
| 
      
 23 
     | 
    
         
            +
            require "models/ship_part"
         
     | 
| 
      
 24 
     | 
    
         
            +
            require "models/squeak"
         
     | 
| 
      
 25 
     | 
    
         
            +
            require "models/tag"
         
     | 
| 
      
 26 
     | 
    
         
            +
            require "models/tagging"
         
     | 
| 
      
 27 
     | 
    
         
            +
            require "models/treasure"
         
     | 
| 
      
 28 
     | 
    
         
            +
            require "models/eye"
         
     | 
| 
      
 29 
     | 
    
         
            +
            require "models/electron"
         
     | 
| 
      
 30 
     | 
    
         
            +
            require "models/molecule"
         
     | 
| 
      
 31 
     | 
    
         
            +
            require "models/member"
         
     | 
| 
      
 32 
     | 
    
         
            +
            require "models/member_detail"
         
     | 
| 
      
 33 
     | 
    
         
            +
            require "models/organization"
         
     | 
| 
      
 34 
     | 
    
         
            +
            require "models/guitar"
         
     | 
| 
      
 35 
     | 
    
         
            +
            require "models/tuning_peg"
         
     | 
| 
      
 36 
     | 
    
         
            +
            require "models/reply"
         
     | 
| 
       29 
37 
     | 
    
         | 
| 
       30 
38 
     | 
    
         
             
            class TestAutosaveAssociationsInGeneral < ActiveRecord::TestCase
         
     | 
| 
       31 
     | 
    
         
            -
              def  
     | 
| 
      
 39 
     | 
    
         
            +
              def test_autosave_works_even_when_other_callbacks_update_the_parent_model
         
     | 
| 
      
 40 
     | 
    
         
            +
                reference = Class.new(ActiveRecord::Base) do
         
     | 
| 
      
 41 
     | 
    
         
            +
                  self.table_name = "references"
         
     | 
| 
      
 42 
     | 
    
         
            +
                  def self.name; "Reference"; end
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                person = Class.new(ActiveRecord::Base) do
         
     | 
| 
      
 46 
     | 
    
         
            +
                  self.table_name = "people"
         
     | 
| 
      
 47 
     | 
    
         
            +
                  def self.name; "Person"; end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  # It is necessary that the after_create is before the has_many _and_ that it updates the model.
         
     | 
| 
      
 50 
     | 
    
         
            +
                  # This replicates a bug found in https://github.com/rails/rails/issues/38120
         
     | 
| 
      
 51 
     | 
    
         
            +
                  after_create { update(first_name: "first name") }
         
     | 
| 
      
 52 
     | 
    
         
            +
                  has_many :references, autosave: true, anonymous_class: reference
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                reference_instance = reference.create!
         
     | 
| 
      
 56 
     | 
    
         
            +
                person_instance = person.create!(first_name: "foo", references: [reference_instance])
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                reference_instance.reload
         
     | 
| 
      
 59 
     | 
    
         
            +
                assert_equal person_instance.id, reference_instance.person_id
         
     | 
| 
      
 60 
     | 
    
         
            +
                assert_equal "first name", person_instance.first_name # Make sure the after_create is actually called
         
     | 
| 
      
 61 
     | 
    
         
            +
              end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
              def test_autosave_does_not_pass_through_non_custom_validation_contexts
         
     | 
| 
       32 
64 
     | 
    
         
             
                person = Class.new(ActiveRecord::Base) {
         
     | 
| 
       33 
     | 
    
         
            -
                  self.table_name =  
     | 
| 
       34 
     | 
    
         
            -
                  validate :should_be_cool, : 
     | 
| 
       35 
     | 
    
         
            -
                  def self.name;  
     | 
| 
      
 65 
     | 
    
         
            +
                  self.table_name = "people"
         
     | 
| 
      
 66 
     | 
    
         
            +
                  validate :should_be_cool, on: :create
         
     | 
| 
      
 67 
     | 
    
         
            +
                  def self.name; "Person"; end
         
     | 
| 
       36 
68 
     | 
    
         | 
| 
       37 
69 
     | 
    
         
             
                  private
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
                       
     | 
| 
      
 70 
     | 
    
         
            +
                    def should_be_cool
         
     | 
| 
      
 71 
     | 
    
         
            +
                      unless first_name == "cool"
         
     | 
| 
      
 72 
     | 
    
         
            +
                        errors.add :first_name, "not cool"
         
     | 
| 
      
 73 
     | 
    
         
            +
                      end
         
     | 
| 
       42 
74 
     | 
    
         
             
                    end
         
     | 
| 
       43 
     | 
    
         
            -
                  end
         
     | 
| 
       44 
75 
     | 
    
         
             
                }
         
     | 
| 
       45 
76 
     | 
    
         
             
                reference = Class.new(ActiveRecord::Base) {
         
     | 
| 
       46 
77 
     | 
    
         
             
                  self.table_name = "references"
         
     | 
| 
       47 
     | 
    
         
            -
                  def self.name;  
     | 
| 
      
 78 
     | 
    
         
            +
                  def self.name; "Reference"; end
         
     | 
| 
       48 
79 
     | 
    
         
             
                  belongs_to :person, autosave: true, anonymous_class: person
         
     | 
| 
       49 
80 
     | 
    
         
             
                }
         
     | 
| 
       50 
81 
     | 
    
         | 
| 
       51 
     | 
    
         
            -
                u = person.create!(first_name:  
     | 
| 
       52 
     | 
    
         
            -
                u. 
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
      
 82 
     | 
    
         
            +
                u = person.create!(first_name: "cool")
         
     | 
| 
      
 83 
     | 
    
         
            +
                u.first_name = "nah"
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                assert_predicate u, :valid?
         
     | 
| 
      
 86 
     | 
    
         
            +
                r = reference.new(person: u)
         
     | 
| 
      
 87 
     | 
    
         
            +
                assert_predicate r, :valid?
         
     | 
| 
       54 
88 
     | 
    
         
             
              end
         
     | 
| 
       55 
89 
     | 
    
         | 
| 
       56 
90 
     | 
    
         
             
              def test_should_not_add_the_same_callbacks_multiple_times_for_has_one
         
     | 
| 
         @@ -73,60 +107,59 @@ class TestAutosaveAssociationsInGeneral < ActiveRecord::TestCase 
     | 
|
| 
       73 
107 
     | 
    
         
             
                ship = ShipWithoutNestedAttributes.new
         
     | 
| 
       74 
108 
     | 
    
         
             
                ship.prisoners.build
         
     | 
| 
       75 
109 
     | 
    
         | 
| 
       76 
     | 
    
         
            -
                 
     | 
| 
      
 110 
     | 
    
         
            +
                assert_not_predicate ship, :valid?
         
     | 
| 
       77 
111 
     | 
    
         
             
                assert_equal 1, ship.errors[:name].length
         
     | 
| 
       78 
112 
     | 
    
         
             
              end
         
     | 
| 
       79 
113 
     | 
    
         | 
| 
       80 
114 
     | 
    
         
             
              private
         
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
                   
     | 
| 
      
 115 
     | 
    
         
            +
                def assert_no_difference_when_adding_callbacks_twice_for(model, association_name)
         
     | 
| 
      
 116 
     | 
    
         
            +
                  reflection = model.reflect_on_association(association_name)
         
     | 
| 
      
 117 
     | 
    
         
            +
                  assert_no_difference "callbacks_for_model(#{model.name}).length" do
         
     | 
| 
      
 118 
     | 
    
         
            +
                    model.send(:add_autosave_association_callbacks, reflection)
         
     | 
| 
      
 119 
     | 
    
         
            +
                  end
         
     | 
| 
       86 
120 
     | 
    
         
             
                end
         
     | 
| 
       87 
     | 
    
         
            -
              end
         
     | 
| 
       88 
121 
     | 
    
         | 
| 
       89 
     | 
    
         
            -
             
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
      
 122 
     | 
    
         
            +
                def callbacks_for_model(model)
         
     | 
| 
      
 123 
     | 
    
         
            +
                  model.instance_variables.grep(/_callbacks$/).flat_map do |ivar|
         
     | 
| 
      
 124 
     | 
    
         
            +
                    model.instance_variable_get(ivar)
         
     | 
| 
      
 125 
     | 
    
         
            +
                  end
         
     | 
| 
       92 
126 
     | 
    
         
             
                end
         
     | 
| 
       93 
     | 
    
         
            -
              end
         
     | 
| 
       94 
127 
     | 
    
         
             
            end
         
     | 
| 
       95 
128 
     | 
    
         | 
| 
       96 
129 
     | 
    
         
             
            class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase
         
     | 
| 
       97 
130 
     | 
    
         
             
              fixtures :companies, :accounts
         
     | 
| 
       98 
131 
     | 
    
         | 
| 
       99 
132 
     | 
    
         
             
              def test_should_save_parent_but_not_invalid_child
         
     | 
| 
       100 
     | 
    
         
            -
                firm = Firm.new(: 
     | 
| 
       101 
     | 
    
         
            -
                 
     | 
| 
      
 133 
     | 
    
         
            +
                firm = Firm.new(name: "GlobalMegaCorp")
         
     | 
| 
      
 134 
     | 
    
         
            +
                assert_predicate firm, :valid?
         
     | 
| 
       102 
135 
     | 
    
         | 
| 
       103 
136 
     | 
    
         
             
                firm.build_account_using_primary_key
         
     | 
| 
       104 
     | 
    
         
            -
                 
     | 
| 
      
 137 
     | 
    
         
            +
                assert_not_predicate firm.build_account_using_primary_key, :valid?
         
     | 
| 
       105 
138 
     | 
    
         | 
| 
       106 
139 
     | 
    
         
             
                assert firm.save
         
     | 
| 
       107 
     | 
    
         
            -
                 
     | 
| 
      
 140 
     | 
    
         
            +
                assert_not_predicate firm.account_using_primary_key, :persisted?
         
     | 
| 
       108 
141 
     | 
    
         
             
              end
         
     | 
| 
       109 
142 
     | 
    
         | 
| 
       110 
143 
     | 
    
         
             
              def test_save_fails_for_invalid_has_one
         
     | 
| 
       111 
144 
     | 
    
         
             
                firm = Firm.first
         
     | 
| 
       112 
     | 
    
         
            -
                 
     | 
| 
      
 145 
     | 
    
         
            +
                assert_predicate firm, :valid?
         
     | 
| 
       113 
146 
     | 
    
         | 
| 
       114 
147 
     | 
    
         
             
                firm.build_account
         
     | 
| 
       115 
148 
     | 
    
         | 
| 
       116 
     | 
    
         
            -
                 
     | 
| 
       117 
     | 
    
         
            -
                 
     | 
| 
       118 
     | 
    
         
            -
                 
     | 
| 
      
 149 
     | 
    
         
            +
                assert_not_predicate firm.account, :valid?
         
     | 
| 
      
 150 
     | 
    
         
            +
                assert_not_predicate firm, :valid?
         
     | 
| 
      
 151 
     | 
    
         
            +
                assert_not firm.save
         
     | 
| 
       119 
152 
     | 
    
         
             
                assert_equal ["is invalid"], firm.errors["account"]
         
     | 
| 
       120 
153 
     | 
    
         
             
              end
         
     | 
| 
       121 
154 
     | 
    
         | 
| 
       122 
155 
     | 
    
         
             
              def test_save_succeeds_for_invalid_has_one_with_validate_false
         
     | 
| 
       123 
156 
     | 
    
         
             
                firm = Firm.first
         
     | 
| 
       124 
     | 
    
         
            -
                 
     | 
| 
      
 157 
     | 
    
         
            +
                assert_predicate firm, :valid?
         
     | 
| 
       125 
158 
     | 
    
         | 
| 
       126 
159 
     | 
    
         
             
                firm.build_unvalidated_account
         
     | 
| 
       127 
160 
     | 
    
         | 
| 
       128 
     | 
    
         
            -
                 
     | 
| 
       129 
     | 
    
         
            -
                 
     | 
| 
      
 161 
     | 
    
         
            +
                assert_not_predicate firm.unvalidated_account, :valid?
         
     | 
| 
      
 162 
     | 
    
         
            +
                assert_predicate firm, :valid?
         
     | 
| 
       130 
163 
     | 
    
         
             
                assert firm.save
         
     | 
| 
       131 
164 
     | 
    
         
             
              end
         
     | 
| 
       132 
165 
     | 
    
         | 
| 
         @@ -135,10 +168,10 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas 
     | 
|
| 
       135 
168 
     | 
    
         | 
| 
       136 
169 
     | 
    
         
             
                account = firm.build_account("credit_limit" => 1000)
         
     | 
| 
       137 
170 
     | 
    
         
             
                assert_equal account, firm.account
         
     | 
| 
       138 
     | 
    
         
            -
                 
     | 
| 
      
 171 
     | 
    
         
            +
                assert_not_predicate account, :persisted?
         
     | 
| 
       139 
172 
     | 
    
         
             
                assert firm.save
         
     | 
| 
       140 
173 
     | 
    
         
             
                assert_equal account, firm.account
         
     | 
| 
       141 
     | 
    
         
            -
                 
     | 
| 
      
 174 
     | 
    
         
            +
                assert_predicate account, :persisted?
         
     | 
| 
       142 
175 
     | 
    
         
             
              end
         
     | 
| 
       143 
176 
     | 
    
         | 
| 
       144 
177 
     | 
    
         
             
              def test_build_before_either_saved
         
     | 
| 
         @@ -146,16 +179,16 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas 
     | 
|
| 
       146 
179 
     | 
    
         | 
| 
       147 
180 
     | 
    
         
             
                firm.account = account = Account.new("credit_limit" => 1000)
         
     | 
| 
       148 
181 
     | 
    
         
             
                assert_equal account, firm.account
         
     | 
| 
       149 
     | 
    
         
            -
                 
     | 
| 
      
 182 
     | 
    
         
            +
                assert_not_predicate account, :persisted?
         
     | 
| 
       150 
183 
     | 
    
         
             
                assert firm.save
         
     | 
| 
       151 
184 
     | 
    
         
             
                assert_equal account, firm.account
         
     | 
| 
       152 
     | 
    
         
            -
                 
     | 
| 
      
 185 
     | 
    
         
            +
                assert_predicate account, :persisted?
         
     | 
| 
       153 
186 
     | 
    
         
             
              end
         
     | 
| 
       154 
187 
     | 
    
         | 
| 
       155 
188 
     | 
    
         
             
              def test_assignment_before_parent_saved
         
     | 
| 
       156 
189 
     | 
    
         
             
                firm = Firm.new("name" => "GlobalMegaCorp")
         
     | 
| 
       157 
190 
     | 
    
         
             
                firm.account = a = Account.find(1)
         
     | 
| 
       158 
     | 
    
         
            -
                 
     | 
| 
      
 191 
     | 
    
         
            +
                assert_not_predicate firm, :persisted?
         
     | 
| 
       159 
192 
     | 
    
         
             
                assert_equal a, firm.account
         
     | 
| 
       160 
193 
     | 
    
         
             
                assert firm.save
         
     | 
| 
       161 
194 
     | 
    
         
             
                assert_equal a, firm.account
         
     | 
| 
         @@ -166,20 +199,20 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas 
     | 
|
| 
       166 
199 
     | 
    
         
             
              def test_assignment_before_either_saved
         
     | 
| 
       167 
200 
     | 
    
         
             
                firm = Firm.new("name" => "GlobalMegaCorp")
         
     | 
| 
       168 
201 
     | 
    
         
             
                firm.account = a = Account.new("credit_limit" => 1000)
         
     | 
| 
       169 
     | 
    
         
            -
                 
     | 
| 
       170 
     | 
    
         
            -
                 
     | 
| 
      
 202 
     | 
    
         
            +
                assert_not_predicate firm, :persisted?
         
     | 
| 
      
 203 
     | 
    
         
            +
                assert_not_predicate a, :persisted?
         
     | 
| 
       171 
204 
     | 
    
         
             
                assert_equal a, firm.account
         
     | 
| 
       172 
205 
     | 
    
         
             
                assert firm.save
         
     | 
| 
       173 
     | 
    
         
            -
                 
     | 
| 
       174 
     | 
    
         
            -
                 
     | 
| 
      
 206 
     | 
    
         
            +
                assert_predicate firm, :persisted?
         
     | 
| 
      
 207 
     | 
    
         
            +
                assert_predicate a, :persisted?
         
     | 
| 
       175 
208 
     | 
    
         
             
                assert_equal a, firm.account
         
     | 
| 
       176 
209 
     | 
    
         
             
                firm.association(:account).reload
         
     | 
| 
       177 
210 
     | 
    
         
             
                assert_equal a, firm.account
         
     | 
| 
       178 
211 
     | 
    
         
             
              end
         
     | 
| 
       179 
212 
     | 
    
         | 
| 
       180 
213 
     | 
    
         
             
              def test_not_resaved_when_unchanged
         
     | 
| 
       181 
     | 
    
         
            -
                firm = Firm.all.merge!(: 
     | 
| 
       182 
     | 
    
         
            -
                firm.name +=  
     | 
| 
      
 214 
     | 
    
         
            +
                firm = Firm.all.merge!(includes: :account).first
         
     | 
| 
      
 215 
     | 
    
         
            +
                firm.name += "-changed"
         
     | 
| 
       183 
216 
     | 
    
         
             
                assert_queries(1) { firm.save! }
         
     | 
| 
       184 
217 
     | 
    
         | 
| 
       185 
218 
     | 
    
         
             
                firm = Firm.first
         
     | 
| 
         @@ -196,21 +229,21 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas 
     | 
|
| 
       196 
229 
     | 
    
         
             
              end
         
     | 
| 
       197 
230 
     | 
    
         | 
| 
       198 
231 
     | 
    
         
             
              def test_callbacks_firing_order_on_create
         
     | 
| 
       199 
     | 
    
         
            -
                eye = Eye.create(: 
     | 
| 
      
 232 
     | 
    
         
            +
                eye = Eye.create(iris_attributes: { color: "honey" })
         
     | 
| 
       200 
233 
     | 
    
         
             
                assert_equal [true, false], eye.after_create_callbacks_stack
         
     | 
| 
       201 
234 
     | 
    
         
             
              end
         
     | 
| 
       202 
235 
     | 
    
         | 
| 
       203 
236 
     | 
    
         
             
              def test_callbacks_firing_order_on_update
         
     | 
| 
       204 
     | 
    
         
            -
                eye = Eye.create(iris_attributes: {color:  
     | 
| 
       205 
     | 
    
         
            -
                eye.update(iris_attributes: {color:  
     | 
| 
      
 237 
     | 
    
         
            +
                eye = Eye.create(iris_attributes: { color: "honey" })
         
     | 
| 
      
 238 
     | 
    
         
            +
                eye.update(iris_attributes: { color: "green" })
         
     | 
| 
       206 
239 
     | 
    
         
             
                assert_equal [true, false], eye.after_update_callbacks_stack
         
     | 
| 
       207 
240 
     | 
    
         
             
              end
         
     | 
| 
       208 
241 
     | 
    
         | 
| 
       209 
242 
     | 
    
         
             
              def test_callbacks_firing_order_on_save
         
     | 
| 
       210 
     | 
    
         
            -
                eye = Eye.create(iris_attributes: {color:  
     | 
| 
      
 243 
     | 
    
         
            +
                eye = Eye.create(iris_attributes: { color: "honey" })
         
     | 
| 
       211 
244 
     | 
    
         
             
                assert_equal [false, false], eye.after_save_callbacks_stack
         
     | 
| 
       212 
245 
     | 
    
         | 
| 
       213 
     | 
    
         
            -
                eye.update(iris_attributes: {color:  
     | 
| 
      
 246 
     | 
    
         
            +
                eye.update(iris_attributes: { color: "blue" })
         
     | 
| 
       214 
247 
     | 
    
         
             
                assert_equal [false, false, false, false], eye.after_save_callbacks_stack
         
     | 
| 
       215 
248 
     | 
    
         
             
              end
         
     | 
| 
       216 
249 
     | 
    
         
             
            end
         
     | 
| 
         @@ -219,34 +252,34 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test 
     | 
|
| 
       219 
252 
     | 
    
         
             
              fixtures :companies, :posts, :tags, :taggings
         
     | 
| 
       220 
253 
     | 
    
         | 
| 
       221 
254 
     | 
    
         
             
              def test_should_save_parent_but_not_invalid_child
         
     | 
| 
       222 
     | 
    
         
            -
                client = Client.new(: 
     | 
| 
       223 
     | 
    
         
            -
                 
     | 
| 
      
 255 
     | 
    
         
            +
                client = Client.new(name: "Joe (the Plumber)")
         
     | 
| 
      
 256 
     | 
    
         
            +
                assert_predicate client, :valid?
         
     | 
| 
       224 
257 
     | 
    
         | 
| 
       225 
258 
     | 
    
         
             
                client.build_firm
         
     | 
| 
       226 
     | 
    
         
            -
                 
     | 
| 
      
 259 
     | 
    
         
            +
                assert_not_predicate client.firm, :valid?
         
     | 
| 
       227 
260 
     | 
    
         | 
| 
       228 
261 
     | 
    
         
             
                assert client.save
         
     | 
| 
       229 
     | 
    
         
            -
                 
     | 
| 
      
 262 
     | 
    
         
            +
                assert_not_predicate client.firm, :persisted?
         
     | 
| 
       230 
263 
     | 
    
         
             
              end
         
     | 
| 
       231 
264 
     | 
    
         | 
| 
       232 
265 
     | 
    
         
             
              def test_save_fails_for_invalid_belongs_to
         
     | 
| 
       233 
266 
     | 
    
         
             
                # Oracle saves empty string as NULL therefore :message changed to one space
         
     | 
| 
       234 
     | 
    
         
            -
                assert log = AuditLog.create(: 
     | 
| 
      
 267 
     | 
    
         
            +
                assert log = AuditLog.create(developer_id: 0, message: " ")
         
     | 
| 
       235 
268 
     | 
    
         | 
| 
       236 
269 
     | 
    
         
             
                log.developer = Developer.new
         
     | 
| 
       237 
     | 
    
         
            -
                 
     | 
| 
       238 
     | 
    
         
            -
                 
     | 
| 
       239 
     | 
    
         
            -
                 
     | 
| 
      
 270 
     | 
    
         
            +
                assert_not_predicate log.developer, :valid?
         
     | 
| 
      
 271 
     | 
    
         
            +
                assert_not_predicate log, :valid?
         
     | 
| 
      
 272 
     | 
    
         
            +
                assert_not log.save
         
     | 
| 
       240 
273 
     | 
    
         
             
                assert_equal ["is invalid"], log.errors["developer"]
         
     | 
| 
       241 
274 
     | 
    
         
             
              end
         
     | 
| 
       242 
275 
     | 
    
         | 
| 
       243 
276 
     | 
    
         
             
              def test_save_succeeds_for_invalid_belongs_to_with_validate_false
         
     | 
| 
       244 
277 
     | 
    
         
             
                # Oracle saves empty string as NULL therefore :message changed to one space
         
     | 
| 
       245 
     | 
    
         
            -
                assert log = AuditLog.create(: 
     | 
| 
      
 278 
     | 
    
         
            +
                assert log = AuditLog.create(developer_id: 0, message: " ")
         
     | 
| 
       246 
279 
     | 
    
         | 
| 
       247 
280 
     | 
    
         
             
                log.unvalidated_developer = Developer.new
         
     | 
| 
       248 
     | 
    
         
            -
                 
     | 
| 
       249 
     | 
    
         
            -
                 
     | 
| 
      
 281 
     | 
    
         
            +
                assert_not_predicate log.unvalidated_developer, :valid?
         
     | 
| 
      
 282 
     | 
    
         
            +
                assert_predicate log, :valid?
         
     | 
| 
       250 
283 
     | 
    
         
             
                assert log.save
         
     | 
| 
       251 
284 
     | 
    
         
             
              end
         
     | 
| 
       252 
285 
     | 
    
         | 
| 
         @@ -255,10 +288,10 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test 
     | 
|
| 
       255 
288 
     | 
    
         
             
                apple = Firm.new("name" => "Apple")
         
     | 
| 
       256 
289 
     | 
    
         
             
                client.firm = apple
         
     | 
| 
       257 
290 
     | 
    
         
             
                assert_equal apple, client.firm
         
     | 
| 
       258 
     | 
    
         
            -
                 
     | 
| 
      
 291 
     | 
    
         
            +
                assert_not_predicate apple, :persisted?
         
     | 
| 
       259 
292 
     | 
    
         
             
                assert client.save
         
     | 
| 
       260 
293 
     | 
    
         
             
                assert apple.save
         
     | 
| 
       261 
     | 
    
         
            -
                 
     | 
| 
      
 294 
     | 
    
         
            +
                assert_predicate apple, :persisted?
         
     | 
| 
       262 
295 
     | 
    
         
             
                assert_equal apple, client.firm
         
     | 
| 
       263 
296 
     | 
    
         
             
                client.association(:firm).reload
         
     | 
| 
       264 
297 
     | 
    
         
             
                assert_equal apple, client.firm
         
     | 
| 
         @@ -268,11 +301,11 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test 
     | 
|
| 
       268 
301 
     | 
    
         
             
                final_cut = Client.new("name" => "Final Cut")
         
     | 
| 
       269 
302 
     | 
    
         
             
                apple = Firm.new("name" => "Apple")
         
     | 
| 
       270 
303 
     | 
    
         
             
                final_cut.firm = apple
         
     | 
| 
       271 
     | 
    
         
            -
                 
     | 
| 
       272 
     | 
    
         
            -
                 
     | 
| 
      
 304 
     | 
    
         
            +
                assert_not_predicate final_cut, :persisted?
         
     | 
| 
      
 305 
     | 
    
         
            +
                assert_not_predicate apple, :persisted?
         
     | 
| 
       273 
306 
     | 
    
         
             
                assert final_cut.save
         
     | 
| 
       274 
     | 
    
         
            -
                 
     | 
| 
       275 
     | 
    
         
            -
                 
     | 
| 
      
 307 
     | 
    
         
            +
                assert_predicate final_cut, :persisted?
         
     | 
| 
      
 308 
     | 
    
         
            +
                assert_predicate apple, :persisted?
         
     | 
| 
       276 
309 
     | 
    
         
             
                assert_equal apple, final_cut.firm
         
     | 
| 
       277 
310 
     | 
    
         
             
                final_cut.association(:firm).reload
         
     | 
| 
       278 
311 
     | 
    
         
             
                assert_equal apple, final_cut.firm
         
     | 
| 
         @@ -362,41 +395,55 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test 
     | 
|
| 
       362 
395 
     | 
    
         | 
| 
       363 
396 
     | 
    
         
             
              def test_store_association_with_a_polymorphic_relationship
         
     | 
| 
       364 
397 
     | 
    
         
             
                num_tagging = Tagging.count
         
     | 
| 
       365 
     | 
    
         
            -
                tags(:misc).create_tagging(: 
     | 
| 
      
 398 
     | 
    
         
            +
                tags(:misc).create_tagging(taggable: posts(:thinking))
         
     | 
| 
       366 
399 
     | 
    
         
             
                assert_equal num_tagging + 1, Tagging.count
         
     | 
| 
       367 
400 
     | 
    
         
             
              end
         
     | 
| 
       368 
401 
     | 
    
         | 
| 
       369 
402 
     | 
    
         
             
              def test_build_and_then_save_parent_should_not_reload_target
         
     | 
| 
       370 
403 
     | 
    
         
             
                client = Client.first
         
     | 
| 
       371 
     | 
    
         
            -
                apple = client.build_firm(: 
     | 
| 
      
 404 
     | 
    
         
            +
                apple = client.build_firm(name: "Apple")
         
     | 
| 
       372 
405 
     | 
    
         
             
                client.save!
         
     | 
| 
       373 
406 
     | 
    
         
             
                assert_no_queries { assert_equal apple, client.firm }
         
     | 
| 
       374 
407 
     | 
    
         
             
              end
         
     | 
| 
       375 
408 
     | 
    
         | 
| 
       376 
409 
     | 
    
         
             
              def test_validation_does_not_validate_stale_association_target
         
     | 
| 
       377 
     | 
    
         
            -
                valid_developer   = Developer.create!(: 
     | 
| 
      
 410 
     | 
    
         
            +
                valid_developer   = Developer.create!(name: "Dude", salary: 50_000)
         
     | 
| 
       378 
411 
     | 
    
         
             
                invalid_developer = Developer.new()
         
     | 
| 
       379 
412 
     | 
    
         | 
| 
       380 
     | 
    
         
            -
                auditlog = AuditLog.new(: 
     | 
| 
      
 413 
     | 
    
         
            +
                auditlog = AuditLog.new(message: "foo")
         
     | 
| 
       381 
414 
     | 
    
         
             
                auditlog.developer    = invalid_developer
         
     | 
| 
       382 
415 
     | 
    
         
             
                auditlog.developer_id = valid_developer.id
         
     | 
| 
       383 
416 
     | 
    
         | 
| 
       384 
     | 
    
         
            -
                 
     | 
| 
      
 417 
     | 
    
         
            +
                assert_predicate auditlog, :valid?
         
     | 
| 
      
 418 
     | 
    
         
            +
              end
         
     | 
| 
      
 419 
     | 
    
         
            +
             
     | 
| 
      
 420 
     | 
    
         
            +
              def test_validation_does_not_validate_non_dirty_association_target
         
     | 
| 
      
 421 
     | 
    
         
            +
                mouse = Mouse.create!(name: "Will")
         
     | 
| 
      
 422 
     | 
    
         
            +
                Squeak.create!(mouse: mouse)
         
     | 
| 
      
 423 
     | 
    
         
            +
             
     | 
| 
      
 424 
     | 
    
         
            +
                mouse.name = nil
         
     | 
| 
      
 425 
     | 
    
         
            +
                mouse.save! validate: false
         
     | 
| 
      
 426 
     | 
    
         
            +
             
     | 
| 
      
 427 
     | 
    
         
            +
                squeak = Squeak.last
         
     | 
| 
      
 428 
     | 
    
         
            +
             
     | 
| 
      
 429 
     | 
    
         
            +
                assert_equal true, squeak.valid?
         
     | 
| 
      
 430 
     | 
    
         
            +
                assert_equal true, squeak.mouse.present?
         
     | 
| 
      
 431 
     | 
    
         
            +
                assert_equal true, squeak.valid?
         
     | 
| 
       385 
432 
     | 
    
         
             
              end
         
     | 
| 
       386 
433 
     | 
    
         
             
            end
         
     | 
| 
       387 
434 
     | 
    
         | 
| 
       388 
435 
     | 
    
         
             
            class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttributes < ActiveRecord::TestCase
         
     | 
| 
       389 
436 
     | 
    
         
             
              def test_invalid_adding_with_nested_attributes
         
     | 
| 
       390 
437 
     | 
    
         
             
                molecule = Molecule.new
         
     | 
| 
       391 
     | 
    
         
            -
                valid_electron = Electron.new(name:  
     | 
| 
      
 438 
     | 
    
         
            +
                valid_electron = Electron.new(name: "electron")
         
     | 
| 
       392 
439 
     | 
    
         
             
                invalid_electron = Electron.new
         
     | 
| 
       393 
440 
     | 
    
         | 
| 
       394 
441 
     | 
    
         
             
                molecule.electrons = [valid_electron, invalid_electron]
         
     | 
| 
       395 
442 
     | 
    
         
             
                molecule.save
         
     | 
| 
       396 
443 
     | 
    
         | 
| 
       397 
     | 
    
         
            -
                 
     | 
| 
       398 
     | 
    
         
            -
                 
     | 
| 
       399 
     | 
    
         
            -
                assert_not molecule.persisted?,  
     | 
| 
      
 444 
     | 
    
         
            +
                assert_not_predicate invalid_electron, :valid?
         
     | 
| 
      
 445 
     | 
    
         
            +
                assert_predicate valid_electron, :valid?
         
     | 
| 
      
 446 
     | 
    
         
            +
                assert_not molecule.persisted?, "Molecule should not be persisted when its electrons are invalid"
         
     | 
| 
       400 
447 
     | 
    
         
             
              end
         
     | 
| 
       401 
448 
     | 
    
         | 
| 
       402 
449 
     | 
    
         
             
              def test_errors_should_be_indexed_when_passed_as_array
         
     | 
| 
         @@ -407,9 +454,9 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttrib 
     | 
|
| 
       407 
454 
     | 
    
         | 
| 
       408 
455 
     | 
    
         
             
                guitar.tuning_pegs = [tuning_peg_valid, tuning_peg_invalid]
         
     | 
| 
       409 
456 
     | 
    
         | 
| 
       410 
     | 
    
         
            -
                 
     | 
| 
       411 
     | 
    
         
            -
                 
     | 
| 
       412 
     | 
    
         
            -
                 
     | 
| 
      
 457 
     | 
    
         
            +
                assert_not_predicate tuning_peg_invalid, :valid?
         
     | 
| 
      
 458 
     | 
    
         
            +
                assert_predicate tuning_peg_valid, :valid?
         
     | 
| 
      
 459 
     | 
    
         
            +
                assert_not_predicate guitar, :valid?
         
     | 
| 
       413 
460 
     | 
    
         
             
                assert_equal ["is not a number"], guitar.errors["tuning_pegs[1].pitch"]
         
     | 
| 
       414 
461 
     | 
    
         
             
                assert_not_equal ["is not a number"], guitar.errors["tuning_pegs.pitch"]
         
     | 
| 
       415 
462 
     | 
    
         
             
              end
         
     | 
| 
         @@ -419,14 +466,14 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttrib 
     | 
|
| 
       419 
466 
     | 
    
         
             
                ActiveRecord::Base.index_nested_attribute_errors = true
         
     | 
| 
       420 
467 
     | 
    
         | 
| 
       421 
468 
     | 
    
         
             
                molecule = Molecule.new
         
     | 
| 
       422 
     | 
    
         
            -
                valid_electron = Electron.new(name:  
     | 
| 
      
 469 
     | 
    
         
            +
                valid_electron = Electron.new(name: "electron")
         
     | 
| 
       423 
470 
     | 
    
         
             
                invalid_electron = Electron.new
         
     | 
| 
       424 
471 
     | 
    
         | 
| 
       425 
472 
     | 
    
         
             
                molecule.electrons = [valid_electron, invalid_electron]
         
     | 
| 
       426 
473 
     | 
    
         | 
| 
       427 
     | 
    
         
            -
                 
     | 
| 
       428 
     | 
    
         
            -
                 
     | 
| 
       429 
     | 
    
         
            -
                 
     | 
| 
      
 474 
     | 
    
         
            +
                assert_not_predicate invalid_electron, :valid?
         
     | 
| 
      
 475 
     | 
    
         
            +
                assert_predicate valid_electron, :valid?
         
     | 
| 
      
 476 
     | 
    
         
            +
                assert_not_predicate molecule, :valid?
         
     | 
| 
       430 
477 
     | 
    
         
             
                assert_equal ["can't be blank"], molecule.errors["electrons[1].name"]
         
     | 
| 
       431 
478 
     | 
    
         
             
                assert_not_equal ["can't be blank"], molecule.errors["electrons.name"]
         
     | 
| 
       432 
479 
     | 
    
         
             
              ensure
         
     | 
| 
         @@ -435,14 +482,14 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttrib 
     | 
|
| 
       435 
482 
     | 
    
         | 
| 
       436 
483 
     | 
    
         
             
              def test_errors_details_should_be_set
         
     | 
| 
       437 
484 
     | 
    
         
             
                molecule = Molecule.new
         
     | 
| 
       438 
     | 
    
         
            -
                valid_electron = Electron.new(name:  
     | 
| 
      
 485 
     | 
    
         
            +
                valid_electron = Electron.new(name: "electron")
         
     | 
| 
       439 
486 
     | 
    
         
             
                invalid_electron = Electron.new
         
     | 
| 
       440 
487 
     | 
    
         | 
| 
       441 
488 
     | 
    
         
             
                molecule.electrons = [valid_electron, invalid_electron]
         
     | 
| 
       442 
489 
     | 
    
         | 
| 
       443 
     | 
    
         
            -
                 
     | 
| 
       444 
     | 
    
         
            -
                 
     | 
| 
       445 
     | 
    
         
            -
                 
     | 
| 
      
 490 
     | 
    
         
            +
                assert_not_predicate invalid_electron, :valid?
         
     | 
| 
      
 491 
     | 
    
         
            +
                assert_predicate valid_electron, :valid?
         
     | 
| 
      
 492 
     | 
    
         
            +
                assert_not_predicate molecule, :valid?
         
     | 
| 
       446 
493 
     | 
    
         
             
                assert_equal [{ error: :blank }], molecule.errors.details[:"electrons.name"]
         
     | 
| 
       447 
494 
     | 
    
         
             
              end
         
     | 
| 
       448 
495 
     | 
    
         | 
| 
         @@ -454,9 +501,9 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttrib 
     | 
|
| 
       454 
501 
     | 
    
         | 
| 
       455 
502 
     | 
    
         
             
                guitar.tuning_pegs = [tuning_peg_valid, tuning_peg_invalid]
         
     | 
| 
       456 
503 
     | 
    
         | 
| 
       457 
     | 
    
         
            -
                 
     | 
| 
       458 
     | 
    
         
            -
                 
     | 
| 
       459 
     | 
    
         
            -
                 
     | 
| 
      
 504 
     | 
    
         
            +
                assert_not_predicate tuning_peg_invalid, :valid?
         
     | 
| 
      
 505 
     | 
    
         
            +
                assert_predicate tuning_peg_valid, :valid?
         
     | 
| 
      
 506 
     | 
    
         
            +
                assert_not_predicate guitar, :valid?
         
     | 
| 
       460 
507 
     | 
    
         
             
                assert_equal [{ error: :not_a_number, value: nil }], guitar.errors.details[:"tuning_pegs[1].pitch"]
         
     | 
| 
       461 
508 
     | 
    
         
             
                assert_equal [], guitar.errors.details[:"tuning_pegs.pitch"]
         
     | 
| 
       462 
509 
     | 
    
         
             
              end
         
     | 
| 
         @@ -466,14 +513,14 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttrib 
     | 
|
| 
       466 
513 
     | 
    
         
             
                ActiveRecord::Base.index_nested_attribute_errors = true
         
     | 
| 
       467 
514 
     | 
    
         | 
| 
       468 
515 
     | 
    
         
             
                molecule = Molecule.new
         
     | 
| 
       469 
     | 
    
         
            -
                valid_electron = Electron.new(name:  
     | 
| 
      
 516 
     | 
    
         
            +
                valid_electron = Electron.new(name: "electron")
         
     | 
| 
       470 
517 
     | 
    
         
             
                invalid_electron = Electron.new
         
     | 
| 
       471 
518 
     | 
    
         | 
| 
       472 
519 
     | 
    
         
             
                molecule.electrons = [valid_electron, invalid_electron]
         
     | 
| 
       473 
520 
     | 
    
         | 
| 
       474 
     | 
    
         
            -
                 
     | 
| 
       475 
     | 
    
         
            -
                 
     | 
| 
       476 
     | 
    
         
            -
                 
     | 
| 
      
 521 
     | 
    
         
            +
                assert_not_predicate invalid_electron, :valid?
         
     | 
| 
      
 522 
     | 
    
         
            +
                assert_predicate valid_electron, :valid?
         
     | 
| 
      
 523 
     | 
    
         
            +
                assert_not_predicate molecule, :valid?
         
     | 
| 
       477 
524 
     | 
    
         
             
                assert_equal [{ error: :blank }], molecule.errors.details[:"electrons[1].name"]
         
     | 
| 
       478 
525 
     | 
    
         
             
                assert_equal [], molecule.errors.details[:"electrons.name"]
         
     | 
| 
       479 
526 
     | 
    
         
             
              ensure
         
     | 
| 
         @@ -482,38 +529,50 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttrib 
     | 
|
| 
       482 
529 
     | 
    
         | 
| 
       483 
530 
     | 
    
         
             
              def test_valid_adding_with_nested_attributes
         
     | 
| 
       484 
531 
     | 
    
         
             
                molecule = Molecule.new
         
     | 
| 
       485 
     | 
    
         
            -
                valid_electron = Electron.new(name:  
     | 
| 
      
 532 
     | 
    
         
            +
                valid_electron = Electron.new(name: "electron")
         
     | 
| 
       486 
533 
     | 
    
         | 
| 
       487 
534 
     | 
    
         
             
                molecule.electrons = [valid_electron]
         
     | 
| 
       488 
535 
     | 
    
         
             
                molecule.save
         
     | 
| 
       489 
536 
     | 
    
         | 
| 
       490 
     | 
    
         
            -
                 
     | 
| 
       491 
     | 
    
         
            -
                 
     | 
| 
      
 537 
     | 
    
         
            +
                assert_predicate valid_electron, :valid?
         
     | 
| 
      
 538 
     | 
    
         
            +
                assert_predicate molecule, :persisted?
         
     | 
| 
       492 
539 
     | 
    
         
             
                assert_equal 1, molecule.electrons.count
         
     | 
| 
       493 
540 
     | 
    
         
             
              end
         
     | 
| 
       494 
541 
     | 
    
         
             
            end
         
     | 
| 
       495 
542 
     | 
    
         | 
| 
       496 
543 
     | 
    
         
             
            class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCase
         
     | 
| 
       497 
     | 
    
         
            -
              fixtures :companies, : 
     | 
| 
      
 544 
     | 
    
         
            +
              fixtures :companies, :developers
         
     | 
| 
       498 
545 
     | 
    
         | 
| 
       499 
546 
     | 
    
         
             
              def test_invalid_adding
         
     | 
| 
       500 
547 
     | 
    
         
             
                firm = Firm.find(1)
         
     | 
| 
       501 
     | 
    
         
            -
                 
     | 
| 
       502 
     | 
    
         
            -
                 
     | 
| 
       503 
     | 
    
         
            -
                 
     | 
| 
       504 
     | 
    
         
            -
                 
     | 
| 
       505 
     | 
    
         
            -
                 
     | 
| 
      
 548 
     | 
    
         
            +
                assert_not (firm.clients_of_firm << c = Client.new)
         
     | 
| 
      
 549 
     | 
    
         
            +
                assert_not_predicate c, :persisted?
         
     | 
| 
      
 550 
     | 
    
         
            +
                assert_not_predicate firm, :valid?
         
     | 
| 
      
 551 
     | 
    
         
            +
                assert_not firm.save
         
     | 
| 
      
 552 
     | 
    
         
            +
                assert_not_predicate c, :persisted?
         
     | 
| 
       506 
553 
     | 
    
         
             
              end
         
     | 
| 
       507 
554 
     | 
    
         | 
| 
       508 
555 
     | 
    
         
             
              def test_invalid_adding_before_save
         
     | 
| 
       509 
556 
     | 
    
         
             
                new_firm = Firm.new("name" => "A New Firm, Inc")
         
     | 
| 
       510 
557 
     | 
    
         
             
                new_firm.clients_of_firm.concat([c = Client.new, Client.new("name" => "Apple")])
         
     | 
| 
       511 
     | 
    
         
            -
                 
     | 
| 
       512 
     | 
    
         
            -
                 
     | 
| 
       513 
     | 
    
         
            -
                 
     | 
| 
       514 
     | 
    
         
            -
                 
     | 
| 
       515 
     | 
    
         
            -
                 
     | 
| 
       516 
     | 
    
         
            -
                 
     | 
| 
      
 558 
     | 
    
         
            +
                assert_not_predicate c, :persisted?
         
     | 
| 
      
 559 
     | 
    
         
            +
                assert_not_predicate c, :valid?
         
     | 
| 
      
 560 
     | 
    
         
            +
                assert_not_predicate new_firm, :valid?
         
     | 
| 
      
 561 
     | 
    
         
            +
                assert_not new_firm.save
         
     | 
| 
      
 562 
     | 
    
         
            +
                assert_not_predicate c, :persisted?
         
     | 
| 
      
 563 
     | 
    
         
            +
                assert_not_predicate new_firm, :persisted?
         
     | 
| 
      
 564 
     | 
    
         
            +
              end
         
     | 
| 
      
 565 
     | 
    
         
            +
             
     | 
| 
      
 566 
     | 
    
         
            +
              def test_adding_unsavable_association
         
     | 
| 
      
 567 
     | 
    
         
            +
                new_firm = Firm.new("name" => "A New Firm, Inc")
         
     | 
| 
      
 568 
     | 
    
         
            +
                client = new_firm.clients.new("name" => "Apple")
         
     | 
| 
      
 569 
     | 
    
         
            +
                client.throw_on_save = true
         
     | 
| 
      
 570 
     | 
    
         
            +
             
     | 
| 
      
 571 
     | 
    
         
            +
                assert_predicate client, :valid?
         
     | 
| 
      
 572 
     | 
    
         
            +
                assert_predicate new_firm, :valid?
         
     | 
| 
      
 573 
     | 
    
         
            +
                assert_not new_firm.save
         
     | 
| 
      
 574 
     | 
    
         
            +
                assert_not_predicate new_firm, :persisted?
         
     | 
| 
      
 575 
     | 
    
         
            +
                assert_not_predicate client, :persisted?
         
     | 
| 
       517 
576 
     | 
    
         
             
              end
         
     | 
| 
       518 
577 
     | 
    
         | 
| 
       519 
578 
     | 
    
         
             
              def test_invalid_adding_with_validate_false
         
     | 
| 
         @@ -521,10 +580,10 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa 
     | 
|
| 
       521 
580 
     | 
    
         
             
                client = Client.new
         
     | 
| 
       522 
581 
     | 
    
         
             
                firm.unvalidated_clients_of_firm << client
         
     | 
| 
       523 
582 
     | 
    
         | 
| 
       524 
     | 
    
         
            -
                 
     | 
| 
       525 
     | 
    
         
            -
                 
     | 
| 
      
 583 
     | 
    
         
            +
                assert_predicate firm, :valid?
         
     | 
| 
      
 584 
     | 
    
         
            +
                assert_not_predicate client, :valid?
         
     | 
| 
       526 
585 
     | 
    
         
             
                assert firm.save
         
     | 
| 
       527 
     | 
    
         
            -
                 
     | 
| 
      
 586 
     | 
    
         
            +
                assert_not_predicate client, :persisted?
         
     | 
| 
       528 
587 
     | 
    
         
             
              end
         
     | 
| 
       529 
588 
     | 
    
         | 
| 
       530 
589 
     | 
    
         
             
              def test_valid_adding_with_validate_false
         
     | 
| 
         @@ -533,24 +592,52 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa 
     | 
|
| 
       533 
592 
     | 
    
         
             
                firm = Firm.first
         
     | 
| 
       534 
593 
     | 
    
         
             
                client = Client.new("name" => "Apple")
         
     | 
| 
       535 
594 
     | 
    
         | 
| 
       536 
     | 
    
         
            -
                 
     | 
| 
       537 
     | 
    
         
            -
                 
     | 
| 
       538 
     | 
    
         
            -
                 
     | 
| 
      
 595 
     | 
    
         
            +
                assert_predicate firm, :valid?
         
     | 
| 
      
 596 
     | 
    
         
            +
                assert_predicate client, :valid?
         
     | 
| 
      
 597 
     | 
    
         
            +
                assert_not_predicate client, :persisted?
         
     | 
| 
       539 
598 
     | 
    
         | 
| 
       540 
599 
     | 
    
         
             
                firm.unvalidated_clients_of_firm << client
         
     | 
| 
       541 
600 
     | 
    
         | 
| 
       542 
601 
     | 
    
         
             
                assert firm.save
         
     | 
| 
       543 
     | 
    
         
            -
                 
     | 
| 
      
 602 
     | 
    
         
            +
                assert_predicate client, :persisted?
         
     | 
| 
       544 
603 
     | 
    
         
             
                assert_equal no_of_clients + 1, Client.count
         
     | 
| 
       545 
604 
     | 
    
         
             
              end
         
     | 
| 
       546 
605 
     | 
    
         | 
| 
      
 606 
     | 
    
         
            +
              def test_parent_should_save_children_record_with_foreign_key_validation_set_in_before_save_callback
         
     | 
| 
      
 607 
     | 
    
         
            +
                company = NewlyContractedCompany.new(name: "test")
         
     | 
| 
      
 608 
     | 
    
         
            +
             
     | 
| 
      
 609 
     | 
    
         
            +
                assert company.save
         
     | 
| 
      
 610 
     | 
    
         
            +
                assert_not_empty company.reload.new_contracts
         
     | 
| 
      
 611 
     | 
    
         
            +
              end
         
     | 
| 
      
 612 
     | 
    
         
            +
             
     | 
| 
      
 613 
     | 
    
         
            +
              def test_parent_should_not_get_saved_with_duplicate_children_records
         
     | 
| 
      
 614 
     | 
    
         
            +
                assert_no_difference "Reply.count" do
         
     | 
| 
      
 615 
     | 
    
         
            +
                  assert_no_difference "SillyUniqueReply.count" do
         
     | 
| 
      
 616 
     | 
    
         
            +
                    reply = Reply.new
         
     | 
| 
      
 617 
     | 
    
         
            +
                    reply.silly_unique_replies.build([
         
     | 
| 
      
 618 
     | 
    
         
            +
                      { content: "Best content" },
         
     | 
| 
      
 619 
     | 
    
         
            +
                      { content: "Best content" }
         
     | 
| 
      
 620 
     | 
    
         
            +
                    ])
         
     | 
| 
      
 621 
     | 
    
         
            +
             
     | 
| 
      
 622 
     | 
    
         
            +
                    assert_not reply.save
         
     | 
| 
      
 623 
     | 
    
         
            +
                    assert_equal ["is invalid"], reply.errors[:silly_unique_replies]
         
     | 
| 
      
 624 
     | 
    
         
            +
                    assert_empty reply.silly_unique_replies.first.errors
         
     | 
| 
      
 625 
     | 
    
         
            +
             
     | 
| 
      
 626 
     | 
    
         
            +
                    assert_equal(
         
     | 
| 
      
 627 
     | 
    
         
            +
                      ["has already been taken"],
         
     | 
| 
      
 628 
     | 
    
         
            +
                      reply.silly_unique_replies.last.errors[:content]
         
     | 
| 
      
 629 
     | 
    
         
            +
                    )
         
     | 
| 
      
 630 
     | 
    
         
            +
                  end
         
     | 
| 
      
 631 
     | 
    
         
            +
                end
         
     | 
| 
      
 632 
     | 
    
         
            +
              end
         
     | 
| 
      
 633 
     | 
    
         
            +
             
     | 
| 
       547 
634 
     | 
    
         
             
              def test_invalid_build
         
     | 
| 
       548 
635 
     | 
    
         
             
                new_client = companies(:first_firm).clients_of_firm.build
         
     | 
| 
       549 
     | 
    
         
            -
                 
     | 
| 
       550 
     | 
    
         
            -
                 
     | 
| 
      
 636 
     | 
    
         
            +
                assert_not_predicate new_client, :persisted?
         
     | 
| 
      
 637 
     | 
    
         
            +
                assert_not_predicate new_client, :valid?
         
     | 
| 
       551 
638 
     | 
    
         
             
                assert_equal new_client, companies(:first_firm).clients_of_firm.last
         
     | 
| 
       552 
     | 
    
         
            -
                 
     | 
| 
       553 
     | 
    
         
            -
                 
     | 
| 
      
 639 
     | 
    
         
            +
                assert_not companies(:first_firm).save
         
     | 
| 
      
 640 
     | 
    
         
            +
                assert_not_predicate new_client, :persisted?
         
     | 
| 
       554 
641 
     | 
    
         
             
                assert_equal 2, companies(:first_firm).clients_of_firm.reload.size
         
     | 
| 
       555 
642 
     | 
    
         
             
              end
         
     | 
| 
       556 
643 
     | 
    
         | 
| 
         @@ -569,8 +656,8 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa 
     | 
|
| 
       569 
656 
     | 
    
         
             
                assert_equal no_of_firms, Firm.count      # Firm was not saved to database.
         
     | 
| 
       570 
657 
     | 
    
         
             
                assert_equal no_of_clients, Client.count  # Clients were not saved to database.
         
     | 
| 
       571 
658 
     | 
    
         
             
                assert new_firm.save
         
     | 
| 
       572 
     | 
    
         
            -
                 
     | 
| 
       573 
     | 
    
         
            -
                 
     | 
| 
      
 659 
     | 
    
         
            +
                assert_predicate new_firm, :persisted?
         
     | 
| 
      
 660 
     | 
    
         
            +
                assert_predicate c, :persisted?
         
     | 
| 
       574 
661 
     | 
    
         
             
                assert_equal new_firm, c.firm
         
     | 
| 
       575 
662 
     | 
    
         
             
                assert_equal no_of_firms + 1, Firm.count      # Firm was saved to database.
         
     | 
| 
       576 
663 
     | 
    
         
             
                assert_equal no_of_clients + 2, Client.count  # Clients were saved to database.
         
     | 
| 
         @@ -585,58 +672,62 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa 
     | 
|
| 
       585 
672 
     | 
    
         
             
                firm.save
         
     | 
| 
       586 
673 
     | 
    
         
             
                firm.reload
         
     | 
| 
       587 
674 
     | 
    
         
             
                assert_equal 2, firm.clients.length
         
     | 
| 
       588 
     | 
    
         
            -
                 
     | 
| 
      
 675 
     | 
    
         
            +
                assert_includes firm.clients, companies(:second_client)
         
     | 
| 
       589 
676 
     | 
    
         
             
              end
         
     | 
| 
       590 
677 
     | 
    
         | 
| 
       591 
678 
     | 
    
         
             
              def test_assign_ids_for_through_a_belongs_to
         
     | 
| 
       592 
     | 
    
         
            -
                 
     | 
| 
       593 
     | 
    
         
            -
                 
     | 
| 
       594 
     | 
    
         
            -
                 
     | 
| 
       595 
     | 
    
         
            -
                 
     | 
| 
       596 
     | 
    
         
            -
                assert_equal 2,  
     | 
| 
       597 
     | 
    
         
            -
                 
     | 
| 
      
 679 
     | 
    
         
            +
                firm = Firm.new("name" => "Apple")
         
     | 
| 
      
 680 
     | 
    
         
            +
                firm.developer_ids = [developers(:david).id, developers(:jamis).id]
         
     | 
| 
      
 681 
     | 
    
         
            +
                firm.save
         
     | 
| 
      
 682 
     | 
    
         
            +
                firm.reload
         
     | 
| 
      
 683 
     | 
    
         
            +
                assert_equal 2, firm.developers.length
         
     | 
| 
      
 684 
     | 
    
         
            +
                assert_includes firm.developers, developers(:david)
         
     | 
| 
       598 
685 
     | 
    
         
             
              end
         
     | 
| 
       599 
686 
     | 
    
         | 
| 
       600 
687 
     | 
    
         
             
              def test_build_before_save
         
     | 
| 
       601 
688 
     | 
    
         
             
                company = companies(:first_firm)
         
     | 
| 
       602 
     | 
    
         
            -
                new_client = assert_no_queries(ignore_none: false) { company.clients_of_firm.build("name" => "Another Client") }
         
     | 
| 
       603 
     | 
    
         
            -
                assert !company.clients_of_firm.loaded?
         
     | 
| 
       604 
689 
     | 
    
         | 
| 
       605 
     | 
    
         
            -
                company.name  
     | 
| 
      
 690 
     | 
    
         
            +
                new_client = assert_queries(0) { company.clients_of_firm.build("name" => "Another Client") }
         
     | 
| 
      
 691 
     | 
    
         
            +
                assert_not_predicate company.clients_of_firm, :loaded?
         
     | 
| 
      
 692 
     | 
    
         
            +
             
     | 
| 
      
 693 
     | 
    
         
            +
                company.name += "-changed"
         
     | 
| 
       606 
694 
     | 
    
         
             
                assert_queries(2) { assert company.save }
         
     | 
| 
       607 
     | 
    
         
            -
                 
     | 
| 
      
 695 
     | 
    
         
            +
                assert_predicate new_client, :persisted?
         
     | 
| 
       608 
696 
     | 
    
         
             
                assert_equal 3, company.clients_of_firm.reload.size
         
     | 
| 
       609 
697 
     | 
    
         
             
              end
         
     | 
| 
       610 
698 
     | 
    
         | 
| 
       611 
699 
     | 
    
         
             
              def test_build_many_before_save
         
     | 
| 
       612 
700 
     | 
    
         
             
                company = companies(:first_firm)
         
     | 
| 
       613 
     | 
    
         
            -
                assert_no_queries(ignore_none: false) { company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) }
         
     | 
| 
       614 
701 
     | 
    
         | 
| 
       615 
     | 
    
         
            -
                company.name  
     | 
| 
      
 702 
     | 
    
         
            +
                assert_queries(0) { company.clients_of_firm.build([{ "name" => "Another Client" }, { "name" => "Another Client II" }]) }
         
     | 
| 
      
 703 
     | 
    
         
            +
             
     | 
| 
      
 704 
     | 
    
         
            +
                company.name += "-changed"
         
     | 
| 
       616 
705 
     | 
    
         
             
                assert_queries(3) { assert company.save }
         
     | 
| 
       617 
706 
     | 
    
         
             
                assert_equal 4, company.clients_of_firm.reload.size
         
     | 
| 
       618 
707 
     | 
    
         
             
              end
         
     | 
| 
       619 
708 
     | 
    
         | 
| 
       620 
709 
     | 
    
         
             
              def test_build_via_block_before_save
         
     | 
| 
       621 
710 
     | 
    
         
             
                company = companies(:first_firm)
         
     | 
| 
       622 
     | 
    
         
            -
                new_client = assert_no_queries(ignore_none: false) { company.clients_of_firm.build {|client| client.name = "Another Client" } }
         
     | 
| 
       623 
     | 
    
         
            -
                assert !company.clients_of_firm.loaded?
         
     | 
| 
       624 
711 
     | 
    
         | 
| 
       625 
     | 
    
         
            -
                company.name  
     | 
| 
      
 712 
     | 
    
         
            +
                new_client = assert_queries(0) { company.clients_of_firm.build { |client| client.name = "Another Client" } }
         
     | 
| 
      
 713 
     | 
    
         
            +
                assert_not_predicate company.clients_of_firm, :loaded?
         
     | 
| 
      
 714 
     | 
    
         
            +
             
     | 
| 
      
 715 
     | 
    
         
            +
                company.name += "-changed"
         
     | 
| 
       626 
716 
     | 
    
         
             
                assert_queries(2) { assert company.save }
         
     | 
| 
       627 
     | 
    
         
            -
                 
     | 
| 
      
 717 
     | 
    
         
            +
                assert_predicate new_client, :persisted?
         
     | 
| 
       628 
718 
     | 
    
         
             
                assert_equal 3, company.clients_of_firm.reload.size
         
     | 
| 
       629 
719 
     | 
    
         
             
              end
         
     | 
| 
       630 
720 
     | 
    
         | 
| 
       631 
721 
     | 
    
         
             
              def test_build_many_via_block_before_save
         
     | 
| 
       632 
722 
     | 
    
         
             
                company = companies(:first_firm)
         
     | 
| 
       633 
     | 
    
         
            -
             
     | 
| 
       634 
     | 
    
         
            -
             
     | 
| 
      
 723 
     | 
    
         
            +
             
     | 
| 
      
 724 
     | 
    
         
            +
                assert_queries(0) do
         
     | 
| 
      
 725 
     | 
    
         
            +
                  company.clients_of_firm.build([{ "name" => "Another Client" }, { "name" => "Another Client II" }]) do |client|
         
     | 
| 
       635 
726 
     | 
    
         
             
                    client.name = "changed"
         
     | 
| 
       636 
727 
     | 
    
         
             
                  end
         
     | 
| 
       637 
728 
     | 
    
         
             
                end
         
     | 
| 
       638 
729 
     | 
    
         | 
| 
       639 
     | 
    
         
            -
                company.name +=  
     | 
| 
      
 730 
     | 
    
         
            +
                company.name += "-changed"
         
     | 
| 
       640 
731 
     | 
    
         
             
                assert_queries(3) { assert company.save }
         
     | 
| 
       641 
732 
     | 
    
         
             
                assert_equal 4, company.clients_of_firm.reload.size
         
     | 
| 
       642 
733 
     | 
    
         
             
              end
         
     | 
| 
         @@ -647,7 +738,16 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa 
     | 
|
| 
       647 
738 
     | 
    
         
             
                assert firm.save
         
     | 
| 
       648 
739 
     | 
    
         
             
                firm.reload
         
     | 
| 
       649 
740 
     | 
    
         
             
                assert_equal 2, firm.clients.length
         
     | 
| 
       650 
     | 
    
         
            -
                 
     | 
| 
      
 741 
     | 
    
         
            +
                assert_includes firm.clients, Client.find_by_name("New Client")
         
     | 
| 
      
 742 
     | 
    
         
            +
              end
         
     | 
| 
      
 743 
     | 
    
         
            +
             
     | 
| 
      
 744 
     | 
    
         
            +
              def test_replace_on_duplicated_object
         
     | 
| 
      
 745 
     | 
    
         
            +
                firm = Firm.create!("name" => "New Firm").dup
         
     | 
| 
      
 746 
     | 
    
         
            +
                firm.clients = [companies(:second_client), Client.new("name" => "New Client")]
         
     | 
| 
      
 747 
     | 
    
         
            +
                assert firm.save
         
     | 
| 
      
 748 
     | 
    
         
            +
                firm.reload
         
     | 
| 
      
 749 
     | 
    
         
            +
                assert_equal 2, firm.clients.length
         
     | 
| 
      
 750 
     | 
    
         
            +
                assert_includes firm.clients, Client.find_by_name("New Client")
         
     | 
| 
       651 
751 
     | 
    
         
             
              end
         
     | 
| 
       652 
752 
     | 
    
         
             
            end
         
     | 
| 
       653 
753 
     | 
    
         | 
| 
         @@ -656,79 +756,88 @@ class TestDefaultAutosaveAssociationOnNewRecord < ActiveRecord::TestCase 
     | 
|
| 
       656 
756 
     | 
    
         
             
                new_account = Account.new("credit_limit" => 1000)
         
     | 
| 
       657 
757 
     | 
    
         
             
                new_firm = Firm.new("name" => "some firm")
         
     | 
| 
       658 
758 
     | 
    
         | 
| 
       659 
     | 
    
         
            -
                 
     | 
| 
      
 759 
     | 
    
         
            +
                assert_not_predicate new_firm, :persisted?
         
     | 
| 
       660 
760 
     | 
    
         
             
                new_account.firm = new_firm
         
     | 
| 
       661 
761 
     | 
    
         
             
                new_account.save!
         
     | 
| 
       662 
762 
     | 
    
         | 
| 
       663 
     | 
    
         
            -
                 
     | 
| 
      
 763 
     | 
    
         
            +
                assert_predicate new_firm, :persisted?
         
     | 
| 
       664 
764 
     | 
    
         | 
| 
       665 
765 
     | 
    
         
             
                new_account = Account.new("credit_limit" => 1000)
         
     | 
| 
       666 
766 
     | 
    
         
             
                new_autosaved_firm = Firm.new("name" => "some firm")
         
     | 
| 
       667 
767 
     | 
    
         | 
| 
       668 
     | 
    
         
            -
                 
     | 
| 
      
 768 
     | 
    
         
            +
                assert_not_predicate new_autosaved_firm, :persisted?
         
     | 
| 
       669 
769 
     | 
    
         
             
                new_account.unautosaved_firm = new_autosaved_firm
         
     | 
| 
       670 
770 
     | 
    
         
             
                new_account.save!
         
     | 
| 
       671 
771 
     | 
    
         | 
| 
       672 
     | 
    
         
            -
                 
     | 
| 
      
 772 
     | 
    
         
            +
                assert_not_predicate new_autosaved_firm, :persisted?
         
     | 
| 
       673 
773 
     | 
    
         
             
              end
         
     | 
| 
       674 
774 
     | 
    
         | 
| 
       675 
775 
     | 
    
         
             
              def test_autosave_new_record_on_has_one_can_be_disabled_per_relationship
         
     | 
| 
       676 
776 
     | 
    
         
             
                firm = Firm.new("name" => "some firm")
         
     | 
| 
       677 
777 
     | 
    
         
             
                account = Account.new("credit_limit" => 1000)
         
     | 
| 
       678 
778 
     | 
    
         | 
| 
       679 
     | 
    
         
            -
                 
     | 
| 
      
 779 
     | 
    
         
            +
                assert_not_predicate account, :persisted?
         
     | 
| 
       680 
780 
     | 
    
         
             
                firm.account = account
         
     | 
| 
       681 
781 
     | 
    
         
             
                firm.save!
         
     | 
| 
       682 
782 
     | 
    
         | 
| 
       683 
     | 
    
         
            -
                 
     | 
| 
      
 783 
     | 
    
         
            +
                assert_predicate account, :persisted?
         
     | 
| 
       684 
784 
     | 
    
         | 
| 
       685 
785 
     | 
    
         
             
                firm = Firm.new("name" => "some firm")
         
     | 
| 
       686 
786 
     | 
    
         
             
                account = Account.new("credit_limit" => 1000)
         
     | 
| 
       687 
787 
     | 
    
         | 
| 
       688 
788 
     | 
    
         
             
                firm.unautosaved_account = account
         
     | 
| 
       689 
789 
     | 
    
         | 
| 
       690 
     | 
    
         
            -
                 
     | 
| 
      
 790 
     | 
    
         
            +
                assert_not_predicate account, :persisted?
         
     | 
| 
       691 
791 
     | 
    
         
             
                firm.unautosaved_account = account
         
     | 
| 
       692 
792 
     | 
    
         
             
                firm.save!
         
     | 
| 
       693 
793 
     | 
    
         | 
| 
       694 
     | 
    
         
            -
                 
     | 
| 
      
 794 
     | 
    
         
            +
                assert_not_predicate account, :persisted?
         
     | 
| 
       695 
795 
     | 
    
         
             
              end
         
     | 
| 
       696 
796 
     | 
    
         | 
| 
       697 
797 
     | 
    
         
             
              def test_autosave_new_record_on_has_many_can_be_disabled_per_relationship
         
     | 
| 
       698 
798 
     | 
    
         
             
                firm = Firm.new("name" => "some firm")
         
     | 
| 
       699 
799 
     | 
    
         
             
                account = Account.new("credit_limit" => 1000)
         
     | 
| 
       700 
800 
     | 
    
         | 
| 
       701 
     | 
    
         
            -
                 
     | 
| 
      
 801 
     | 
    
         
            +
                assert_not_predicate account, :persisted?
         
     | 
| 
       702 
802 
     | 
    
         
             
                firm.accounts << account
         
     | 
| 
       703 
803 
     | 
    
         | 
| 
       704 
804 
     | 
    
         
             
                firm.save!
         
     | 
| 
       705 
     | 
    
         
            -
                 
     | 
| 
      
 805 
     | 
    
         
            +
                assert_predicate account, :persisted?
         
     | 
| 
       706 
806 
     | 
    
         | 
| 
       707 
807 
     | 
    
         
             
                firm = Firm.new("name" => "some firm")
         
     | 
| 
       708 
808 
     | 
    
         
             
                account = Account.new("credit_limit" => 1000)
         
     | 
| 
       709 
809 
     | 
    
         | 
| 
       710 
     | 
    
         
            -
                 
     | 
| 
      
 810 
     | 
    
         
            +
                assert_not_predicate account, :persisted?
         
     | 
| 
       711 
811 
     | 
    
         
             
                firm.unautosaved_accounts << account
         
     | 
| 
       712 
812 
     | 
    
         | 
| 
       713 
813 
     | 
    
         
             
                firm.save!
         
     | 
| 
       714 
     | 
    
         
            -
                 
     | 
| 
      
 814 
     | 
    
         
            +
                assert_not_predicate account, :persisted?
         
     | 
| 
       715 
815 
     | 
    
         
             
              end
         
     | 
| 
       716 
816 
     | 
    
         | 
| 
       717 
817 
     | 
    
         
             
              def test_autosave_new_record_with_after_create_callback
         
     | 
| 
       718 
     | 
    
         
            -
                post = PostWithAfterCreateCallback.new(title:  
     | 
| 
       719 
     | 
    
         
            -
                post.comments.build(body:  
     | 
| 
      
 818 
     | 
    
         
            +
                post = PostWithAfterCreateCallback.new(title: "Captain Murphy", body: "is back")
         
     | 
| 
      
 819 
     | 
    
         
            +
                post.comments.build(body: "foo")
         
     | 
| 
       720 
820 
     | 
    
         
             
                post.save!
         
     | 
| 
       721 
821 
     | 
    
         | 
| 
       722 
822 
     | 
    
         
             
                assert_not_nil post.author_id
         
     | 
| 
       723 
823 
     | 
    
         
             
              end
         
     | 
| 
      
 824 
     | 
    
         
            +
             
     | 
| 
      
 825 
     | 
    
         
            +
              def test_autosave_new_record_with_after_create_callback_and_habtm_association
         
     | 
| 
      
 826 
     | 
    
         
            +
                post = PostWithAfterCreateCallback.new(title: "Captain Murphy", body: "is back")
         
     | 
| 
      
 827 
     | 
    
         
            +
                post.comments.build(body: "foo")
         
     | 
| 
      
 828 
     | 
    
         
            +
                post.categories.build(name: "bar")
         
     | 
| 
      
 829 
     | 
    
         
            +
                post.save!
         
     | 
| 
      
 830 
     | 
    
         
            +
             
     | 
| 
      
 831 
     | 
    
         
            +
                assert_equal 1, post.categories.reload.length
         
     | 
| 
      
 832 
     | 
    
         
            +
              end
         
     | 
| 
       724 
833 
     | 
    
         
             
            end
         
     | 
| 
       725 
834 
     | 
    
         | 
| 
       726 
835 
     | 
    
         
             
            class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase
         
     | 
| 
       727 
836 
     | 
    
         
             
              self.use_transactional_tests = false
         
     | 
| 
       728 
837 
     | 
    
         | 
| 
       729 
838 
     | 
    
         
             
              setup do
         
     | 
| 
       730 
     | 
    
         
            -
                @pirate = Pirate.create(: 
     | 
| 
       731 
     | 
    
         
            -
                @ship = @pirate.create_ship(: 
     | 
| 
      
 839 
     | 
    
         
            +
                @pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?")
         
     | 
| 
      
 840 
     | 
    
         
            +
                @ship = @pirate.create_ship(name: "Nights Dirty Lightning")
         
     | 
| 
       732 
841 
     | 
    
         
             
              end
         
     | 
| 
       733 
842 
     | 
    
         | 
| 
       734 
843 
     | 
    
         
             
              teardown do
         
     | 
| 
         @@ -744,18 +853,18 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase 
     | 
|
| 
       744 
853 
     | 
    
         
             
                @pirate.mark_for_destruction
         
     | 
| 
       745 
854 
     | 
    
         
             
                @pirate.ship.mark_for_destruction
         
     | 
| 
       746 
855 
     | 
    
         | 
| 
       747 
     | 
    
         
            -
                 
     | 
| 
       748 
     | 
    
         
            -
                 
     | 
| 
      
 856 
     | 
    
         
            +
                assert_not_predicate @pirate.reload, :marked_for_destruction?
         
     | 
| 
      
 857 
     | 
    
         
            +
                assert_not_predicate @pirate.ship.reload, :marked_for_destruction?
         
     | 
| 
       749 
858 
     | 
    
         
             
              end
         
     | 
| 
       750 
859 
     | 
    
         | 
| 
       751 
860 
     | 
    
         
             
              # has_one
         
     | 
| 
       752 
861 
     | 
    
         
             
              def test_should_destroy_a_child_association_as_part_of_the_save_transaction_if_it_was_marked_for_destruction
         
     | 
| 
       753 
     | 
    
         
            -
                 
     | 
| 
      
 862 
     | 
    
         
            +
                assert_not_predicate @pirate.ship, :marked_for_destruction?
         
     | 
| 
       754 
863 
     | 
    
         | 
| 
       755 
864 
     | 
    
         
             
                @pirate.ship.mark_for_destruction
         
     | 
| 
       756 
865 
     | 
    
         
             
                id = @pirate.ship.id
         
     | 
| 
       757 
866 
     | 
    
         | 
| 
       758 
     | 
    
         
            -
                 
     | 
| 
      
 867 
     | 
    
         
            +
                assert_predicate @pirate.ship, :marked_for_destruction?
         
     | 
| 
       759 
868 
     | 
    
         
             
                assert Ship.find_by_id(id)
         
     | 
| 
       760 
869 
     | 
    
         | 
| 
       761 
870 
     | 
    
         
             
                @pirate.save
         
     | 
| 
         @@ -764,12 +873,13 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase 
     | 
|
| 
       764 
873 
     | 
    
         
             
              end
         
     | 
| 
       765 
874 
     | 
    
         | 
| 
       766 
875 
     | 
    
         
             
              def test_should_skip_validation_on_a_child_association_if_marked_for_destruction
         
     | 
| 
       767 
     | 
    
         
            -
                @pirate.ship.name =  
     | 
| 
       768 
     | 
    
         
            -
                 
     | 
| 
      
 876 
     | 
    
         
            +
                @pirate.ship.name = ""
         
     | 
| 
      
 877 
     | 
    
         
            +
                assert_not_predicate @pirate, :valid?
         
     | 
| 
       769 
878 
     | 
    
         | 
| 
       770 
879 
     | 
    
         
             
                @pirate.ship.mark_for_destruction
         
     | 
| 
       771 
     | 
    
         
            -
                @pirate.ship 
     | 
| 
       772 
     | 
    
         
            -
             
     | 
| 
      
 880 
     | 
    
         
            +
                assert_not_called(@pirate.ship, :valid?) do
         
     | 
| 
      
 881 
     | 
    
         
            +
                  assert_difference("Ship.count", -1) { @pirate.save! }
         
     | 
| 
      
 882 
     | 
    
         
            +
                end
         
     | 
| 
       773 
883 
     | 
    
         
             
              end
         
     | 
| 
       774 
884 
     | 
    
         | 
| 
       775 
885 
     | 
    
         
             
              def test_a_child_marked_for_destruction_should_not_be_destroyed_twice
         
     | 
| 
         @@ -784,16 +894,17 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase 
     | 
|
| 
       784 
894 
     | 
    
         
             
              def test_should_rollback_destructions_if_an_exception_occurred_while_saving_a_child
         
     | 
| 
       785 
895 
     | 
    
         
             
                # Stub the save method of the @pirate.ship instance to destroy and then raise an exception
         
     | 
| 
       786 
896 
     | 
    
         
             
                class << @pirate.ship
         
     | 
| 
       787 
     | 
    
         
            -
                  def save( 
     | 
| 
      
 897 
     | 
    
         
            +
                  def save(**)
         
     | 
| 
       788 
898 
     | 
    
         
             
                    super
         
     | 
| 
       789 
899 
     | 
    
         
             
                    destroy
         
     | 
| 
       790 
     | 
    
         
            -
                    raise  
     | 
| 
      
 900 
     | 
    
         
            +
                    raise "Oh noes!"
         
     | 
| 
       791 
901 
     | 
    
         
             
                  end
         
     | 
| 
       792 
902 
     | 
    
         
             
                end
         
     | 
| 
       793 
903 
     | 
    
         | 
| 
       794 
904 
     | 
    
         
             
                @ship.pirate.catchphrase = "Changed Catchphrase"
         
     | 
| 
      
 905 
     | 
    
         
            +
                @ship.name_will_change!
         
     | 
| 
       795 
906 
     | 
    
         | 
| 
       796 
     | 
    
         
            -
                assert_raise(RuntimeError) {  
     | 
| 
      
 907 
     | 
    
         
            +
                assert_raise(RuntimeError) { assert_not @pirate.save }
         
     | 
| 
       797 
908 
     | 
    
         
             
                assert_not_nil @pirate.reload.ship
         
     | 
| 
       798 
909 
     | 
    
         
             
              end
         
     | 
| 
       799 
910 
     | 
    
         | 
| 
         @@ -804,18 +915,19 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase 
     | 
|
| 
       804 
915 
     | 
    
         
             
              end
         
     | 
| 
       805 
916 
     | 
    
         | 
| 
       806 
917 
     | 
    
         
             
              def test_should_not_save_changed_has_one_unchanged_object_if_child_is_saved
         
     | 
| 
       807 
     | 
    
         
            -
                @pirate.ship 
     | 
| 
       808 
     | 
    
         
            -
             
     | 
| 
      
 918 
     | 
    
         
            +
                assert_not_called(@pirate.ship, :save) do
         
     | 
| 
      
 919 
     | 
    
         
            +
                  assert @pirate.save
         
     | 
| 
      
 920 
     | 
    
         
            +
                end
         
     | 
| 
       809 
921 
     | 
    
         
             
              end
         
     | 
| 
       810 
922 
     | 
    
         | 
| 
       811 
923 
     | 
    
         
             
              # belongs_to
         
     | 
| 
       812 
924 
     | 
    
         
             
              def test_should_destroy_a_parent_association_as_part_of_the_save_transaction_if_it_was_marked_for_destruction
         
     | 
| 
       813 
     | 
    
         
            -
                 
     | 
| 
      
 925 
     | 
    
         
            +
                assert_not_predicate @ship.pirate, :marked_for_destruction?
         
     | 
| 
       814 
926 
     | 
    
         | 
| 
       815 
927 
     | 
    
         
             
                @ship.pirate.mark_for_destruction
         
     | 
| 
       816 
928 
     | 
    
         
             
                id = @ship.pirate.id
         
     | 
| 
       817 
929 
     | 
    
         | 
| 
       818 
     | 
    
         
            -
                 
     | 
| 
      
 930 
     | 
    
         
            +
                assert_predicate @ship.pirate, :marked_for_destruction?
         
     | 
| 
       819 
931 
     | 
    
         
             
                assert Pirate.find_by_id(id)
         
     | 
| 
       820 
932 
     | 
    
         | 
| 
       821 
933 
     | 
    
         
             
                @ship.save
         
     | 
| 
         @@ -824,12 +936,13 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase 
     | 
|
| 
       824 
936 
     | 
    
         
             
              end
         
     | 
| 
       825 
937 
     | 
    
         | 
| 
       826 
938 
     | 
    
         
             
              def test_should_skip_validation_on_a_parent_association_if_marked_for_destruction
         
     | 
| 
       827 
     | 
    
         
            -
                @ship.pirate.catchphrase =  
     | 
| 
       828 
     | 
    
         
            -
                 
     | 
| 
      
 939 
     | 
    
         
            +
                @ship.pirate.catchphrase = ""
         
     | 
| 
      
 940 
     | 
    
         
            +
                assert_not_predicate @ship, :valid?
         
     | 
| 
       829 
941 
     | 
    
         | 
| 
       830 
942 
     | 
    
         
             
                @ship.pirate.mark_for_destruction
         
     | 
| 
       831 
     | 
    
         
            -
                @ship.pirate 
     | 
| 
       832 
     | 
    
         
            -
             
     | 
| 
      
 943 
     | 
    
         
            +
                assert_not_called(@ship.pirate, :valid?) do
         
     | 
| 
      
 944 
     | 
    
         
            +
                  assert_difference("Pirate.count", -1) { @ship.save! }
         
     | 
| 
      
 945 
     | 
    
         
            +
                end
         
     | 
| 
       833 
946 
     | 
    
         
             
              end
         
     | 
| 
       834 
947 
     | 
    
         | 
| 
       835 
948 
     | 
    
         
             
              def test_a_parent_marked_for_destruction_should_not_be_destroyed_twice
         
     | 
| 
         @@ -844,32 +957,32 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase 
     | 
|
| 
       844 
957 
     | 
    
         
             
              def test_should_rollback_destructions_if_an_exception_occurred_while_saving_a_parent
         
     | 
| 
       845 
958 
     | 
    
         
             
                # Stub the save method of the @ship.pirate instance to destroy and then raise an exception
         
     | 
| 
       846 
959 
     | 
    
         
             
                class << @ship.pirate
         
     | 
| 
       847 
     | 
    
         
            -
                  def save( 
     | 
| 
      
 960 
     | 
    
         
            +
                  def save(**)
         
     | 
| 
       848 
961 
     | 
    
         
             
                    super
         
     | 
| 
       849 
962 
     | 
    
         
             
                    destroy
         
     | 
| 
       850 
     | 
    
         
            -
                    raise  
     | 
| 
      
 963 
     | 
    
         
            +
                    raise "Oh noes!"
         
     | 
| 
       851 
964 
     | 
    
         
             
                  end
         
     | 
| 
       852 
965 
     | 
    
         
             
                end
         
     | 
| 
       853 
966 
     | 
    
         | 
| 
       854 
967 
     | 
    
         
             
                @ship.pirate.catchphrase = "Changed Catchphrase"
         
     | 
| 
       855 
968 
     | 
    
         | 
| 
       856 
     | 
    
         
            -
                assert_raise(RuntimeError) {  
     | 
| 
      
 969 
     | 
    
         
            +
                assert_raise(RuntimeError) { assert_not @ship.save }
         
     | 
| 
       857 
970 
     | 
    
         
             
                assert_not_nil @ship.reload.pirate
         
     | 
| 
       858 
971 
     | 
    
         
             
              end
         
     | 
| 
       859 
972 
     | 
    
         | 
| 
       860 
973 
     | 
    
         
             
              def test_should_save_changed_child_objects_if_parent_is_saved
         
     | 
| 
       861 
     | 
    
         
            -
                @pirate = @ship.create_pirate(: 
     | 
| 
       862 
     | 
    
         
            -
                @parrot = @pirate.parrots.create!(: 
     | 
| 
      
 974 
     | 
    
         
            +
                @pirate = @ship.create_pirate(catchphrase: "Don' botharrr talkin' like one, savvy?")
         
     | 
| 
      
 975 
     | 
    
         
            +
                @parrot = @pirate.parrots.create!(name: "Posideons Killer")
         
     | 
| 
       863 
976 
     | 
    
         
             
                @parrot.name = "NewName"
         
     | 
| 
       864 
977 
     | 
    
         
             
                @ship.save
         
     | 
| 
       865 
978 
     | 
    
         | 
| 
       866 
     | 
    
         
            -
                assert_equal  
     | 
| 
      
 979 
     | 
    
         
            +
                assert_equal "NewName", @parrot.reload.name
         
     | 
| 
       867 
980 
     | 
    
         
             
              end
         
     | 
| 
       868 
981 
     | 
    
         | 
| 
       869 
982 
     | 
    
         
             
              def test_should_destroy_has_many_as_part_of_the_save_transaction_if_they_were_marked_for_destruction
         
     | 
| 
       870 
     | 
    
         
            -
                2.times { |i| @pirate.birds.create!(: 
     | 
| 
      
 983 
     | 
    
         
            +
                2.times { |i| @pirate.birds.create!(name: "birds_#{i}") }
         
     | 
| 
       871 
984 
     | 
    
         | 
| 
       872 
     | 
    
         
            -
                 
     | 
| 
      
 985 
     | 
    
         
            +
                assert_not @pirate.birds.any?(&:marked_for_destruction?)
         
     | 
| 
       873 
986 
     | 
    
         | 
| 
       874 
987 
     | 
    
         
             
                @pirate.birds.each(&:mark_for_destruction)
         
     | 
| 
       875 
988 
     | 
    
         
             
                klass = @pirate.birds.first.class
         
     | 
| 
         @@ -879,7 +992,7 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase 
     | 
|
| 
       879 
992 
     | 
    
         
             
                ids.each { |id| assert klass.find_by_id(id) }
         
     | 
| 
       880 
993 
     | 
    
         | 
| 
       881 
994 
     | 
    
         
             
                @pirate.save
         
     | 
| 
       882 
     | 
    
         
            -
                 
     | 
| 
      
 995 
     | 
    
         
            +
                assert_empty @pirate.reload.birds
         
     | 
| 
       883 
996 
     | 
    
         
             
                ids.each { |id| assert_nil klass.find_by_id(id) }
         
     | 
| 
       884 
997 
     | 
    
         
             
              end
         
     | 
| 
       885 
998 
     | 
    
         | 
| 
         @@ -887,62 +1000,67 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase 
     | 
|
| 
       887 
1000 
     | 
    
         
             
                @pirate.birds.create!(name: :parrot)
         
     | 
| 
       888 
1001 
     | 
    
         
             
                @pirate.birds.first.destroy
         
     | 
| 
       889 
1002 
     | 
    
         
             
                @pirate.save!
         
     | 
| 
       890 
     | 
    
         
            -
                 
     | 
| 
      
 1003 
     | 
    
         
            +
                assert_empty @pirate.reload.birds
         
     | 
| 
       891 
1004 
     | 
    
         
             
              end
         
     | 
| 
       892 
1005 
     | 
    
         | 
| 
       893 
1006 
     | 
    
         
             
              def test_should_skip_validation_on_has_many_if_marked_for_destruction
         
     | 
| 
       894 
     | 
    
         
            -
                2.times { |i| @pirate.birds.create!(: 
     | 
| 
      
 1007 
     | 
    
         
            +
                2.times { |i| @pirate.birds.create!(name: "birds_#{i}") }
         
     | 
| 
       895 
1008 
     | 
    
         | 
| 
       896 
     | 
    
         
            -
                @pirate.birds.each { |bird| bird.name =  
     | 
| 
       897 
     | 
    
         
            -
                 
     | 
| 
      
 1009 
     | 
    
         
            +
                @pirate.birds.each { |bird| bird.name = "" }
         
     | 
| 
      
 1010 
     | 
    
         
            +
                assert_not_predicate @pirate, :valid?
         
     | 
| 
       898 
1011 
     | 
    
         | 
| 
       899 
     | 
    
         
            -
                @pirate.birds.each 
     | 
| 
       900 
     | 
    
         
            -
             
     | 
| 
       901 
     | 
    
         
            -
             
     | 
| 
      
 1012 
     | 
    
         
            +
                @pirate.birds.each(&:mark_for_destruction)
         
     | 
| 
      
 1013 
     | 
    
         
            +
             
     | 
| 
      
 1014 
     | 
    
         
            +
                assert_not_called(@pirate.birds.first, :valid?) do
         
     | 
| 
      
 1015 
     | 
    
         
            +
                  assert_not_called(@pirate.birds.last, :valid?) do
         
     | 
| 
      
 1016 
     | 
    
         
            +
                    assert_difference("Bird.count", -2) { @pirate.save! }
         
     | 
| 
      
 1017 
     | 
    
         
            +
                  end
         
     | 
| 
       902 
1018 
     | 
    
         
             
                end
         
     | 
| 
       903 
     | 
    
         
            -
                assert_difference("Bird.count", -2) { @pirate.save! }
         
     | 
| 
       904 
1019 
     | 
    
         
             
              end
         
     | 
| 
       905 
1020 
     | 
    
         | 
| 
       906 
1021 
     | 
    
         
             
              def test_should_skip_validation_on_has_many_if_destroyed
         
     | 
| 
       907 
     | 
    
         
            -
                @pirate.birds.create!(: 
     | 
| 
      
 1022 
     | 
    
         
            +
                @pirate.birds.create!(name: "birds_1")
         
     | 
| 
       908 
1023 
     | 
    
         | 
| 
       909 
     | 
    
         
            -
                @pirate.birds.each { |bird| bird.name =  
     | 
| 
       910 
     | 
    
         
            -
                 
     | 
| 
      
 1024 
     | 
    
         
            +
                @pirate.birds.each { |bird| bird.name = "" }
         
     | 
| 
      
 1025 
     | 
    
         
            +
                assert_not_predicate @pirate, :valid?
         
     | 
| 
       911 
1026 
     | 
    
         | 
| 
       912 
1027 
     | 
    
         
             
                @pirate.birds.each(&:destroy)
         
     | 
| 
       913 
     | 
    
         
            -
                 
     | 
| 
      
 1028 
     | 
    
         
            +
                assert_predicate @pirate, :valid?
         
     | 
| 
       914 
1029 
     | 
    
         
             
              end
         
     | 
| 
       915 
1030 
     | 
    
         | 
| 
       916 
1031 
     | 
    
         
             
              def test_a_child_marked_for_destruction_should_not_be_destroyed_twice_while_saving_has_many
         
     | 
| 
       917 
     | 
    
         
            -
                @pirate.birds.create!(: 
     | 
| 
      
 1032 
     | 
    
         
            +
                @pirate.birds.create!(name: "birds_1")
         
     | 
| 
       918 
1033 
     | 
    
         | 
| 
       919 
1034 
     | 
    
         
             
                @pirate.birds.each(&:mark_for_destruction)
         
     | 
| 
       920 
1035 
     | 
    
         
             
                assert @pirate.save
         
     | 
| 
       921 
1036 
     | 
    
         | 
| 
       922 
     | 
    
         
            -
                @pirate.birds.each  
     | 
| 
       923 
     | 
    
         
            -
             
     | 
| 
      
 1037 
     | 
    
         
            +
                @pirate.birds.each do |bird|
         
     | 
| 
      
 1038 
     | 
    
         
            +
                  assert_not_called(bird, :destroy) do
         
     | 
| 
      
 1039 
     | 
    
         
            +
                    assert @pirate.save
         
     | 
| 
      
 1040 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1041 
     | 
    
         
            +
                end
         
     | 
| 
       924 
1042 
     | 
    
         
             
              end
         
     | 
| 
       925 
1043 
     | 
    
         | 
| 
       926 
1044 
     | 
    
         
             
              def test_should_rollback_destructions_if_an_exception_occurred_while_saving_has_many
         
     | 
| 
       927 
     | 
    
         
            -
                2.times { |i| @pirate.birds.create!(: 
     | 
| 
      
 1045 
     | 
    
         
            +
                2.times { |i| @pirate.birds.create!(name: "birds_#{i}") }
         
     | 
| 
       928 
1046 
     | 
    
         
             
                before = @pirate.birds.map { |c| c.mark_for_destruction ; c }
         
     | 
| 
       929 
1047 
     | 
    
         | 
| 
       930 
1048 
     | 
    
         
             
                # Stub the destroy method of the second child to raise an exception
         
     | 
| 
       931 
1049 
     | 
    
         
             
                class << before.last
         
     | 
| 
       932 
1050 
     | 
    
         
             
                  def destroy(*args)
         
     | 
| 
       933 
1051 
     | 
    
         
             
                    super
         
     | 
| 
       934 
     | 
    
         
            -
                    raise  
     | 
| 
      
 1052 
     | 
    
         
            +
                    raise "Oh noes!"
         
     | 
| 
       935 
1053 
     | 
    
         
             
                  end
         
     | 
| 
       936 
1054 
     | 
    
         
             
                end
         
     | 
| 
       937 
1055 
     | 
    
         | 
| 
       938 
     | 
    
         
            -
                assert_raise(RuntimeError) {  
     | 
| 
      
 1056 
     | 
    
         
            +
                assert_raise(RuntimeError) { assert_not @pirate.save }
         
     | 
| 
       939 
1057 
     | 
    
         
             
                assert_equal before, @pirate.reload.birds
         
     | 
| 
       940 
1058 
     | 
    
         
             
              end
         
     | 
| 
       941 
1059 
     | 
    
         | 
| 
       942 
1060 
     | 
    
         
             
              def test_when_new_record_a_child_marked_for_destruction_should_not_affect_other_records_from_saving
         
     | 
| 
       943 
     | 
    
         
            -
                @pirate = @ship.build_pirate(: 
     | 
| 
      
 1061 
     | 
    
         
            +
                @pirate = @ship.build_pirate(catchphrase: "Arr' now I shall keep me eye on you matey!") # new record
         
     | 
| 
       944 
1062 
     | 
    
         | 
| 
       945 
     | 
    
         
            -
                3.times { |i| @pirate.birds.build(: 
     | 
| 
      
 1063 
     | 
    
         
            +
                3.times { |i| @pirate.birds.build(name: "birds_#{i}") }
         
     | 
| 
       946 
1064 
     | 
    
         
             
                @pirate.birds[1].mark_for_destruction
         
     | 
| 
       947 
1065 
     | 
    
         
             
                @pirate.save!
         
     | 
| 
       948 
1066 
     | 
    
         | 
| 
         @@ -968,8 +1086,8 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase 
     | 
|
| 
       968 
1086 
     | 
    
         
             
                define_method("test_should_run_add_callback_#{callback_type}s_for_has_many") do
         
     | 
| 
       969 
1087 
     | 
    
         
             
                  association_name_with_callbacks = "birds_with_#{callback_type}_callbacks"
         
     | 
| 
       970 
1088 
     | 
    
         | 
| 
       971 
     | 
    
         
            -
                  pirate = Pirate.new(: 
     | 
| 
       972 
     | 
    
         
            -
                  pirate. 
     | 
| 
      
 1089 
     | 
    
         
            +
                  pirate = Pirate.new(catchphrase: "Arr")
         
     | 
| 
      
 1090 
     | 
    
         
            +
                  pirate.public_send(association_name_with_callbacks).build(name: "Crowe the One-Eyed")
         
     | 
| 
       973 
1091 
     | 
    
         | 
| 
       974 
1092 
     | 
    
         
             
                  expected = [
         
     | 
| 
       975 
1093 
     | 
    
         
             
                    "before_adding_#{callback_type}_bird_<new>",
         
     | 
| 
         @@ -982,9 +1100,9 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase 
     | 
|
| 
       982 
1100 
     | 
    
         
             
                define_method("test_should_run_remove_callback_#{callback_type}s_for_has_many") do
         
     | 
| 
       983 
1101 
     | 
    
         
             
                  association_name_with_callbacks = "birds_with_#{callback_type}_callbacks"
         
     | 
| 
       984 
1102 
     | 
    
         | 
| 
       985 
     | 
    
         
            -
                  @pirate. 
     | 
| 
       986 
     | 
    
         
            -
                  @pirate. 
     | 
| 
       987 
     | 
    
         
            -
                  child_id = @pirate. 
     | 
| 
      
 1103 
     | 
    
         
            +
                  @pirate.public_send(association_name_with_callbacks).create!(name: "Crowe the One-Eyed")
         
     | 
| 
      
 1104 
     | 
    
         
            +
                  @pirate.public_send(association_name_with_callbacks).each(&:mark_for_destruction)
         
     | 
| 
      
 1105 
     | 
    
         
            +
                  child_id = @pirate.public_send(association_name_with_callbacks).first.id
         
     | 
| 
       988 
1106 
     | 
    
         | 
| 
       989 
1107 
     | 
    
         
             
                  @pirate.ship_log.clear
         
     | 
| 
       990 
1108 
     | 
    
         
             
                  @pirate.save
         
     | 
| 
         @@ -999,71 +1117,73 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase 
     | 
|
| 
       999 
1117 
     | 
    
         
             
              end
         
     | 
| 
       1000 
1118 
     | 
    
         | 
| 
       1001 
1119 
     | 
    
         
             
              def test_should_destroy_habtm_as_part_of_the_save_transaction_if_they_were_marked_for_destruction
         
     | 
| 
       1002 
     | 
    
         
            -
                2.times { |i| @pirate.parrots.create!(: 
     | 
| 
      
 1120 
     | 
    
         
            +
                2.times { |i| @pirate.parrots.create!(name: "parrots_#{i}") }
         
     | 
| 
       1003 
1121 
     | 
    
         | 
| 
       1004 
     | 
    
         
            -
                 
     | 
| 
      
 1122 
     | 
    
         
            +
                assert_not @pirate.parrots.any?(&:marked_for_destruction?)
         
     | 
| 
       1005 
1123 
     | 
    
         
             
                @pirate.parrots.each(&:mark_for_destruction)
         
     | 
| 
       1006 
1124 
     | 
    
         | 
| 
       1007 
1125 
     | 
    
         
             
                assert_no_difference "Parrot.count" do
         
     | 
| 
       1008 
1126 
     | 
    
         
             
                  @pirate.save
         
     | 
| 
       1009 
1127 
     | 
    
         
             
                end
         
     | 
| 
       1010 
1128 
     | 
    
         | 
| 
       1011 
     | 
    
         
            -
                 
     | 
| 
      
 1129 
     | 
    
         
            +
                assert_empty @pirate.reload.parrots
         
     | 
| 
       1012 
1130 
     | 
    
         | 
| 
       1013 
1131 
     | 
    
         
             
                join_records = Pirate.connection.select_all("SELECT * FROM parrots_pirates WHERE pirate_id = #{@pirate.id}")
         
     | 
| 
       1014 
     | 
    
         
            -
                 
     | 
| 
      
 1132 
     | 
    
         
            +
                assert_empty join_records
         
     | 
| 
       1015 
1133 
     | 
    
         
             
              end
         
     | 
| 
       1016 
1134 
     | 
    
         | 
| 
       1017 
1135 
     | 
    
         
             
              def test_should_skip_validation_on_habtm_if_marked_for_destruction
         
     | 
| 
       1018 
     | 
    
         
            -
                2.times { |i| @pirate.parrots.create!(: 
     | 
| 
      
 1136 
     | 
    
         
            +
                2.times { |i| @pirate.parrots.create!(name: "parrots_#{i}") }
         
     | 
| 
       1019 
1137 
     | 
    
         | 
| 
       1020 
     | 
    
         
            -
                @pirate.parrots.each { |parrot| parrot.name =  
     | 
| 
       1021 
     | 
    
         
            -
                 
     | 
| 
      
 1138 
     | 
    
         
            +
                @pirate.parrots.each { |parrot| parrot.name = "" }
         
     | 
| 
      
 1139 
     | 
    
         
            +
                assert_not_predicate @pirate, :valid?
         
     | 
| 
       1022 
1140 
     | 
    
         | 
| 
       1023 
     | 
    
         
            -
                @pirate.parrots.each  
     | 
| 
       1024 
     | 
    
         
            -
             
     | 
| 
       1025 
     | 
    
         
            -
             
     | 
| 
      
 1141 
     | 
    
         
            +
                @pirate.parrots.each { |parrot| parrot.mark_for_destruction }
         
     | 
| 
      
 1142 
     | 
    
         
            +
             
     | 
| 
      
 1143 
     | 
    
         
            +
                assert_not_called(@pirate.parrots.first, :valid?) do
         
     | 
| 
      
 1144 
     | 
    
         
            +
                  assert_not_called(@pirate.parrots.last, :valid?) do
         
     | 
| 
      
 1145 
     | 
    
         
            +
                    @pirate.save!
         
     | 
| 
      
 1146 
     | 
    
         
            +
                  end
         
     | 
| 
       1026 
1147 
     | 
    
         
             
                end
         
     | 
| 
       1027 
1148 
     | 
    
         | 
| 
       1028 
     | 
    
         
            -
                @pirate. 
     | 
| 
       1029 
     | 
    
         
            -
                assert @pirate.reload.parrots.empty?
         
     | 
| 
      
 1149 
     | 
    
         
            +
                assert_empty @pirate.reload.parrots
         
     | 
| 
       1030 
1150 
     | 
    
         
             
              end
         
     | 
| 
       1031 
1151 
     | 
    
         | 
| 
       1032 
1152 
     | 
    
         
             
              def test_should_skip_validation_on_habtm_if_destroyed
         
     | 
| 
       1033 
     | 
    
         
            -
                @pirate.parrots.create!(: 
     | 
| 
      
 1153 
     | 
    
         
            +
                @pirate.parrots.create!(name: "parrots_1")
         
     | 
| 
       1034 
1154 
     | 
    
         | 
| 
       1035 
     | 
    
         
            -
                @pirate.parrots.each { |parrot| parrot.name =  
     | 
| 
       1036 
     | 
    
         
            -
                 
     | 
| 
      
 1155 
     | 
    
         
            +
                @pirate.parrots.each { |parrot| parrot.name = "" }
         
     | 
| 
      
 1156 
     | 
    
         
            +
                assert_not_predicate @pirate, :valid?
         
     | 
| 
       1037 
1157 
     | 
    
         | 
| 
       1038 
1158 
     | 
    
         
             
                @pirate.parrots.each(&:destroy)
         
     | 
| 
       1039 
     | 
    
         
            -
                 
     | 
| 
      
 1159 
     | 
    
         
            +
                assert_predicate @pirate, :valid?
         
     | 
| 
       1040 
1160 
     | 
    
         
             
              end
         
     | 
| 
       1041 
1161 
     | 
    
         | 
| 
       1042 
1162 
     | 
    
         
             
              def test_a_child_marked_for_destruction_should_not_be_destroyed_twice_while_saving_habtm
         
     | 
| 
       1043 
     | 
    
         
            -
                @pirate.parrots.create!(: 
     | 
| 
      
 1163 
     | 
    
         
            +
                @pirate.parrots.create!(name: "parrots_1")
         
     | 
| 
       1044 
1164 
     | 
    
         | 
| 
       1045 
1165 
     | 
    
         
             
                @pirate.parrots.each(&:mark_for_destruction)
         
     | 
| 
       1046 
1166 
     | 
    
         
             
                assert @pirate.save
         
     | 
| 
       1047 
1167 
     | 
    
         | 
| 
       1048 
1168 
     | 
    
         
             
                Pirate.transaction do
         
     | 
| 
       1049 
     | 
    
         
            -
                   
     | 
| 
      
 1169 
     | 
    
         
            +
                  assert_no_queries do
         
     | 
| 
       1050 
1170 
     | 
    
         
             
                    assert @pirate.save
         
     | 
| 
       1051 
1171 
     | 
    
         
             
                  end
         
     | 
| 
       1052 
1172 
     | 
    
         
             
                end
         
     | 
| 
       1053 
1173 
     | 
    
         
             
              end
         
     | 
| 
       1054 
1174 
     | 
    
         | 
| 
       1055 
1175 
     | 
    
         
             
              def test_should_rollback_destructions_if_an_exception_occurred_while_saving_habtm
         
     | 
| 
       1056 
     | 
    
         
            -
                2.times { |i| @pirate.parrots.create!(: 
     | 
| 
      
 1176 
     | 
    
         
            +
                2.times { |i| @pirate.parrots.create!(name: "parrots_#{i}") }
         
     | 
| 
       1057 
1177 
     | 
    
         
             
                before = @pirate.parrots.map { |c| c.mark_for_destruction ; c }
         
     | 
| 
       1058 
1178 
     | 
    
         | 
| 
       1059 
1179 
     | 
    
         
             
                class << @pirate.association(:parrots)
         
     | 
| 
       1060 
1180 
     | 
    
         
             
                  def destroy(*args)
         
     | 
| 
       1061 
1181 
     | 
    
         
             
                    super
         
     | 
| 
       1062 
     | 
    
         
            -
                    raise  
     | 
| 
      
 1182 
     | 
    
         
            +
                    raise "Oh noes!"
         
     | 
| 
       1063 
1183 
     | 
    
         
             
                  end
         
     | 
| 
       1064 
1184 
     | 
    
         
             
                end
         
     | 
| 
       1065 
1185 
     | 
    
         | 
| 
       1066 
     | 
    
         
            -
                assert_raise(RuntimeError) {  
     | 
| 
      
 1186 
     | 
    
         
            +
                assert_raise(RuntimeError) { assert_not @pirate.save }
         
     | 
| 
       1067 
1187 
     | 
    
         
             
                assert_equal before, @pirate.reload.parrots
         
     | 
| 
       1068 
1188 
     | 
    
         
             
              end
         
     | 
| 
       1069 
1189 
     | 
    
         | 
| 
         @@ -1072,8 +1192,8 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase 
     | 
|
| 
       1072 
1192 
     | 
    
         
             
                define_method("test_should_run_add_callback_#{callback_type}s_for_habtm") do
         
     | 
| 
       1073 
1193 
     | 
    
         
             
                  association_name_with_callbacks = "parrots_with_#{callback_type}_callbacks"
         
     | 
| 
       1074 
1194 
     | 
    
         | 
| 
       1075 
     | 
    
         
            -
                  pirate = Pirate.new(: 
     | 
| 
       1076 
     | 
    
         
            -
                  pirate. 
     | 
| 
      
 1195 
     | 
    
         
            +
                  pirate = Pirate.new(catchphrase: "Arr")
         
     | 
| 
      
 1196 
     | 
    
         
            +
                  pirate.public_send(association_name_with_callbacks).build(name: "Crowe the One-Eyed")
         
     | 
| 
       1077 
1197 
     | 
    
         | 
| 
       1078 
1198 
     | 
    
         
             
                  expected = [
         
     | 
| 
       1079 
1199 
     | 
    
         
             
                    "before_adding_#{callback_type}_parrot_<new>",
         
     | 
| 
         @@ -1086,9 +1206,9 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase 
     | 
|
| 
       1086 
1206 
     | 
    
         
             
                define_method("test_should_run_remove_callback_#{callback_type}s_for_habtm") do
         
     | 
| 
       1087 
1207 
     | 
    
         
             
                  association_name_with_callbacks = "parrots_with_#{callback_type}_callbacks"
         
     | 
| 
       1088 
1208 
     | 
    
         | 
| 
       1089 
     | 
    
         
            -
                  @pirate. 
     | 
| 
       1090 
     | 
    
         
            -
                  @pirate. 
     | 
| 
       1091 
     | 
    
         
            -
                  child_id = @pirate. 
     | 
| 
      
 1209 
     | 
    
         
            +
                  @pirate.public_send(association_name_with_callbacks).create!(name: "Crowe the One-Eyed")
         
     | 
| 
      
 1210 
     | 
    
         
            +
                  @pirate.public_send(association_name_with_callbacks).each(&:mark_for_destruction)
         
     | 
| 
      
 1211 
     | 
    
         
            +
                  child_id = @pirate.public_send(association_name_with_callbacks).first.id
         
     | 
| 
       1092 
1212 
     | 
    
         | 
| 
       1093 
1213 
     | 
    
         
             
                  @pirate.ship_log.clear
         
     | 
| 
       1094 
1214 
     | 
    
         
             
                  @pirate.save
         
     | 
| 
         @@ -1108,60 +1228,60 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase 
     | 
|
| 
       1108 
1228 
     | 
    
         | 
| 
       1109 
1229 
     | 
    
         
             
              def setup
         
     | 
| 
       1110 
1230 
     | 
    
         
             
                super
         
     | 
| 
       1111 
     | 
    
         
            -
                @pirate = Pirate.create(: 
     | 
| 
       1112 
     | 
    
         
            -
                @ship = @pirate.create_ship(: 
     | 
| 
      
 1231 
     | 
    
         
            +
                @pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?")
         
     | 
| 
      
 1232 
     | 
    
         
            +
                @ship = @pirate.create_ship(name: "Nights Dirty Lightning")
         
     | 
| 
       1113 
1233 
     | 
    
         
             
              end
         
     | 
| 
       1114 
1234 
     | 
    
         | 
| 
       1115 
1235 
     | 
    
         
             
              def test_should_still_work_without_an_associated_model
         
     | 
| 
       1116 
1236 
     | 
    
         
             
                @ship.destroy
         
     | 
| 
       1117 
1237 
     | 
    
         
             
                @pirate.reload.catchphrase = "Arr"
         
     | 
| 
       1118 
1238 
     | 
    
         
             
                @pirate.save
         
     | 
| 
       1119 
     | 
    
         
            -
                assert_equal  
     | 
| 
      
 1239 
     | 
    
         
            +
                assert_equal "Arr", @pirate.reload.catchphrase
         
     | 
| 
       1120 
1240 
     | 
    
         
             
              end
         
     | 
| 
       1121 
1241 
     | 
    
         | 
| 
       1122 
1242 
     | 
    
         
             
              def test_should_automatically_save_the_associated_model
         
     | 
| 
       1123 
     | 
    
         
            -
                @pirate.ship.name =  
     | 
| 
      
 1243 
     | 
    
         
            +
                @pirate.ship.name = "The Vile Insanity"
         
     | 
| 
       1124 
1244 
     | 
    
         
             
                @pirate.save
         
     | 
| 
       1125 
     | 
    
         
            -
                assert_equal  
     | 
| 
      
 1245 
     | 
    
         
            +
                assert_equal "The Vile Insanity", @pirate.reload.ship.name
         
     | 
| 
       1126 
1246 
     | 
    
         
             
              end
         
     | 
| 
       1127 
1247 
     | 
    
         | 
| 
       1128 
1248 
     | 
    
         
             
              def test_changed_for_autosave_should_handle_cycles
         
     | 
| 
       1129 
1249 
     | 
    
         
             
                @ship.pirate = @pirate
         
     | 
| 
       1130 
     | 
    
         
            -
                 
     | 
| 
      
 1250 
     | 
    
         
            +
                assert_no_queries { @ship.save! }
         
     | 
| 
       1131 
1251 
     | 
    
         | 
| 
       1132 
1252 
     | 
    
         
             
                @parrot = @pirate.parrots.create(name: "some_name")
         
     | 
| 
       1133 
     | 
    
         
            -
                @parrot.name="changed_name"
         
     | 
| 
      
 1253 
     | 
    
         
            +
                @parrot.name = "changed_name"
         
     | 
| 
       1134 
1254 
     | 
    
         
             
                assert_queries(1) { @ship.save! }
         
     | 
| 
       1135 
     | 
    
         
            -
                 
     | 
| 
      
 1255 
     | 
    
         
            +
                assert_no_queries { @ship.save! }
         
     | 
| 
       1136 
1256 
     | 
    
         
             
              end
         
     | 
| 
       1137 
1257 
     | 
    
         | 
| 
       1138 
1258 
     | 
    
         
             
              def test_should_automatically_save_bang_the_associated_model
         
     | 
| 
       1139 
     | 
    
         
            -
                @pirate.ship.name =  
     | 
| 
      
 1259 
     | 
    
         
            +
                @pirate.ship.name = "The Vile Insanity"
         
     | 
| 
       1140 
1260 
     | 
    
         
             
                @pirate.save!
         
     | 
| 
       1141 
     | 
    
         
            -
                assert_equal  
     | 
| 
      
 1261 
     | 
    
         
            +
                assert_equal "The Vile Insanity", @pirate.reload.ship.name
         
     | 
| 
       1142 
1262 
     | 
    
         
             
              end
         
     | 
| 
       1143 
1263 
     | 
    
         | 
| 
       1144 
1264 
     | 
    
         
             
              def test_should_automatically_validate_the_associated_model
         
     | 
| 
       1145 
     | 
    
         
            -
                @pirate.ship.name =  
     | 
| 
       1146 
     | 
    
         
            -
                 
     | 
| 
       1147 
     | 
    
         
            -
                 
     | 
| 
      
 1265 
     | 
    
         
            +
                @pirate.ship.name = ""
         
     | 
| 
      
 1266 
     | 
    
         
            +
                assert_predicate @pirate, :invalid?
         
     | 
| 
      
 1267 
     | 
    
         
            +
                assert_predicate @pirate.errors[:"ship.name"], :any?
         
     | 
| 
       1148 
1268 
     | 
    
         
             
              end
         
     | 
| 
       1149 
1269 
     | 
    
         | 
| 
       1150 
1270 
     | 
    
         
             
              def test_should_merge_errors_on_the_associated_models_onto_the_parent_even_if_it_is_not_valid
         
     | 
| 
       1151 
1271 
     | 
    
         
             
                @pirate.ship.name   = nil
         
     | 
| 
       1152 
1272 
     | 
    
         
             
                @pirate.catchphrase = nil
         
     | 
| 
       1153 
     | 
    
         
            -
                 
     | 
| 
       1154 
     | 
    
         
            -
                 
     | 
| 
       1155 
     | 
    
         
            -
                 
     | 
| 
      
 1273 
     | 
    
         
            +
                assert_predicate @pirate, :invalid?
         
     | 
| 
      
 1274 
     | 
    
         
            +
                assert_predicate @pirate.errors[:"ship.name"], :any?
         
     | 
| 
      
 1275 
     | 
    
         
            +
                assert_predicate @pirate.errors[:catchphrase], :any?
         
     | 
| 
       1156 
1276 
     | 
    
         
             
              end
         
     | 
| 
       1157 
1277 
     | 
    
         | 
| 
       1158 
1278 
     | 
    
         
             
              def test_should_not_ignore_different_error_messages_on_the_same_attribute
         
     | 
| 
       1159 
1279 
     | 
    
         
             
                old_validators = Ship._validators.deep_dup
         
     | 
| 
       1160 
1280 
     | 
    
         
             
                old_callbacks = Ship._validate_callbacks.deep_dup
         
     | 
| 
       1161 
     | 
    
         
            -
                Ship.validates_format_of :name, : 
     | 
| 
      
 1281 
     | 
    
         
            +
                Ship.validates_format_of :name, with: /\w/
         
     | 
| 
       1162 
1282 
     | 
    
         
             
                @pirate.ship.name   = ""
         
     | 
| 
       1163 
1283 
     | 
    
         
             
                @pirate.catchphrase = nil
         
     | 
| 
       1164 
     | 
    
         
            -
                 
     | 
| 
      
 1284 
     | 
    
         
            +
                assert_predicate @pirate, :invalid?
         
     | 
| 
       1165 
1285 
     | 
    
         
             
                assert_equal ["can't be blank", "is invalid"], @pirate.errors[:"ship.name"]
         
     | 
| 
       1166 
1286 
     | 
    
         
             
              ensure
         
     | 
| 
       1167 
1287 
     | 
    
         
             
                Ship._validators = old_validators if old_validators
         
     | 
| 
         @@ -1169,49 +1289,49 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase 
     | 
|
| 
       1169 
1289 
     | 
    
         
             
              end
         
     | 
| 
       1170 
1290 
     | 
    
         | 
| 
       1171 
1291 
     | 
    
         
             
              def test_should_still_allow_to_bypass_validations_on_the_associated_model
         
     | 
| 
       1172 
     | 
    
         
            -
                @pirate.catchphrase =  
     | 
| 
       1173 
     | 
    
         
            -
                @pirate.ship.name =  
     | 
| 
       1174 
     | 
    
         
            -
                @pirate.save(: 
     | 
| 
      
 1292 
     | 
    
         
            +
                @pirate.catchphrase = ""
         
     | 
| 
      
 1293 
     | 
    
         
            +
                @pirate.ship.name = ""
         
     | 
| 
      
 1294 
     | 
    
         
            +
                @pirate.save(validate: false)
         
     | 
| 
       1175 
1295 
     | 
    
         
             
                # Oracle saves empty string as NULL
         
     | 
| 
       1176 
1296 
     | 
    
         
             
                if current_adapter?(:OracleAdapter)
         
     | 
| 
       1177 
1297 
     | 
    
         
             
                  assert_equal [nil, nil], [@pirate.reload.catchphrase, @pirate.ship.name]
         
     | 
| 
       1178 
1298 
     | 
    
         
             
                else
         
     | 
| 
       1179 
     | 
    
         
            -
                  assert_equal [ 
     | 
| 
      
 1299 
     | 
    
         
            +
                  assert_equal ["", ""], [@pirate.reload.catchphrase, @pirate.ship.name]
         
     | 
| 
       1180 
1300 
     | 
    
         
             
                end
         
     | 
| 
       1181 
1301 
     | 
    
         
             
              end
         
     | 
| 
       1182 
1302 
     | 
    
         | 
| 
       1183 
1303 
     | 
    
         
             
              def test_should_allow_to_bypass_validations_on_associated_models_at_any_depth
         
     | 
| 
       1184 
     | 
    
         
            -
                2.times { |i| @pirate.ship.parts.create!(: 
     | 
| 
      
 1304 
     | 
    
         
            +
                2.times { |i| @pirate.ship.parts.create!(name: "part #{i}") }
         
     | 
| 
       1185 
1305 
     | 
    
         | 
| 
       1186 
     | 
    
         
            -
                @pirate.catchphrase =  
     | 
| 
       1187 
     | 
    
         
            -
                @pirate.ship.name =  
     | 
| 
       1188 
     | 
    
         
            -
                @pirate.ship.parts.each { |part| part.name =  
     | 
| 
       1189 
     | 
    
         
            -
                @pirate.save(: 
     | 
| 
      
 1306 
     | 
    
         
            +
                @pirate.catchphrase = ""
         
     | 
| 
      
 1307 
     | 
    
         
            +
                @pirate.ship.name = ""
         
     | 
| 
      
 1308 
     | 
    
         
            +
                @pirate.ship.parts.each { |part| part.name = "" }
         
     | 
| 
      
 1309 
     | 
    
         
            +
                @pirate.save(validate: false)
         
     | 
| 
       1190 
1310 
     | 
    
         | 
| 
       1191 
1311 
     | 
    
         
             
                values = [@pirate.reload.catchphrase, @pirate.ship.name, *@pirate.ship.parts.map(&:name)]
         
     | 
| 
       1192 
1312 
     | 
    
         
             
                # Oracle saves empty string as NULL
         
     | 
| 
       1193 
1313 
     | 
    
         
             
                if current_adapter?(:OracleAdapter)
         
     | 
| 
       1194 
1314 
     | 
    
         
             
                  assert_equal [nil, nil, nil, nil], values
         
     | 
| 
       1195 
1315 
     | 
    
         
             
                else
         
     | 
| 
       1196 
     | 
    
         
            -
                  assert_equal [ 
     | 
| 
      
 1316 
     | 
    
         
            +
                  assert_equal ["", "", "", ""], values
         
     | 
| 
       1197 
1317 
     | 
    
         
             
                end
         
     | 
| 
       1198 
1318 
     | 
    
         
             
              end
         
     | 
| 
       1199 
1319 
     | 
    
         | 
| 
       1200 
1320 
     | 
    
         
             
              def test_should_still_raise_an_ActiveRecordRecord_Invalid_exception_if_we_want_that
         
     | 
| 
       1201 
     | 
    
         
            -
                @pirate.ship.name =  
     | 
| 
      
 1321 
     | 
    
         
            +
                @pirate.ship.name = ""
         
     | 
| 
       1202 
1322 
     | 
    
         
             
                assert_raise(ActiveRecord::RecordInvalid) do
         
     | 
| 
       1203 
1323 
     | 
    
         
             
                  @pirate.save!
         
     | 
| 
       1204 
1324 
     | 
    
         
             
                end
         
     | 
| 
       1205 
1325 
     | 
    
         
             
              end
         
     | 
| 
       1206 
1326 
     | 
    
         | 
| 
       1207 
1327 
     | 
    
         
             
              def test_should_not_save_and_return_false_if_a_callback_cancelled_saving
         
     | 
| 
       1208 
     | 
    
         
            -
                pirate = Pirate.new(: 
     | 
| 
       1209 
     | 
    
         
            -
                ship = pirate.build_ship(: 
     | 
| 
      
 1328 
     | 
    
         
            +
                pirate = Pirate.new(catchphrase: "Arr")
         
     | 
| 
      
 1329 
     | 
    
         
            +
                ship = pirate.build_ship(name: "The Vile Insanity")
         
     | 
| 
       1210 
1330 
     | 
    
         
             
                ship.cancel_save_from_callback = true
         
     | 
| 
       1211 
1331 
     | 
    
         | 
| 
       1212 
     | 
    
         
            -
                assert_no_difference  
     | 
| 
       1213 
     | 
    
         
            -
                  assert_no_difference  
     | 
| 
       1214 
     | 
    
         
            -
                     
     | 
| 
      
 1332 
     | 
    
         
            +
                assert_no_difference "Pirate.count" do
         
     | 
| 
      
 1333 
     | 
    
         
            +
                  assert_no_difference "Ship.count" do
         
     | 
| 
      
 1334 
     | 
    
         
            +
                    assert_not pirate.save
         
     | 
| 
       1215 
1335 
     | 
    
         
             
                  end
         
     | 
| 
       1216 
1336 
     | 
    
         
             
                end
         
     | 
| 
       1217 
1337 
     | 
    
         
             
              end
         
     | 
| 
         @@ -1219,51 +1339,75 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase 
     | 
|
| 
       1219 
1339 
     | 
    
         
             
              def test_should_rollback_any_changes_if_an_exception_occurred_while_saving
         
     | 
| 
       1220 
1340 
     | 
    
         
             
                before = [@pirate.catchphrase, @pirate.ship.name]
         
     | 
| 
       1221 
1341 
     | 
    
         | 
| 
       1222 
     | 
    
         
            -
                @pirate.catchphrase =  
     | 
| 
       1223 
     | 
    
         
            -
                @pirate.ship.name =  
     | 
| 
      
 1342 
     | 
    
         
            +
                @pirate.catchphrase = "Arr"
         
     | 
| 
      
 1343 
     | 
    
         
            +
                @pirate.ship.name = "The Vile Insanity"
         
     | 
| 
       1224 
1344 
     | 
    
         | 
| 
       1225 
1345 
     | 
    
         
             
                # Stub the save method of the @pirate.ship instance to raise an exception
         
     | 
| 
       1226 
1346 
     | 
    
         
             
                class << @pirate.ship
         
     | 
| 
       1227 
     | 
    
         
            -
                  def save( 
     | 
| 
      
 1347 
     | 
    
         
            +
                  def save(**)
         
     | 
| 
       1228 
1348 
     | 
    
         
             
                    super
         
     | 
| 
       1229 
     | 
    
         
            -
                    raise  
     | 
| 
      
 1349 
     | 
    
         
            +
                    raise "Oh noes!"
         
     | 
| 
       1230 
1350 
     | 
    
         
             
                  end
         
     | 
| 
       1231 
1351 
     | 
    
         
             
                end
         
     | 
| 
       1232 
1352 
     | 
    
         | 
| 
       1233 
     | 
    
         
            -
                assert_raise(RuntimeError) {  
     | 
| 
      
 1353 
     | 
    
         
            +
                assert_raise(RuntimeError) { assert_not @pirate.save }
         
     | 
| 
       1234 
1354 
     | 
    
         
             
                assert_equal before, [@pirate.reload.catchphrase, @pirate.ship.name]
         
     | 
| 
       1235 
1355 
     | 
    
         
             
              end
         
     | 
| 
       1236 
1356 
     | 
    
         | 
| 
       1237 
1357 
     | 
    
         
             
              def test_should_not_load_the_associated_model
         
     | 
| 
       1238 
     | 
    
         
            -
                assert_queries(1) { @pirate.catchphrase =  
     | 
| 
      
 1358 
     | 
    
         
            +
                assert_queries(1) { @pirate.catchphrase = "Arr"; @pirate.save! }
         
     | 
| 
       1239 
1359 
     | 
    
         
             
              end
         
     | 
| 
       1240 
1360 
     | 
    
         | 
| 
       1241 
1361 
     | 
    
         
             
              def test_mark_for_destruction_is_ignored_without_autosave_true
         
     | 
| 
       1242 
1362 
     | 
    
         
             
                ship = ShipWithoutNestedAttributes.new(name: "The Black Flag")
         
     | 
| 
       1243 
1363 
     | 
    
         
             
                ship.parts.build.mark_for_destruction
         
     | 
| 
       1244 
1364 
     | 
    
         | 
| 
       1245 
     | 
    
         
            -
                 
     | 
| 
      
 1365 
     | 
    
         
            +
                assert_not_predicate ship, :valid?
         
     | 
| 
       1246 
1366 
     | 
    
         
             
              end
         
     | 
| 
       1247 
1367 
     | 
    
         
             
            end
         
     | 
| 
       1248 
1368 
     | 
    
         | 
| 
       1249 
1369 
     | 
    
         
             
            class TestAutosaveAssociationOnAHasOneThroughAssociation < ActiveRecord::TestCase
         
     | 
| 
       1250 
1370 
     | 
    
         
             
              self.use_transactional_tests = false unless supports_savepoints?
         
     | 
| 
       1251 
1371 
     | 
    
         | 
| 
       1252 
     | 
    
         
            -
              def  
     | 
| 
       1253 
     | 
    
         
            -
                super
         
     | 
| 
      
 1372 
     | 
    
         
            +
              def create_member_with_organization
         
     | 
| 
       1254 
1373 
     | 
    
         
             
                organization = Organization.create
         
     | 
| 
       1255 
     | 
    
         
            -
                 
     | 
| 
       1256 
     | 
    
         
            -
                MemberDetail.create(organization: organization, member:  
     | 
| 
      
 1374 
     | 
    
         
            +
                member = Member.create
         
     | 
| 
      
 1375 
     | 
    
         
            +
                MemberDetail.create(organization: organization, member: member)
         
     | 
| 
      
 1376 
     | 
    
         
            +
             
     | 
| 
      
 1377 
     | 
    
         
            +
                member
         
     | 
| 
       1257 
1378 
     | 
    
         
             
              end
         
     | 
| 
       1258 
1379 
     | 
    
         | 
| 
       1259 
1380 
     | 
    
         
             
              def test_should_not_has_one_through_model
         
     | 
| 
       1260 
     | 
    
         
            -
                 
     | 
| 
       1261 
     | 
    
         
            -
             
     | 
| 
      
 1381 
     | 
    
         
            +
                member = create_member_with_organization
         
     | 
| 
      
 1382 
     | 
    
         
            +
             
     | 
| 
      
 1383 
     | 
    
         
            +
                class << member.organization
         
     | 
| 
      
 1384 
     | 
    
         
            +
                  def save(**)
         
     | 
| 
      
 1385 
     | 
    
         
            +
                    super
         
     | 
| 
      
 1386 
     | 
    
         
            +
                    raise "Oh noes!"
         
     | 
| 
      
 1387 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1388 
     | 
    
         
            +
                end
         
     | 
| 
      
 1389 
     | 
    
         
            +
                assert_nothing_raised { member.save }
         
     | 
| 
      
 1390 
     | 
    
         
            +
              end
         
     | 
| 
      
 1391 
     | 
    
         
            +
             
     | 
| 
      
 1392 
     | 
    
         
            +
              def create_author_with_post_with_comment
         
     | 
| 
      
 1393 
     | 
    
         
            +
                Author.create! name: "David" # make comment_id not match author_id
         
     | 
| 
      
 1394 
     | 
    
         
            +
                author = Author.create! name: "Sergiy"
         
     | 
| 
      
 1395 
     | 
    
         
            +
                post = Post.create! author: author, title: "foo", body: "bar"
         
     | 
| 
      
 1396 
     | 
    
         
            +
                Comment.create! post: post, body: "cool comment"
         
     | 
| 
      
 1397 
     | 
    
         
            +
             
     | 
| 
      
 1398 
     | 
    
         
            +
                author
         
     | 
| 
      
 1399 
     | 
    
         
            +
              end
         
     | 
| 
      
 1400 
     | 
    
         
            +
             
     | 
| 
      
 1401 
     | 
    
         
            +
              def test_should_not_reversed_has_one_through_model
         
     | 
| 
      
 1402 
     | 
    
         
            +
                author = create_author_with_post_with_comment
         
     | 
| 
      
 1403 
     | 
    
         
            +
             
     | 
| 
      
 1404 
     | 
    
         
            +
                class << author.comment_on_first_post
         
     | 
| 
      
 1405 
     | 
    
         
            +
                  def save(**)
         
     | 
| 
       1262 
1406 
     | 
    
         
             
                    super
         
     | 
| 
       1263 
     | 
    
         
            -
                    raise  
     | 
| 
      
 1407 
     | 
    
         
            +
                    raise "Oh noes!"
         
     | 
| 
       1264 
1408 
     | 
    
         
             
                  end
         
     | 
| 
       1265 
1409 
     | 
    
         
             
                end
         
     | 
| 
       1266 
     | 
    
         
            -
                assert_nothing_raised {  
     | 
| 
      
 1410 
     | 
    
         
            +
                assert_nothing_raised { author.save }
         
     | 
| 
       1267 
1411 
     | 
    
         
             
              end
         
     | 
| 
       1268 
1412 
     | 
    
         
             
            end
         
     | 
| 
       1269 
1413 
     | 
    
         | 
| 
         @@ -1272,70 +1416,70 @@ class TestAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase 
     | 
|
| 
       1272 
1416 
     | 
    
         | 
| 
       1273 
1417 
     | 
    
         
             
              def setup
         
     | 
| 
       1274 
1418 
     | 
    
         
             
                super
         
     | 
| 
       1275 
     | 
    
         
            -
                @ship = Ship.create(: 
     | 
| 
       1276 
     | 
    
         
            -
                @pirate = @ship.create_pirate(: 
     | 
| 
      
 1419 
     | 
    
         
            +
                @ship = Ship.create(name: "Nights Dirty Lightning")
         
     | 
| 
      
 1420 
     | 
    
         
            +
                @pirate = @ship.create_pirate(catchphrase: "Don' botharrr talkin' like one, savvy?")
         
     | 
| 
       1277 
1421 
     | 
    
         
             
              end
         
     | 
| 
       1278 
1422 
     | 
    
         | 
| 
       1279 
1423 
     | 
    
         
             
              def test_should_still_work_without_an_associated_model
         
     | 
| 
       1280 
1424 
     | 
    
         
             
                @pirate.destroy
         
     | 
| 
       1281 
1425 
     | 
    
         
             
                @ship.reload.name = "The Vile Insanity"
         
     | 
| 
       1282 
1426 
     | 
    
         
             
                @ship.save
         
     | 
| 
       1283 
     | 
    
         
            -
                assert_equal  
     | 
| 
      
 1427 
     | 
    
         
            +
                assert_equal "The Vile Insanity", @ship.reload.name
         
     | 
| 
       1284 
1428 
     | 
    
         
             
              end
         
     | 
| 
       1285 
1429 
     | 
    
         | 
| 
       1286 
1430 
     | 
    
         
             
              def test_should_automatically_save_the_associated_model
         
     | 
| 
       1287 
     | 
    
         
            -
                @ship.pirate.catchphrase =  
     | 
| 
      
 1431 
     | 
    
         
            +
                @ship.pirate.catchphrase = "Arr"
         
     | 
| 
       1288 
1432 
     | 
    
         
             
                @ship.save
         
     | 
| 
       1289 
     | 
    
         
            -
                assert_equal  
     | 
| 
      
 1433 
     | 
    
         
            +
                assert_equal "Arr", @ship.reload.pirate.catchphrase
         
     | 
| 
       1290 
1434 
     | 
    
         
             
              end
         
     | 
| 
       1291 
1435 
     | 
    
         | 
| 
       1292 
1436 
     | 
    
         
             
              def test_should_automatically_save_bang_the_associated_model
         
     | 
| 
       1293 
     | 
    
         
            -
                @ship.pirate.catchphrase =  
     | 
| 
      
 1437 
     | 
    
         
            +
                @ship.pirate.catchphrase = "Arr"
         
     | 
| 
       1294 
1438 
     | 
    
         
             
                @ship.save!
         
     | 
| 
       1295 
     | 
    
         
            -
                assert_equal  
     | 
| 
      
 1439 
     | 
    
         
            +
                assert_equal "Arr", @ship.reload.pirate.catchphrase
         
     | 
| 
       1296 
1440 
     | 
    
         
             
              end
         
     | 
| 
       1297 
1441 
     | 
    
         | 
| 
       1298 
1442 
     | 
    
         
             
              def test_should_automatically_validate_the_associated_model
         
     | 
| 
       1299 
     | 
    
         
            -
                @ship.pirate.catchphrase =  
     | 
| 
       1300 
     | 
    
         
            -
                 
     | 
| 
       1301 
     | 
    
         
            -
                 
     | 
| 
      
 1443 
     | 
    
         
            +
                @ship.pirate.catchphrase = ""
         
     | 
| 
      
 1444 
     | 
    
         
            +
                assert_predicate @ship, :invalid?
         
     | 
| 
      
 1445 
     | 
    
         
            +
                assert_predicate @ship.errors[:"pirate.catchphrase"], :any?
         
     | 
| 
       1302 
1446 
     | 
    
         
             
              end
         
     | 
| 
       1303 
1447 
     | 
    
         | 
| 
       1304 
1448 
     | 
    
         
             
              def test_should_merge_errors_on_the_associated_model_onto_the_parent_even_if_it_is_not_valid
         
     | 
| 
       1305 
1449 
     | 
    
         
             
                @ship.name = nil
         
     | 
| 
       1306 
1450 
     | 
    
         
             
                @ship.pirate.catchphrase = nil
         
     | 
| 
       1307 
     | 
    
         
            -
                 
     | 
| 
       1308 
     | 
    
         
            -
                 
     | 
| 
       1309 
     | 
    
         
            -
                 
     | 
| 
      
 1451 
     | 
    
         
            +
                assert_predicate @ship, :invalid?
         
     | 
| 
      
 1452 
     | 
    
         
            +
                assert_predicate @ship.errors[:name], :any?
         
     | 
| 
      
 1453 
     | 
    
         
            +
                assert_predicate @ship.errors[:"pirate.catchphrase"], :any?
         
     | 
| 
       1310 
1454 
     | 
    
         
             
              end
         
     | 
| 
       1311 
1455 
     | 
    
         | 
| 
       1312 
1456 
     | 
    
         
             
              def test_should_still_allow_to_bypass_validations_on_the_associated_model
         
     | 
| 
       1313 
     | 
    
         
            -
                @ship.pirate.catchphrase =  
     | 
| 
       1314 
     | 
    
         
            -
                @ship.name =  
     | 
| 
       1315 
     | 
    
         
            -
                @ship.save(: 
     | 
| 
      
 1457 
     | 
    
         
            +
                @ship.pirate.catchphrase = ""
         
     | 
| 
      
 1458 
     | 
    
         
            +
                @ship.name = ""
         
     | 
| 
      
 1459 
     | 
    
         
            +
                @ship.save(validate: false)
         
     | 
| 
       1316 
1460 
     | 
    
         
             
                # Oracle saves empty string as NULL
         
     | 
| 
       1317 
1461 
     | 
    
         
             
                if current_adapter?(:OracleAdapter)
         
     | 
| 
       1318 
1462 
     | 
    
         
             
                  assert_equal [nil, nil], [@ship.reload.name, @ship.pirate.catchphrase]
         
     | 
| 
       1319 
1463 
     | 
    
         
             
                else
         
     | 
| 
       1320 
     | 
    
         
            -
                  assert_equal [ 
     | 
| 
      
 1464 
     | 
    
         
            +
                  assert_equal ["", ""], [@ship.reload.name, @ship.pirate.catchphrase]
         
     | 
| 
       1321 
1465 
     | 
    
         
             
                end
         
     | 
| 
       1322 
1466 
     | 
    
         
             
              end
         
     | 
| 
       1323 
1467 
     | 
    
         | 
| 
       1324 
1468 
     | 
    
         
             
              def test_should_still_raise_an_ActiveRecordRecord_Invalid_exception_if_we_want_that
         
     | 
| 
       1325 
     | 
    
         
            -
                @ship.pirate.catchphrase =  
     | 
| 
      
 1469 
     | 
    
         
            +
                @ship.pirate.catchphrase = ""
         
     | 
| 
       1326 
1470 
     | 
    
         
             
                assert_raise(ActiveRecord::RecordInvalid) do
         
     | 
| 
       1327 
1471 
     | 
    
         
             
                  @ship.save!
         
     | 
| 
       1328 
1472 
     | 
    
         
             
                end
         
     | 
| 
       1329 
1473 
     | 
    
         
             
              end
         
     | 
| 
       1330 
1474 
     | 
    
         | 
| 
       1331 
1475 
     | 
    
         
             
              def test_should_not_save_and_return_false_if_a_callback_cancelled_saving
         
     | 
| 
       1332 
     | 
    
         
            -
                ship = Ship.new(: 
     | 
| 
       1333 
     | 
    
         
            -
                pirate = ship.build_pirate(: 
     | 
| 
      
 1476 
     | 
    
         
            +
                ship = Ship.new(name: "The Vile Insanity")
         
     | 
| 
      
 1477 
     | 
    
         
            +
                pirate = ship.build_pirate(catchphrase: "Arr")
         
     | 
| 
       1334 
1478 
     | 
    
         
             
                pirate.cancel_save_from_callback = true
         
     | 
| 
       1335 
1479 
     | 
    
         | 
| 
       1336 
     | 
    
         
            -
                assert_no_difference  
     | 
| 
       1337 
     | 
    
         
            -
                  assert_no_difference  
     | 
| 
       1338 
     | 
    
         
            -
                     
     | 
| 
      
 1480 
     | 
    
         
            +
                assert_no_difference "Ship.count" do
         
     | 
| 
      
 1481 
     | 
    
         
            +
                  assert_no_difference "Pirate.count" do
         
     | 
| 
      
 1482 
     | 
    
         
            +
                    assert_not ship.save
         
     | 
| 
       1339 
1483 
     | 
    
         
             
                  end
         
     | 
| 
       1340 
1484 
     | 
    
         
             
                end
         
     | 
| 
       1341 
1485 
     | 
    
         
             
              end
         
     | 
| 
         @@ -1343,41 +1487,41 @@ class TestAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase 
     | 
|
| 
       1343 
1487 
     | 
    
         
             
              def test_should_rollback_any_changes_if_an_exception_occurred_while_saving
         
     | 
| 
       1344 
1488 
     | 
    
         
             
                before = [@ship.pirate.catchphrase, @ship.name]
         
     | 
| 
       1345 
1489 
     | 
    
         | 
| 
       1346 
     | 
    
         
            -
                @ship.pirate.catchphrase =  
     | 
| 
       1347 
     | 
    
         
            -
                @ship.name =  
     | 
| 
      
 1490 
     | 
    
         
            +
                @ship.pirate.catchphrase = "Arr"
         
     | 
| 
      
 1491 
     | 
    
         
            +
                @ship.name = "The Vile Insanity"
         
     | 
| 
       1348 
1492 
     | 
    
         | 
| 
       1349 
1493 
     | 
    
         
             
                # Stub the save method of the @ship.pirate instance to raise an exception
         
     | 
| 
       1350 
1494 
     | 
    
         
             
                class << @ship.pirate
         
     | 
| 
       1351 
     | 
    
         
            -
                  def save( 
     | 
| 
      
 1495 
     | 
    
         
            +
                  def save(**)
         
     | 
| 
       1352 
1496 
     | 
    
         
             
                    super
         
     | 
| 
       1353 
     | 
    
         
            -
                    raise  
     | 
| 
      
 1497 
     | 
    
         
            +
                    raise "Oh noes!"
         
     | 
| 
       1354 
1498 
     | 
    
         
             
                  end
         
     | 
| 
       1355 
1499 
     | 
    
         
             
                end
         
     | 
| 
       1356 
1500 
     | 
    
         | 
| 
       1357 
     | 
    
         
            -
                assert_raise(RuntimeError) {  
     | 
| 
      
 1501 
     | 
    
         
            +
                assert_raise(RuntimeError) { assert_not @ship.save }
         
     | 
| 
       1358 
1502 
     | 
    
         
             
                assert_equal before, [@ship.pirate.reload.catchphrase, @ship.reload.name]
         
     | 
| 
       1359 
1503 
     | 
    
         
             
              end
         
     | 
| 
       1360 
1504 
     | 
    
         | 
| 
       1361 
1505 
     | 
    
         
             
              def test_should_not_load_the_associated_model
         
     | 
| 
       1362 
     | 
    
         
            -
                assert_queries(1) { @ship.name =  
     | 
| 
      
 1506 
     | 
    
         
            +
                assert_queries(1) { @ship.name = "The Vile Insanity"; @ship.save! }
         
     | 
| 
       1363 
1507 
     | 
    
         
             
              end
         
     | 
| 
       1364 
1508 
     | 
    
         
             
            end
         
     | 
| 
       1365 
1509 
     | 
    
         | 
| 
       1366 
1510 
     | 
    
         
             
            module AutosaveAssociationOnACollectionAssociationTests
         
     | 
| 
       1367 
1511 
     | 
    
         
             
              def test_should_automatically_save_the_associated_models
         
     | 
| 
       1368 
     | 
    
         
            -
                new_names = [ 
     | 
| 
       1369 
     | 
    
         
            -
                @pirate. 
     | 
| 
      
 1512 
     | 
    
         
            +
                new_names = ["Grace OMalley", "Privateers Greed"]
         
     | 
| 
      
 1513 
     | 
    
         
            +
                @pirate.public_send(@association_name).each_with_index { |child, i| child.name = new_names[i] }
         
     | 
| 
       1370 
1514 
     | 
    
         | 
| 
       1371 
1515 
     | 
    
         
             
                @pirate.save
         
     | 
| 
       1372 
     | 
    
         
            -
                assert_equal new_names, @pirate.reload. 
     | 
| 
      
 1516 
     | 
    
         
            +
                assert_equal new_names.sort, @pirate.reload.public_send(@association_name).map(&:name).sort
         
     | 
| 
       1373 
1517 
     | 
    
         
             
              end
         
     | 
| 
       1374 
1518 
     | 
    
         | 
| 
       1375 
1519 
     | 
    
         
             
              def test_should_automatically_save_bang_the_associated_models
         
     | 
| 
       1376 
     | 
    
         
            -
                new_names = [ 
     | 
| 
       1377 
     | 
    
         
            -
                @pirate. 
     | 
| 
      
 1520 
     | 
    
         
            +
                new_names = ["Grace OMalley", "Privateers Greed"]
         
     | 
| 
      
 1521 
     | 
    
         
            +
                @pirate.public_send(@association_name).each_with_index { |child, i| child.name = new_names[i] }
         
     | 
| 
       1378 
1522 
     | 
    
         | 
| 
       1379 
1523 
     | 
    
         
             
                @pirate.save!
         
     | 
| 
       1380 
     | 
    
         
            -
                assert_equal new_names, @pirate.reload. 
     | 
| 
      
 1524 
     | 
    
         
            +
                assert_equal new_names.sort, @pirate.reload.public_send(@association_name).map(&:name).sort
         
     | 
| 
       1381 
1525 
     | 
    
         
             
              end
         
     | 
| 
       1382 
1526 
     | 
    
         | 
| 
       1383 
1527 
     | 
    
         
             
              def test_should_update_children_when_autosave_is_true_and_parent_is_new_but_child_is_not
         
     | 
| 
         @@ -1399,135 +1543,135 @@ module AutosaveAssociationOnACollectionAssociationTests 
     | 
|
| 
       1399 
1543 
     | 
    
         
             
              end
         
     | 
| 
       1400 
1544 
     | 
    
         | 
| 
       1401 
1545 
     | 
    
         
             
              def test_should_automatically_validate_the_associated_models
         
     | 
| 
       1402 
     | 
    
         
            -
                @pirate. 
     | 
| 
      
 1546 
     | 
    
         
            +
                @pirate.public_send(@association_name).each { |child| child.name = "" }
         
     | 
| 
       1403 
1547 
     | 
    
         | 
| 
       1404 
     | 
    
         
            -
                 
     | 
| 
      
 1548 
     | 
    
         
            +
                assert_not_predicate @pirate, :valid?
         
     | 
| 
       1405 
1549 
     | 
    
         
             
                assert_equal ["can't be blank"], @pirate.errors["#{@association_name}.name"]
         
     | 
| 
       1406 
     | 
    
         
            -
                 
     | 
| 
      
 1550 
     | 
    
         
            +
                assert_empty @pirate.errors[@association_name]
         
     | 
| 
       1407 
1551 
     | 
    
         
             
              end
         
     | 
| 
       1408 
1552 
     | 
    
         | 
| 
       1409 
1553 
     | 
    
         
             
              def test_should_not_use_default_invalid_error_on_associated_models
         
     | 
| 
       1410 
     | 
    
         
            -
                @pirate. 
     | 
| 
      
 1554 
     | 
    
         
            +
                @pirate.public_send(@association_name).build(name: "")
         
     | 
| 
       1411 
1555 
     | 
    
         | 
| 
       1412 
     | 
    
         
            -
                 
     | 
| 
      
 1556 
     | 
    
         
            +
                assert_not_predicate @pirate, :valid?
         
     | 
| 
       1413 
1557 
     | 
    
         
             
                assert_equal ["can't be blank"], @pirate.errors["#{@association_name}.name"]
         
     | 
| 
       1414 
     | 
    
         
            -
                 
     | 
| 
      
 1558 
     | 
    
         
            +
                assert_empty @pirate.errors[@association_name]
         
     | 
| 
       1415 
1559 
     | 
    
         
             
              end
         
     | 
| 
       1416 
1560 
     | 
    
         | 
| 
       1417 
1561 
     | 
    
         
             
              def test_should_default_invalid_error_from_i18n
         
     | 
| 
       1418 
     | 
    
         
            -
                I18n.backend.store_translations(:en, activerecord: {errors: { models:
         
     | 
| 
      
 1562 
     | 
    
         
            +
                I18n.backend.store_translations(:en, activerecord: { errors: { models:
         
     | 
| 
       1419 
1563 
     | 
    
         
             
                  { @associated_model_name.to_s.to_sym => { blank: "cannot be blank" } }
         
     | 
| 
       1420 
     | 
    
         
            -
                }})
         
     | 
| 
      
 1564 
     | 
    
         
            +
                } })
         
     | 
| 
       1421 
1565 
     | 
    
         | 
| 
       1422 
     | 
    
         
            -
                @pirate. 
     | 
| 
      
 1566 
     | 
    
         
            +
                @pirate.public_send(@association_name).build(name: "")
         
     | 
| 
       1423 
1567 
     | 
    
         | 
| 
       1424 
     | 
    
         
            -
                 
     | 
| 
      
 1568 
     | 
    
         
            +
                assert_not_predicate @pirate, :valid?
         
     | 
| 
       1425 
1569 
     | 
    
         
             
                assert_equal ["cannot be blank"], @pirate.errors["#{@association_name}.name"]
         
     | 
| 
       1426 
1570 
     | 
    
         
             
                assert_equal ["#{@association_name.to_s.humanize} name cannot be blank"], @pirate.errors.full_messages
         
     | 
| 
       1427 
     | 
    
         
            -
                 
     | 
| 
      
 1571 
     | 
    
         
            +
                assert_empty @pirate.errors[@association_name]
         
     | 
| 
       1428 
1572 
     | 
    
         
             
              ensure
         
     | 
| 
       1429 
1573 
     | 
    
         
             
                I18n.backend = I18n::Backend::Simple.new
         
     | 
| 
       1430 
1574 
     | 
    
         
             
              end
         
     | 
| 
       1431 
1575 
     | 
    
         | 
| 
       1432 
1576 
     | 
    
         
             
              def test_should_merge_errors_on_the_associated_models_onto_the_parent_even_if_it_is_not_valid
         
     | 
| 
       1433 
     | 
    
         
            -
                @pirate. 
     | 
| 
      
 1577 
     | 
    
         
            +
                @pirate.public_send(@association_name).each { |child| child.name = "" }
         
     | 
| 
       1434 
1578 
     | 
    
         
             
                @pirate.catchphrase = nil
         
     | 
| 
       1435 
1579 
     | 
    
         | 
| 
       1436 
     | 
    
         
            -
                 
     | 
| 
      
 1580 
     | 
    
         
            +
                assert_not_predicate @pirate, :valid?
         
     | 
| 
       1437 
1581 
     | 
    
         
             
                assert_equal ["can't be blank"], @pirate.errors["#{@association_name}.name"]
         
     | 
| 
       1438 
     | 
    
         
            -
                 
     | 
| 
      
 1582 
     | 
    
         
            +
                assert_predicate @pirate.errors[:catchphrase], :any?
         
     | 
| 
       1439 
1583 
     | 
    
         
             
              end
         
     | 
| 
       1440 
1584 
     | 
    
         | 
| 
       1441 
1585 
     | 
    
         
             
              def test_should_allow_to_bypass_validations_on_the_associated_models_on_update
         
     | 
| 
       1442 
     | 
    
         
            -
                @pirate.catchphrase =  
     | 
| 
       1443 
     | 
    
         
            -
                @pirate. 
     | 
| 
      
 1586 
     | 
    
         
            +
                @pirate.catchphrase = ""
         
     | 
| 
      
 1587 
     | 
    
         
            +
                @pirate.public_send(@association_name).each { |child| child.name = "" }
         
     | 
| 
       1444 
1588 
     | 
    
         | 
| 
       1445 
     | 
    
         
            -
                assert @pirate.save(: 
     | 
| 
      
 1589 
     | 
    
         
            +
                assert @pirate.save(validate: false)
         
     | 
| 
       1446 
1590 
     | 
    
         
             
                # Oracle saves empty string as NULL
         
     | 
| 
       1447 
1591 
     | 
    
         
             
                if current_adapter?(:OracleAdapter)
         
     | 
| 
       1448 
1592 
     | 
    
         
             
                  assert_equal [nil, nil, nil], [
         
     | 
| 
       1449 
1593 
     | 
    
         
             
                    @pirate.reload.catchphrase,
         
     | 
| 
       1450 
     | 
    
         
            -
                    @pirate. 
     | 
| 
       1451 
     | 
    
         
            -
                    @pirate. 
     | 
| 
      
 1594 
     | 
    
         
            +
                    @pirate.public_send(@association_name).first.name,
         
     | 
| 
      
 1595 
     | 
    
         
            +
                    @pirate.public_send(@association_name).last.name
         
     | 
| 
       1452 
1596 
     | 
    
         
             
                  ]
         
     | 
| 
       1453 
1597 
     | 
    
         
             
                else
         
     | 
| 
       1454 
     | 
    
         
            -
                  assert_equal [ 
     | 
| 
      
 1598 
     | 
    
         
            +
                  assert_equal ["", "", ""], [
         
     | 
| 
       1455 
1599 
     | 
    
         
             
                    @pirate.reload.catchphrase,
         
     | 
| 
       1456 
     | 
    
         
            -
                    @pirate. 
     | 
| 
       1457 
     | 
    
         
            -
                    @pirate. 
     | 
| 
      
 1600 
     | 
    
         
            +
                    @pirate.public_send(@association_name).first.name,
         
     | 
| 
      
 1601 
     | 
    
         
            +
                    @pirate.public_send(@association_name).last.name
         
     | 
| 
       1458 
1602 
     | 
    
         
             
                  ]
         
     | 
| 
       1459 
1603 
     | 
    
         
             
                end
         
     | 
| 
       1460 
1604 
     | 
    
         
             
              end
         
     | 
| 
       1461 
1605 
     | 
    
         | 
| 
       1462 
1606 
     | 
    
         
             
              def test_should_validation_the_associated_models_on_create
         
     | 
| 
       1463 
1607 
     | 
    
         
             
                assert_no_difference("#{ @association_name == :birds ? 'Bird' : 'Parrot' }.count") do
         
     | 
| 
       1464 
     | 
    
         
            -
                  2.times { @pirate. 
     | 
| 
      
 1608 
     | 
    
         
            +
                  2.times { @pirate.public_send(@association_name).build }
         
     | 
| 
       1465 
1609 
     | 
    
         
             
                  @pirate.save
         
     | 
| 
       1466 
1610 
     | 
    
         
             
                end
         
     | 
| 
       1467 
1611 
     | 
    
         
             
              end
         
     | 
| 
       1468 
1612 
     | 
    
         | 
| 
       1469 
1613 
     | 
    
         
             
              def test_should_allow_to_bypass_validations_on_the_associated_models_on_create
         
     | 
| 
       1470 
1614 
     | 
    
         
             
                assert_difference("#{ @association_name == :birds ? 'Bird' : 'Parrot' }.count", 2) do
         
     | 
| 
       1471 
     | 
    
         
            -
                  2.times { @pirate. 
     | 
| 
       1472 
     | 
    
         
            -
                  @pirate.save(: 
     | 
| 
      
 1615 
     | 
    
         
            +
                  2.times { @pirate.public_send(@association_name).build }
         
     | 
| 
      
 1616 
     | 
    
         
            +
                  @pirate.save(validate: false)
         
     | 
| 
       1473 
1617 
     | 
    
         
             
                end
         
     | 
| 
       1474 
1618 
     | 
    
         
             
              end
         
     | 
| 
       1475 
1619 
     | 
    
         | 
| 
       1476 
1620 
     | 
    
         
             
              def test_should_not_save_and_return_false_if_a_callback_cancelled_saving_in_either_create_or_update
         
     | 
| 
       1477 
     | 
    
         
            -
                @pirate.catchphrase =  
     | 
| 
       1478 
     | 
    
         
            -
                @child_1.name =  
     | 
| 
      
 1621 
     | 
    
         
            +
                @pirate.catchphrase = "Changed"
         
     | 
| 
      
 1622 
     | 
    
         
            +
                @child_1.name = "Changed"
         
     | 
| 
       1479 
1623 
     | 
    
         
             
                @child_1.cancel_save_from_callback = true
         
     | 
| 
       1480 
1624 
     | 
    
         | 
| 
       1481 
     | 
    
         
            -
                 
     | 
| 
      
 1625 
     | 
    
         
            +
                assert_not @pirate.save
         
     | 
| 
       1482 
1626 
     | 
    
         
             
                assert_equal "Don' botharrr talkin' like one, savvy?", @pirate.reload.catchphrase
         
     | 
| 
       1483 
1627 
     | 
    
         
             
                assert_equal "Posideons Killer", @child_1.reload.name
         
     | 
| 
       1484 
1628 
     | 
    
         | 
| 
       1485 
     | 
    
         
            -
                new_pirate = Pirate.new(: 
     | 
| 
       1486 
     | 
    
         
            -
                new_child = new_pirate. 
     | 
| 
      
 1629 
     | 
    
         
            +
                new_pirate = Pirate.new(catchphrase: "Arr")
         
     | 
| 
      
 1630 
     | 
    
         
            +
                new_child = new_pirate.public_send(@association_name).build(name: "Grace OMalley")
         
     | 
| 
       1487 
1631 
     | 
    
         
             
                new_child.cancel_save_from_callback = true
         
     | 
| 
       1488 
1632 
     | 
    
         | 
| 
       1489 
     | 
    
         
            -
                assert_no_difference  
     | 
| 
      
 1633 
     | 
    
         
            +
                assert_no_difference "Pirate.count" do
         
     | 
| 
       1490 
1634 
     | 
    
         
             
                  assert_no_difference "#{new_child.class.name}.count" do
         
     | 
| 
       1491 
     | 
    
         
            -
                     
     | 
| 
      
 1635 
     | 
    
         
            +
                    assert_not new_pirate.save
         
     | 
| 
       1492 
1636 
     | 
    
         
             
                  end
         
     | 
| 
       1493 
1637 
     | 
    
         
             
                end
         
     | 
| 
       1494 
1638 
     | 
    
         
             
              end
         
     | 
| 
       1495 
1639 
     | 
    
         | 
| 
       1496 
1640 
     | 
    
         
             
              def test_should_rollback_any_changes_if_an_exception_occurred_while_saving
         
     | 
| 
       1497 
     | 
    
         
            -
                before = [@pirate.catchphrase, *@pirate. 
     | 
| 
       1498 
     | 
    
         
            -
                new_names = [ 
     | 
| 
      
 1641 
     | 
    
         
            +
                before = [@pirate.catchphrase, *@pirate.public_send(@association_name).map(&:name)]
         
     | 
| 
      
 1642 
     | 
    
         
            +
                new_names = ["Grace OMalley", "Privateers Greed"]
         
     | 
| 
       1499 
1643 
     | 
    
         | 
| 
       1500 
     | 
    
         
            -
                @pirate.catchphrase =  
     | 
| 
       1501 
     | 
    
         
            -
                @pirate. 
     | 
| 
      
 1644 
     | 
    
         
            +
                @pirate.catchphrase = "Arr"
         
     | 
| 
      
 1645 
     | 
    
         
            +
                @pirate.public_send(@association_name).each_with_index { |child, i| child.name = new_names[i] }
         
     | 
| 
       1502 
1646 
     | 
    
         | 
| 
       1503 
1647 
     | 
    
         
             
                # Stub the save method of the first child instance to raise an exception
         
     | 
| 
       1504 
     | 
    
         
            -
                class << @pirate. 
     | 
| 
       1505 
     | 
    
         
            -
                  def save( 
     | 
| 
      
 1648 
     | 
    
         
            +
                class << @pirate.public_send(@association_name).first
         
     | 
| 
      
 1649 
     | 
    
         
            +
                  def save(**)
         
     | 
| 
       1506 
1650 
     | 
    
         
             
                    super
         
     | 
| 
       1507 
     | 
    
         
            -
                    raise  
     | 
| 
      
 1651 
     | 
    
         
            +
                    raise "Oh noes!"
         
     | 
| 
       1508 
1652 
     | 
    
         
             
                  end
         
     | 
| 
       1509 
1653 
     | 
    
         
             
                end
         
     | 
| 
       1510 
1654 
     | 
    
         | 
| 
       1511 
     | 
    
         
            -
                assert_raise(RuntimeError) {  
     | 
| 
      
 1655 
     | 
    
         
            +
                assert_raise(RuntimeError) { assert_not @pirate.save }
         
     | 
| 
       1512 
1656 
     | 
    
         
             
                assert_equal before, [@pirate.reload.catchphrase, *@pirate.send(@association_name).map(&:name)]
         
     | 
| 
       1513 
1657 
     | 
    
         
             
              end
         
     | 
| 
       1514 
1658 
     | 
    
         | 
| 
       1515 
1659 
     | 
    
         
             
              def test_should_still_raise_an_ActiveRecordRecord_Invalid_exception_if_we_want_that
         
     | 
| 
       1516 
     | 
    
         
            -
                @pirate. 
     | 
| 
      
 1660 
     | 
    
         
            +
                @pirate.public_send(@association_name).each { |child| child.name = "" }
         
     | 
| 
       1517 
1661 
     | 
    
         
             
                assert_raise(ActiveRecord::RecordInvalid) do
         
     | 
| 
       1518 
1662 
     | 
    
         
             
                  @pirate.save!
         
     | 
| 
       1519 
1663 
     | 
    
         
             
                end
         
     | 
| 
       1520 
1664 
     | 
    
         
             
              end
         
     | 
| 
       1521 
1665 
     | 
    
         | 
| 
       1522 
1666 
     | 
    
         
             
              def test_should_not_load_the_associated_models_if_they_were_not_loaded_yet
         
     | 
| 
       1523 
     | 
    
         
            -
                assert_queries(1) { @pirate.catchphrase =  
     | 
| 
      
 1667 
     | 
    
         
            +
                assert_queries(1) { @pirate.catchphrase = "Arr"; @pirate.save! }
         
     | 
| 
       1524 
1668 
     | 
    
         | 
| 
       1525 
     | 
    
         
            -
                @pirate. 
     | 
| 
      
 1669 
     | 
    
         
            +
                @pirate.public_send(@association_name).load_target
         
     | 
| 
       1526 
1670 
     | 
    
         | 
| 
       1527 
1671 
     | 
    
         
             
                assert_queries(3) do
         
     | 
| 
       1528 
     | 
    
         
            -
                  @pirate.catchphrase =  
     | 
| 
       1529 
     | 
    
         
            -
                  new_names = [ 
     | 
| 
       1530 
     | 
    
         
            -
                  @pirate. 
     | 
| 
      
 1672 
     | 
    
         
            +
                  @pirate.catchphrase = "Yarr"
         
     | 
| 
      
 1673 
     | 
    
         
            +
                  new_names = ["Grace OMalley", "Privateers Greed"]
         
     | 
| 
      
 1674 
     | 
    
         
            +
                  @pirate.public_send(@association_name).each_with_index { |child, i| child.name = new_names[i] }
         
     | 
| 
       1531 
1675 
     | 
    
         
             
                  @pirate.save!
         
     | 
| 
       1532 
1676 
     | 
    
         
             
                end
         
     | 
| 
       1533 
1677 
     | 
    
         
             
              end
         
     | 
| 
         @@ -1541,9 +1685,9 @@ class TestAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCase 
     | 
|
| 
       1541 
1685 
     | 
    
         
             
                @association_name = :birds
         
     | 
| 
       1542 
1686 
     | 
    
         
             
                @associated_model_name = :bird
         
     | 
| 
       1543 
1687 
     | 
    
         | 
| 
       1544 
     | 
    
         
            -
                @pirate = Pirate.create(: 
     | 
| 
       1545 
     | 
    
         
            -
                @child_1 = @pirate.birds.create(: 
     | 
| 
       1546 
     | 
    
         
            -
                @child_2 = @pirate.birds.create(: 
     | 
| 
      
 1688 
     | 
    
         
            +
                @pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?")
         
     | 
| 
      
 1689 
     | 
    
         
            +
                @child_1 = @pirate.birds.create(name: "Posideons Killer")
         
     | 
| 
      
 1690 
     | 
    
         
            +
                @child_2 = @pirate.birds.create(name: "Killer bandita Dionne")
         
     | 
| 
       1547 
1691 
     | 
    
         
             
              end
         
     | 
| 
       1548 
1692 
     | 
    
         | 
| 
       1549 
1693 
     | 
    
         
             
              include AutosaveAssociationOnACollectionAssociationTests
         
     | 
| 
         @@ -1559,8 +1703,8 @@ class TestAutosaveAssociationOnAHasAndBelongsToManyAssociation < ActiveRecord::T 
     | 
|
| 
       1559 
1703 
     | 
    
         
             
                @habtm = true
         
     | 
| 
       1560 
1704 
     | 
    
         | 
| 
       1561 
1705 
     | 
    
         
             
                @pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?")
         
     | 
| 
       1562 
     | 
    
         
            -
                @child_1 = @pirate.parrots.create(name:  
     | 
| 
       1563 
     | 
    
         
            -
                @child_2 = @pirate.parrots.create(name:  
     | 
| 
      
 1706 
     | 
    
         
            +
                @child_1 = @pirate.parrots.create(name: "Posideons Killer")
         
     | 
| 
      
 1707 
     | 
    
         
            +
                @child_2 = @pirate.parrots.create(name: "Killer bandita Dionne")
         
     | 
| 
       1564 
1708 
     | 
    
         
             
              end
         
     | 
| 
       1565 
1709 
     | 
    
         | 
| 
       1566 
1710 
     | 
    
         
             
              include AutosaveAssociationOnACollectionAssociationTests
         
     | 
| 
         @@ -1576,8 +1720,8 @@ class TestAutosaveAssociationOnAHasAndBelongsToManyAssociationWithAcceptsNestedA 
     | 
|
| 
       1576 
1720 
     | 
    
         
             
                @habtm = true
         
     | 
| 
       1577 
1721 
     | 
    
         | 
| 
       1578 
1722 
     | 
    
         
             
                @pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?")
         
     | 
| 
       1579 
     | 
    
         
            -
                @child_1 = @pirate.parrots.create(name:  
     | 
| 
       1580 
     | 
    
         
            -
                @child_2 = @pirate.parrots.create(name:  
     | 
| 
      
 1723 
     | 
    
         
            +
                @child_1 = @pirate.parrots.create(name: "Posideons Killer")
         
     | 
| 
      
 1724 
     | 
    
         
            +
                @child_2 = @pirate.parrots.create(name: "Killer bandita Dionne")
         
     | 
| 
       1581 
1725 
     | 
    
         
             
              end
         
     | 
| 
       1582 
1726 
     | 
    
         | 
| 
       1583 
1727 
     | 
    
         
             
              include AutosaveAssociationOnACollectionAssociationTests
         
     | 
| 
         @@ -1588,15 +1732,63 @@ class TestAutosaveAssociationValidationsOnAHasManyAssociation < ActiveRecord::Te 
     | 
|
| 
       1588 
1732 
     | 
    
         | 
| 
       1589 
1733 
     | 
    
         
             
              def setup
         
     | 
| 
       1590 
1734 
     | 
    
         
             
                super
         
     | 
| 
       1591 
     | 
    
         
            -
                @pirate = Pirate.create(: 
     | 
| 
       1592 
     | 
    
         
            -
                @pirate.birds.create(: 
     | 
| 
      
 1735 
     | 
    
         
            +
                @pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?")
         
     | 
| 
      
 1736 
     | 
    
         
            +
                @pirate.birds.create(name: "cookoo")
         
     | 
| 
      
 1737 
     | 
    
         
            +
             
     | 
| 
      
 1738 
     | 
    
         
            +
                @author = Author.new(name: "DHH")
         
     | 
| 
      
 1739 
     | 
    
         
            +
                @author.published_books.build(name: "Rework", isbn: "1234")
         
     | 
| 
      
 1740 
     | 
    
         
            +
                @author.published_books.build(name: "Remote", isbn: "1234")
         
     | 
| 
       1593 
1741 
     | 
    
         
             
              end
         
     | 
| 
       1594 
1742 
     | 
    
         | 
| 
       1595 
1743 
     | 
    
         
             
              test "should automatically validate associations" do
         
     | 
| 
       1596 
     | 
    
         
            -
                 
     | 
| 
       1597 
     | 
    
         
            -
                @pirate.birds.each { |bird| bird.name =  
     | 
| 
      
 1744 
     | 
    
         
            +
                assert_predicate @pirate, :valid?
         
     | 
| 
      
 1745 
     | 
    
         
            +
                @pirate.birds.each { |bird| bird.name = "" }
         
     | 
| 
      
 1746 
     | 
    
         
            +
             
     | 
| 
      
 1747 
     | 
    
         
            +
                assert_not_predicate @pirate, :valid?
         
     | 
| 
      
 1748 
     | 
    
         
            +
              end
         
     | 
| 
      
 1749 
     | 
    
         
            +
             
     | 
| 
      
 1750 
     | 
    
         
            +
              test "rollbacks whole transaction and raises ActiveRecord::RecordInvalid when associations fail to #save! due to uniqueness validation failure" do
         
     | 
| 
      
 1751 
     | 
    
         
            +
                author_count_before_save = Author.count
         
     | 
| 
      
 1752 
     | 
    
         
            +
                book_count_before_save = Book.count
         
     | 
| 
      
 1753 
     | 
    
         
            +
             
     | 
| 
      
 1754 
     | 
    
         
            +
                assert_no_difference "Author.count" do
         
     | 
| 
      
 1755 
     | 
    
         
            +
                  assert_no_difference "Book.count" do
         
     | 
| 
      
 1756 
     | 
    
         
            +
                    exception = assert_raises(ActiveRecord::RecordInvalid) do
         
     | 
| 
      
 1757 
     | 
    
         
            +
                      @author.save!
         
     | 
| 
      
 1758 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1759 
     | 
    
         
            +
             
     | 
| 
      
 1760 
     | 
    
         
            +
                    assert_equal("Validation failed: Published books is invalid", exception.message)
         
     | 
| 
      
 1761 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1762 
     | 
    
         
            +
                end
         
     | 
| 
      
 1763 
     | 
    
         
            +
             
     | 
| 
      
 1764 
     | 
    
         
            +
                assert_equal(author_count_before_save, Author.count)
         
     | 
| 
      
 1765 
     | 
    
         
            +
                assert_equal(book_count_before_save, Book.count)
         
     | 
| 
      
 1766 
     | 
    
         
            +
              end
         
     | 
| 
       1598 
1767 
     | 
    
         | 
| 
       1599 
     | 
    
         
            -
             
     | 
| 
      
 1768 
     | 
    
         
            +
              test "rollbacks whole transaction when associations fail to #save due to uniqueness validation failure" do
         
     | 
| 
      
 1769 
     | 
    
         
            +
                author_count_before_save = Author.count
         
     | 
| 
      
 1770 
     | 
    
         
            +
                book_count_before_save = Book.count
         
     | 
| 
      
 1771 
     | 
    
         
            +
             
     | 
| 
      
 1772 
     | 
    
         
            +
                assert_no_difference "Author.count" do
         
     | 
| 
      
 1773 
     | 
    
         
            +
                  assert_no_difference "Book.count" do
         
     | 
| 
      
 1774 
     | 
    
         
            +
                    assert_nothing_raised do
         
     | 
| 
      
 1775 
     | 
    
         
            +
                      result = @author.save
         
     | 
| 
      
 1776 
     | 
    
         
            +
             
     | 
| 
      
 1777 
     | 
    
         
            +
                      assert_not(result)
         
     | 
| 
      
 1778 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1779 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1780 
     | 
    
         
            +
                end
         
     | 
| 
      
 1781 
     | 
    
         
            +
             
     | 
| 
      
 1782 
     | 
    
         
            +
                assert_equal(author_count_before_save, Author.count)
         
     | 
| 
      
 1783 
     | 
    
         
            +
                assert_equal(book_count_before_save, Book.count)
         
     | 
| 
      
 1784 
     | 
    
         
            +
              end
         
     | 
| 
      
 1785 
     | 
    
         
            +
             
     | 
| 
      
 1786 
     | 
    
         
            +
              def test_validations_still_fire_on_unchanged_association_with_custom_validation_context
         
     | 
| 
      
 1787 
     | 
    
         
            +
                pirate = FamousPirate.create!(catchphrase: "Avast Ye!")
         
     | 
| 
      
 1788 
     | 
    
         
            +
                pirate.famous_ships.create!
         
     | 
| 
      
 1789 
     | 
    
         
            +
             
     | 
| 
      
 1790 
     | 
    
         
            +
                assert pirate.valid?
         
     | 
| 
      
 1791 
     | 
    
         
            +
                assert_not pirate.valid?(:conference)
         
     | 
| 
       1600 
1792 
     | 
    
         
             
              end
         
     | 
| 
       1601 
1793 
     | 
    
         
             
            end
         
     | 
| 
       1602 
1794 
     | 
    
         | 
| 
         @@ -1605,21 +1797,21 @@ class TestAutosaveAssociationValidationsOnAHasOneAssociation < ActiveRecord::Tes 
     | 
|
| 
       1605 
1797 
     | 
    
         | 
| 
       1606 
1798 
     | 
    
         
             
              def setup
         
     | 
| 
       1607 
1799 
     | 
    
         
             
                super
         
     | 
| 
       1608 
     | 
    
         
            -
                @pirate = Pirate.create(: 
     | 
| 
       1609 
     | 
    
         
            -
                @pirate.create_ship(: 
     | 
| 
      
 1800 
     | 
    
         
            +
                @pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?")
         
     | 
| 
      
 1801 
     | 
    
         
            +
                @pirate.create_ship(name: "titanic")
         
     | 
| 
       1610 
1802 
     | 
    
         
             
                super
         
     | 
| 
       1611 
1803 
     | 
    
         
             
              end
         
     | 
| 
       1612 
1804 
     | 
    
         | 
| 
       1613 
1805 
     | 
    
         
             
              test "should automatically validate associations with :validate => true" do
         
     | 
| 
       1614 
     | 
    
         
            -
                 
     | 
| 
       1615 
     | 
    
         
            -
                @pirate.ship.name =  
     | 
| 
       1616 
     | 
    
         
            -
                 
     | 
| 
      
 1806 
     | 
    
         
            +
                assert_predicate @pirate, :valid?
         
     | 
| 
      
 1807 
     | 
    
         
            +
                @pirate.ship.name = ""
         
     | 
| 
      
 1808 
     | 
    
         
            +
                assert_not_predicate @pirate, :valid?
         
     | 
| 
       1617 
1809 
     | 
    
         
             
              end
         
     | 
| 
       1618 
1810 
     | 
    
         | 
| 
       1619 
1811 
     | 
    
         
             
              test "should not automatically add validate associations without :validate => true" do
         
     | 
| 
       1620 
     | 
    
         
            -
                 
     | 
| 
       1621 
     | 
    
         
            -
                @pirate.non_validated_ship.name =  
     | 
| 
       1622 
     | 
    
         
            -
                 
     | 
| 
      
 1812 
     | 
    
         
            +
                assert_predicate @pirate, :valid?
         
     | 
| 
      
 1813 
     | 
    
         
            +
                @pirate.non_validated_ship.name = ""
         
     | 
| 
      
 1814 
     | 
    
         
            +
                assert_predicate @pirate, :valid?
         
     | 
| 
       1623 
1815 
     | 
    
         
             
              end
         
     | 
| 
       1624 
1816 
     | 
    
         
             
            end
         
     | 
| 
       1625 
1817 
     | 
    
         | 
| 
         @@ -1628,19 +1820,26 @@ class TestAutosaveAssociationValidationsOnABelongsToAssociation < ActiveRecord:: 
     | 
|
| 
       1628 
1820 
     | 
    
         | 
| 
       1629 
1821 
     | 
    
         
             
              def setup
         
     | 
| 
       1630 
1822 
     | 
    
         
             
                super
         
     | 
| 
       1631 
     | 
    
         
            -
                @pirate = Pirate.create(: 
     | 
| 
      
 1823 
     | 
    
         
            +
                @pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?")
         
     | 
| 
       1632 
1824 
     | 
    
         
             
              end
         
     | 
| 
       1633 
1825 
     | 
    
         | 
| 
       1634 
1826 
     | 
    
         
             
              test "should automatically validate associations with :validate => true" do
         
     | 
| 
       1635 
     | 
    
         
            -
                 
     | 
| 
       1636 
     | 
    
         
            -
                @pirate.parrot = Parrot.new(: 
     | 
| 
       1637 
     | 
    
         
            -
                 
     | 
| 
      
 1827 
     | 
    
         
            +
                assert_predicate @pirate, :valid?
         
     | 
| 
      
 1828 
     | 
    
         
            +
                @pirate.parrot = Parrot.new(name: "")
         
     | 
| 
      
 1829 
     | 
    
         
            +
                assert_not_predicate @pirate, :valid?
         
     | 
| 
       1638 
1830 
     | 
    
         
             
              end
         
     | 
| 
       1639 
1831 
     | 
    
         | 
| 
       1640 
1832 
     | 
    
         
             
              test "should not automatically validate associations without :validate => true" do
         
     | 
| 
       1641 
     | 
    
         
            -
                 
     | 
| 
       1642 
     | 
    
         
            -
                @pirate.non_validated_parrot = Parrot.new(: 
     | 
| 
       1643 
     | 
    
         
            -
                 
     | 
| 
      
 1833 
     | 
    
         
            +
                assert_predicate @pirate, :valid?
         
     | 
| 
      
 1834 
     | 
    
         
            +
                @pirate.non_validated_parrot = Parrot.new(name: "")
         
     | 
| 
      
 1835 
     | 
    
         
            +
                assert_predicate @pirate, :valid?
         
     | 
| 
      
 1836 
     | 
    
         
            +
              end
         
     | 
| 
      
 1837 
     | 
    
         
            +
             
     | 
| 
      
 1838 
     | 
    
         
            +
              def test_validations_still_fire_on_unchanged_association_with_custom_validation_context
         
     | 
| 
      
 1839 
     | 
    
         
            +
                firm_with_low_credit = Firm.create!(name: "Something", account: Account.new(credit_limit: 50))
         
     | 
| 
      
 1840 
     | 
    
         
            +
             
     | 
| 
      
 1841 
     | 
    
         
            +
                assert firm_with_low_credit.valid?
         
     | 
| 
      
 1842 
     | 
    
         
            +
                assert_not firm_with_low_credit.valid?(:bank_loan)
         
     | 
| 
       1644 
1843 
     | 
    
         
             
              end
         
     | 
| 
       1645 
1844 
     | 
    
         
             
            end
         
     | 
| 
       1646 
1845 
     | 
    
         | 
| 
         @@ -1649,21 +1848,21 @@ class TestAutosaveAssociationValidationsOnAHABTMAssociation < ActiveRecord::Test 
     | 
|
| 
       1649 
1848 
     | 
    
         | 
| 
       1650 
1849 
     | 
    
         
             
              def setup
         
     | 
| 
       1651 
1850 
     | 
    
         
             
                super
         
     | 
| 
       1652 
     | 
    
         
            -
                @pirate = Pirate.create(: 
     | 
| 
      
 1851 
     | 
    
         
            +
                @pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?")
         
     | 
| 
       1653 
1852 
     | 
    
         
             
              end
         
     | 
| 
       1654 
1853 
     | 
    
         | 
| 
       1655 
1854 
     | 
    
         
             
              test "should automatically validate associations with :validate => true" do
         
     | 
| 
       1656 
     | 
    
         
            -
                 
     | 
| 
       1657 
     | 
    
         
            -
                @pirate.parrots = [ Parrot.new(: 
     | 
| 
       1658 
     | 
    
         
            -
                @pirate.parrots.each { |parrot| parrot.name =  
     | 
| 
       1659 
     | 
    
         
            -
                 
     | 
| 
      
 1855 
     | 
    
         
            +
                assert_predicate @pirate, :valid?
         
     | 
| 
      
 1856 
     | 
    
         
            +
                @pirate.parrots = [ Parrot.new(name: "popuga") ]
         
     | 
| 
      
 1857 
     | 
    
         
            +
                @pirate.parrots.each { |parrot| parrot.name = "" }
         
     | 
| 
      
 1858 
     | 
    
         
            +
                assert_not_predicate @pirate, :valid?
         
     | 
| 
       1660 
1859 
     | 
    
         
             
              end
         
     | 
| 
       1661 
1860 
     | 
    
         | 
| 
       1662 
1861 
     | 
    
         
             
              test "should not automatically validate associations without :validate => true" do
         
     | 
| 
       1663 
     | 
    
         
            -
                 
     | 
| 
       1664 
     | 
    
         
            -
                @pirate.non_validated_parrots = [ Parrot.new(: 
     | 
| 
       1665 
     | 
    
         
            -
                @pirate.non_validated_parrots.each { |parrot| parrot.name =  
     | 
| 
       1666 
     | 
    
         
            -
                 
     | 
| 
      
 1862 
     | 
    
         
            +
                assert_predicate @pirate, :valid?
         
     | 
| 
      
 1863 
     | 
    
         
            +
                @pirate.non_validated_parrots = [ Parrot.new(name: "popuga") ]
         
     | 
| 
      
 1864 
     | 
    
         
            +
                @pirate.non_validated_parrots.each { |parrot| parrot.name = "" }
         
     | 
| 
      
 1865 
     | 
    
         
            +
                assert_predicate @pirate, :valid?
         
     | 
| 
       1667 
1866 
     | 
    
         
             
              end
         
     | 
| 
       1668 
1867 
     | 
    
         
             
            end
         
     | 
| 
       1669 
1868 
     | 
    
         | 
| 
         @@ -1684,7 +1883,7 @@ class TestAutosaveAssociationValidationMethodsGeneration < ActiveRecord::TestCas 
     | 
|
| 
       1684 
1883 
     | 
    
         
             
              end
         
     | 
| 
       1685 
1884 
     | 
    
         | 
| 
       1686 
1885 
     | 
    
         
             
              test "should not generate validation methods for has_one associations without :validate => true" do
         
     | 
| 
       1687 
     | 
    
         
            -
                 
     | 
| 
      
 1886 
     | 
    
         
            +
                assert_not_respond_to @pirate, :validate_associated_records_for_non_validated_ship
         
     | 
| 
       1688 
1887 
     | 
    
         
             
              end
         
     | 
| 
       1689 
1888 
     | 
    
         | 
| 
       1690 
1889 
     | 
    
         
             
              test "should generate validation methods for belongs_to associations with :validate => true" do
         
     | 
| 
         @@ -1692,7 +1891,7 @@ class TestAutosaveAssociationValidationMethodsGeneration < ActiveRecord::TestCas 
     | 
|
| 
       1692 
1891 
     | 
    
         
             
              end
         
     | 
| 
       1693 
1892 
     | 
    
         | 
| 
       1694 
1893 
     | 
    
         
             
              test "should not generate validation methods for belongs_to associations without :validate => true" do
         
     | 
| 
       1695 
     | 
    
         
            -
                 
     | 
| 
      
 1894 
     | 
    
         
            +
                assert_not_respond_to @pirate, :validate_associated_records_for_non_validated_parrot
         
     | 
| 
       1696 
1895 
     | 
    
         
             
              end
         
     | 
| 
       1697 
1896 
     | 
    
         | 
| 
       1698 
1897 
     | 
    
         
             
              test "should generate validation methods for HABTM associations with :validate => true" do
         
     | 
| 
         @@ -1703,6 +1902,52 @@ end 
     | 
|
| 
       1703 
1902 
     | 
    
         
             
            class TestAutosaveAssociationWithTouch < ActiveRecord::TestCase
         
     | 
| 
       1704 
1903 
     | 
    
         
             
              def test_autosave_with_touch_should_not_raise_system_stack_error
         
     | 
| 
       1705 
1904 
     | 
    
         
             
                invoice = Invoice.create
         
     | 
| 
       1706 
     | 
    
         
            -
                assert_nothing_raised { invoice.line_items.create(: 
     | 
| 
      
 1905 
     | 
    
         
            +
                assert_nothing_raised { invoice.line_items.create(amount: 10) }
         
     | 
| 
      
 1906 
     | 
    
         
            +
              end
         
     | 
| 
      
 1907 
     | 
    
         
            +
            end
         
     | 
| 
      
 1908 
     | 
    
         
            +
             
     | 
| 
      
 1909 
     | 
    
         
            +
            class TestAutosaveAssociationOnAHasManyAssociationWithInverse < ActiveRecord::TestCase
         
     | 
| 
      
 1910 
     | 
    
         
            +
              class Post < ActiveRecord::Base
         
     | 
| 
      
 1911 
     | 
    
         
            +
                has_many :comments, inverse_of: :post
         
     | 
| 
      
 1912 
     | 
    
         
            +
              end
         
     | 
| 
      
 1913 
     | 
    
         
            +
             
     | 
| 
      
 1914 
     | 
    
         
            +
              class Comment < ActiveRecord::Base
         
     | 
| 
      
 1915 
     | 
    
         
            +
                belongs_to :post, inverse_of: :comments
         
     | 
| 
      
 1916 
     | 
    
         
            +
             
     | 
| 
      
 1917 
     | 
    
         
            +
                attr_accessor :post_comments_count
         
     | 
| 
      
 1918 
     | 
    
         
            +
                after_save do
         
     | 
| 
      
 1919 
     | 
    
         
            +
                  self.post_comments_count = post.comments.count
         
     | 
| 
      
 1920 
     | 
    
         
            +
                end
         
     | 
| 
      
 1921 
     | 
    
         
            +
              end
         
     | 
| 
      
 1922 
     | 
    
         
            +
             
     | 
| 
      
 1923 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 1924 
     | 
    
         
            +
                Comment.delete_all
         
     | 
| 
      
 1925 
     | 
    
         
            +
              end
         
     | 
| 
      
 1926 
     | 
    
         
            +
             
     | 
| 
      
 1927 
     | 
    
         
            +
              def test_after_save_callback_with_autosave
         
     | 
| 
      
 1928 
     | 
    
         
            +
                post = Post.new(title: "Test", body: "...")
         
     | 
| 
      
 1929 
     | 
    
         
            +
                comment = post.comments.build(body: "...")
         
     | 
| 
      
 1930 
     | 
    
         
            +
                post.save!
         
     | 
| 
      
 1931 
     | 
    
         
            +
             
     | 
| 
      
 1932 
     | 
    
         
            +
                assert_equal 1, post.comments.count
         
     | 
| 
      
 1933 
     | 
    
         
            +
                assert_equal 1, comment.post_comments_count
         
     | 
| 
      
 1934 
     | 
    
         
            +
              end
         
     | 
| 
      
 1935 
     | 
    
         
            +
            end
         
     | 
| 
      
 1936 
     | 
    
         
            +
             
     | 
| 
      
 1937 
     | 
    
         
            +
            class TestAutosaveAssociationOnAHasManyAssociationDefinedInSubclassWithAcceptsNestedAttributes < ActiveRecord::TestCase
         
     | 
| 
      
 1938 
     | 
    
         
            +
              def test_should_update_children_when_association_redefined_in_subclass
         
     | 
| 
      
 1939 
     | 
    
         
            +
                agency = Agency.create!(name: "Agency")
         
     | 
| 
      
 1940 
     | 
    
         
            +
                valid_project = Project.create!(firm: agency, name: "Initial")
         
     | 
| 
      
 1941 
     | 
    
         
            +
                agency.update!(
         
     | 
| 
      
 1942 
     | 
    
         
            +
                  "projects_attributes" => {
         
     | 
| 
      
 1943 
     | 
    
         
            +
                    "0" => {
         
     | 
| 
      
 1944 
     | 
    
         
            +
                      "name" => "Updated",
         
     | 
| 
      
 1945 
     | 
    
         
            +
                      "id" => valid_project.id
         
     | 
| 
      
 1946 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1947 
     | 
    
         
            +
                  }
         
     | 
| 
      
 1948 
     | 
    
         
            +
                )
         
     | 
| 
      
 1949 
     | 
    
         
            +
                valid_project.reload
         
     | 
| 
      
 1950 
     | 
    
         
            +
             
     | 
| 
      
 1951 
     | 
    
         
            +
                assert_equal "Updated", valid_project.name
         
     | 
| 
       1707 
1952 
     | 
    
         
             
              end
         
     | 
| 
       1708 
1953 
     | 
    
         
             
            end
         
     |