ibm_db 5.2.0-x86-mingw32 → 5.4.0-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- 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,44 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "cases/helper"
|
2
|
-
require
|
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
|
29
|
-
require
|
30
|
-
require
|
4
|
+
require "models/post"
|
5
|
+
require "models/person"
|
6
|
+
require "models/reference"
|
7
|
+
require "models/job"
|
8
|
+
require "models/reader"
|
9
|
+
require "models/comment"
|
10
|
+
require "models/rating"
|
11
|
+
require "models/tag"
|
12
|
+
require "models/tagging"
|
13
|
+
require "models/author"
|
14
|
+
require "models/owner"
|
15
|
+
require "models/pet"
|
16
|
+
require "models/pet_treasure"
|
17
|
+
require "models/toy"
|
18
|
+
require "models/treasure"
|
19
|
+
require "models/contract"
|
20
|
+
require "models/company"
|
21
|
+
require "models/developer"
|
22
|
+
require "models/computer"
|
23
|
+
require "models/subscriber"
|
24
|
+
require "models/book"
|
25
|
+
require "models/subscription"
|
26
|
+
require "models/essay"
|
27
|
+
require "models/category"
|
28
|
+
require "models/categorization"
|
29
|
+
require "models/member"
|
30
|
+
require "models/membership"
|
31
|
+
require "models/club"
|
32
|
+
require "models/organization"
|
33
|
+
require "models/user"
|
34
|
+
require "models/family"
|
35
|
+
require "models/family_tree"
|
36
|
+
require "models/section"
|
37
|
+
require "models/seminar"
|
38
|
+
require "models/session"
|
31
39
|
|
32
40
|
class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
33
41
|
fixtures :posts, :readers, :people, :comments, :authors, :categories, :taggings, :tags,
|
34
42
|
:owners, :pets, :toys, :jobs, :references, :companies, :members, :author_addresses,
|
35
43
|
:subscribers, :books, :subscriptions, :developers, :categorizations, :essays,
|
36
|
-
:categories_posts, :clubs, :memberships, :organizations
|
44
|
+
:categories_posts, :clubs, :memberships, :organizations, :author_favorites
|
37
45
|
|
38
46
|
# Dummies to force column loads so query counts are clean.
|
39
47
|
def setup
|
40
|
-
Person.create :
|
41
|
-
Reader.create :
|
48
|
+
Person.create first_name: "gummy"
|
49
|
+
Reader.create person_id: 0, post_id: 0
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_has_many_through_create_record
|
53
|
+
assert books(:awdr).subscribers.create!(nick: "bob")
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_marshal_dump
|
57
|
+
preloaded = Post.includes(:first_blue_tags).first
|
58
|
+
assert_equal preloaded, Marshal.load(Marshal.dump(preloaded))
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_through_association_with_joins
|
62
|
+
assert_equal [comments(:eager_other_comment1)], authors(:mary).comments.merge(Post.joins(:comments))
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_through_association_with_left_joins
|
66
|
+
assert_equal [comments(:eager_other_comment1)], authors(:mary).comments.merge(Post.left_joins(:comments))
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_through_association_with_through_scope_and_nested_where
|
70
|
+
company = Company.create!(name: "special")
|
71
|
+
developer = SpecialDeveloper.create!
|
72
|
+
SpecialContract.create!(company: company, special_developer: developer)
|
73
|
+
|
74
|
+
assert_equal [developer], company.special_developers.where.not("contracts.id": nil)
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_preload_with_nested_association
|
78
|
+
posts = Post.where(id: [authors(:david).id, authors(:mary).id]).
|
79
|
+
preload(:author, :author_favorites_with_scope).order(:id).to_a
|
80
|
+
|
81
|
+
assert_no_queries do
|
82
|
+
posts.each(&:author)
|
83
|
+
posts.each(&:author_favorites_with_scope)
|
84
|
+
assert_equal 1, posts[0].author_favorites_with_scope.length
|
85
|
+
end
|
42
86
|
end
|
43
87
|
|
44
88
|
def test_preload_sti_rhs_class
|
@@ -49,9 +93,9 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
49
93
|
end
|
50
94
|
|
51
95
|
def test_preload_sti_middle_relation
|
52
|
-
club = Club.create!(name:
|
53
|
-
member1 = Member.create!(name:
|
54
|
-
member2 = Member.create!(name:
|
96
|
+
club = Club.create!(name: "Aaron cool banana club")
|
97
|
+
member1 = Member.create!(name: "Aaron")
|
98
|
+
member2 = Member.create!(name: "Cat")
|
55
99
|
|
56
100
|
SuperMembership.create! club: club, member: member1
|
57
101
|
CurrentMembership.create! club: club, member: member2
|
@@ -61,21 +105,26 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
61
105
|
club1.members.sort_by(&:id)
|
62
106
|
end
|
63
107
|
|
64
|
-
def
|
65
|
-
|
108
|
+
def test_preload_multiple_instances_of_the_same_record
|
109
|
+
club = Club.create!(name: "Aaron cool banana club")
|
110
|
+
Membership.create! club: club, member: Member.create!(name: "Aaron")
|
111
|
+
Membership.create! club: club, member: Member.create!(name: "Bob")
|
112
|
+
|
113
|
+
preloaded_clubs = Club.joins(:memberships).preload(:membership).to_a
|
114
|
+
assert_no_queries { preloaded_clubs.each(&:membership) }
|
66
115
|
end
|
67
116
|
|
68
|
-
def
|
117
|
+
def test_ordered_has_many_through
|
69
118
|
person_prime = Class.new(ActiveRecord::Base) do
|
70
|
-
def self.name;
|
119
|
+
def self.name; "Person"; end
|
71
120
|
|
72
121
|
has_many :readers
|
73
|
-
has_many :posts, -> { order(
|
122
|
+
has_many :posts, -> { order("posts.id DESC") }, through: :readers
|
74
123
|
end
|
75
124
|
posts = person_prime.includes(:posts).first.posts
|
76
125
|
|
77
126
|
assert_operator posts.length, :>, 1
|
78
|
-
posts.each_cons(2) do |left,right|
|
127
|
+
posts.each_cons(2) do |left, right|
|
79
128
|
assert_operator left.id, :>, right.id
|
80
129
|
end
|
81
130
|
end
|
@@ -85,7 +134,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
85
134
|
subscription = make_model "Subscription"
|
86
135
|
subscriber = make_model "Subscriber"
|
87
136
|
|
88
|
-
subscriber.primary_key =
|
137
|
+
subscriber.primary_key = "nick"
|
89
138
|
subscription.belongs_to :book, anonymous_class: book
|
90
139
|
subscription.belongs_to :subscriber, anonymous_class: subscriber
|
91
140
|
|
@@ -106,8 +155,8 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
106
155
|
def test_no_pk_join_table_append
|
107
156
|
lesson, _, student = make_no_pk_hm_t
|
108
157
|
|
109
|
-
sicp = lesson.new(:
|
110
|
-
ben = student.new(:
|
158
|
+
sicp = lesson.new(name: "SICP")
|
159
|
+
ben = student.new(name: "Ben Bitdiddle")
|
111
160
|
sicp.students << ben
|
112
161
|
assert sicp.save!
|
113
162
|
end
|
@@ -115,17 +164,17 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
115
164
|
def test_no_pk_join_table_delete
|
116
165
|
lesson, lesson_student, student = make_no_pk_hm_t
|
117
166
|
|
118
|
-
sicp = lesson.new(:
|
119
|
-
ben = student.new(:
|
120
|
-
louis = student.new(:
|
167
|
+
sicp = lesson.new(name: "SICP")
|
168
|
+
ben = student.new(name: "Ben Bitdiddle")
|
169
|
+
louis = student.new(name: "Louis Reasoner")
|
121
170
|
sicp.students << ben
|
122
171
|
sicp.students << louis
|
123
172
|
assert sicp.save!
|
124
173
|
|
125
174
|
sicp.students.reload
|
126
175
|
assert_operator lesson_student.count, :>=, 2
|
127
|
-
assert_no_difference(
|
128
|
-
assert_difference(
|
176
|
+
assert_no_difference("student.count") do
|
177
|
+
assert_difference("lesson_student.count", -2) do
|
129
178
|
sicp.students.destroy(*student.all.to_a)
|
130
179
|
end
|
131
180
|
end
|
@@ -139,8 +188,8 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
139
188
|
after_destroy_called = true
|
140
189
|
end
|
141
190
|
|
142
|
-
sicp = lesson.new(:
|
143
|
-
ben = student.new(:
|
191
|
+
sicp = lesson.new(name: "SICP")
|
192
|
+
ben = student.new(name: "Ben Bitdiddle")
|
144
193
|
sicp.students << ben
|
145
194
|
assert sicp.save!
|
146
195
|
|
@@ -149,33 +198,19 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
149
198
|
assert after_destroy_called, "after destroy should be called"
|
150
199
|
end
|
151
200
|
|
152
|
-
def make_no_pk_hm_t
|
153
|
-
lesson = make_model 'Lesson'
|
154
|
-
student = make_model 'Student'
|
155
|
-
|
156
|
-
lesson_student = make_model 'LessonStudent'
|
157
|
-
lesson_student.table_name = 'lessons_students'
|
158
|
-
|
159
|
-
lesson_student.belongs_to :lesson, :anonymous_class => lesson
|
160
|
-
lesson_student.belongs_to :student, :anonymous_class => student
|
161
|
-
lesson.has_many :lesson_students, :anonymous_class => lesson_student
|
162
|
-
lesson.has_many :students, :through => :lesson_students, :anonymous_class => student
|
163
|
-
[lesson, lesson_student, student]
|
164
|
-
end
|
165
|
-
|
166
201
|
def test_pk_is_not_required_for_join
|
167
202
|
post = Post.includes(:scategories).first
|
168
203
|
post2 = Post.includes(:categories).first
|
169
204
|
|
170
205
|
assert_operator post.categories.length, :>, 0
|
171
|
-
assert_equal post2.categories, post.categories
|
206
|
+
assert_equal post2.categories.sort_by(&:id), post.categories.sort_by(&:id)
|
172
207
|
end
|
173
208
|
|
174
209
|
def test_include?
|
175
210
|
person = Person.new
|
176
211
|
post = Post.new
|
177
212
|
person.posts << post
|
178
|
-
|
213
|
+
assert_includes person.posts, post
|
179
214
|
end
|
180
215
|
|
181
216
|
def test_associate_existing
|
@@ -187,19 +222,19 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
187
222
|
end
|
188
223
|
|
189
224
|
assert_queries(1) do
|
190
|
-
|
225
|
+
assert_includes post.people, person
|
191
226
|
end
|
192
227
|
|
193
|
-
|
228
|
+
assert_includes post.reload.people.reload, person
|
194
229
|
end
|
195
230
|
|
196
231
|
def test_delete_all_for_with_dependent_option_destroy
|
197
232
|
person = people(:david)
|
198
233
|
assert_equal 1, person.jobs_with_dependent_destroy.count
|
199
234
|
|
200
|
-
assert_no_difference
|
201
|
-
assert_difference
|
202
|
-
person.reload.jobs_with_dependent_destroy.delete_all
|
235
|
+
assert_no_difference "Job.count" do
|
236
|
+
assert_difference "Reference.count", -1 do
|
237
|
+
assert_equal 1, person.reload.jobs_with_dependent_destroy.delete_all
|
203
238
|
end
|
204
239
|
end
|
205
240
|
end
|
@@ -208,9 +243,9 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
208
243
|
person = people(:david)
|
209
244
|
assert_equal 1, person.jobs_with_dependent_nullify.count
|
210
245
|
|
211
|
-
assert_no_difference
|
212
|
-
assert_no_difference
|
213
|
-
person.reload.jobs_with_dependent_nullify.delete_all
|
246
|
+
assert_no_difference "Job.count" do
|
247
|
+
assert_no_difference "Reference.count" do
|
248
|
+
assert_equal 1, person.reload.jobs_with_dependent_nullify.delete_all
|
214
249
|
end
|
215
250
|
end
|
216
251
|
end
|
@@ -219,26 +254,35 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
219
254
|
person = people(:david)
|
220
255
|
assert_equal 1, person.jobs_with_dependent_delete_all.count
|
221
256
|
|
222
|
-
assert_no_difference
|
223
|
-
assert_difference
|
224
|
-
person.reload.jobs_with_dependent_delete_all.delete_all
|
257
|
+
assert_no_difference "Job.count" do
|
258
|
+
assert_difference "Reference.count", -1 do
|
259
|
+
assert_equal 1, person.reload.jobs_with_dependent_delete_all.delete_all
|
225
260
|
end
|
226
261
|
end
|
227
262
|
end
|
228
263
|
|
264
|
+
def test_delete_all_on_association_clears_scope
|
265
|
+
post = Post.create!(title: "Rails 6", body: "")
|
266
|
+
people = post.people
|
267
|
+
people.create!(first_name: "Jeb")
|
268
|
+
people.delete_all
|
269
|
+
assert_nil people.first
|
270
|
+
end
|
271
|
+
|
229
272
|
def test_concat
|
230
273
|
person = people(:david)
|
231
274
|
post = posts(:thinking)
|
232
|
-
post.people.concat [person]
|
275
|
+
result = post.people.concat [person]
|
233
276
|
assert_equal 1, post.people.size
|
234
277
|
assert_equal 1, post.people.reload.size
|
278
|
+
assert_equal post.people, result
|
235
279
|
end
|
236
280
|
|
237
281
|
def test_associate_existing_record_twice_should_add_to_target_twice
|
238
282
|
post = posts(:thinking)
|
239
283
|
person = people(:david)
|
240
284
|
|
241
|
-
assert_difference
|
285
|
+
assert_difference "post.people.to_a.count", 2 do
|
242
286
|
post.people << person
|
243
287
|
post.people << person
|
244
288
|
end
|
@@ -248,7 +292,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
248
292
|
post = posts(:thinking)
|
249
293
|
person = people(:david)
|
250
294
|
|
251
|
-
assert_difference
|
295
|
+
assert_difference "post.people.count", 2 do
|
252
296
|
post.people << person
|
253
297
|
post.people << person
|
254
298
|
end
|
@@ -261,12 +305,12 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
261
305
|
post.people << person
|
262
306
|
post.people << person
|
263
307
|
|
264
|
-
counts = [
|
308
|
+
counts = ["post.people.count", "post.people.to_a.count", "post.readers.count", "post.readers.to_a.count"]
|
265
309
|
assert_difference counts, -2 do
|
266
310
|
post.people.delete(person)
|
267
311
|
end
|
268
312
|
|
269
|
-
|
313
|
+
assert_not_includes post.people.reload, person
|
270
314
|
end
|
271
315
|
|
272
316
|
def test_associating_new
|
@@ -274,7 +318,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
274
318
|
new_person = nil # so block binding catches it
|
275
319
|
|
276
320
|
assert_queries(0) do
|
277
|
-
new_person = Person.new :
|
321
|
+
new_person = Person.new first_name: "bob"
|
278
322
|
end
|
279
323
|
|
280
324
|
# Associating new records always saves them
|
@@ -284,59 +328,70 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
284
328
|
end
|
285
329
|
|
286
330
|
assert_queries(1) do
|
287
|
-
|
331
|
+
assert_includes posts(:thinking).people, new_person
|
288
332
|
end
|
289
333
|
|
290
|
-
|
334
|
+
assert_includes posts(:thinking).reload.people.reload, new_person
|
291
335
|
end
|
292
336
|
|
293
337
|
def test_associate_new_by_building
|
294
338
|
assert_queries(1) { posts(:thinking) }
|
295
339
|
|
296
340
|
assert_queries(0) do
|
297
|
-
posts(:thinking).people.build(:
|
298
|
-
posts(:thinking).people.new(:
|
341
|
+
posts(:thinking).people.build(first_name: "Bob")
|
342
|
+
posts(:thinking).people.new(first_name: "Ted")
|
299
343
|
end
|
300
344
|
|
301
345
|
# Should only need to load the association once
|
302
346
|
assert_queries(1) do
|
303
|
-
|
304
|
-
|
347
|
+
assert_includes posts(:thinking).people.collect(&:first_name), "Bob"
|
348
|
+
assert_includes posts(:thinking).people.collect(&:first_name), "Ted"
|
305
349
|
end
|
306
350
|
|
307
351
|
# 2 queries for each new record (1 to save the record itself, 1 for the join model)
|
308
352
|
# * 2 new records = 4
|
309
353
|
# + 1 query to save the actual post = 5
|
310
354
|
assert_queries(5) do
|
311
|
-
posts(:thinking).body +=
|
355
|
+
posts(:thinking).body += "-changed"
|
312
356
|
posts(:thinking).save
|
313
357
|
end
|
314
358
|
|
315
|
-
|
316
|
-
|
359
|
+
assert_includes posts(:thinking).reload.people.reload.collect(&:first_name), "Bob"
|
360
|
+
assert_includes posts(:thinking).reload.people.reload.collect(&:first_name), "Ted"
|
317
361
|
end
|
318
362
|
|
319
363
|
def test_build_then_save_with_has_many_inverse
|
320
364
|
post = posts(:thinking)
|
321
|
-
person = post.people.build(:
|
365
|
+
person = post.people.build(first_name: "Bob")
|
322
366
|
person.save
|
323
367
|
post.reload
|
324
368
|
|
325
|
-
|
369
|
+
assert_includes post.people, person
|
326
370
|
end
|
327
371
|
|
328
372
|
def test_build_then_save_with_has_one_inverse
|
329
373
|
post = posts(:thinking)
|
330
|
-
person = post.single_people.build(:
|
374
|
+
person = post.single_people.build(first_name: "Bob")
|
331
375
|
person.save
|
332
376
|
post.reload
|
333
377
|
|
334
|
-
|
378
|
+
assert_includes post.single_people, person
|
379
|
+
end
|
380
|
+
|
381
|
+
def test_build_then_remove_then_save
|
382
|
+
post = posts(:thinking)
|
383
|
+
post.people.build(first_name: "Bob")
|
384
|
+
ted = post.people.build(first_name: "Ted")
|
385
|
+
post.people.delete(ted)
|
386
|
+
post.save!
|
387
|
+
post.reload
|
388
|
+
|
389
|
+
assert_equal ["Bob"], post.people.collect(&:first_name)
|
335
390
|
end
|
336
391
|
|
337
392
|
def test_both_parent_ids_set_when_saving_new
|
338
|
-
post = Post.new(title:
|
339
|
-
person = Person.new(first_name:
|
393
|
+
post = Post.new(title: "Hello", body: "world")
|
394
|
+
person = Person.new(first_name: "Sean")
|
340
395
|
|
341
396
|
post.people = [person]
|
342
397
|
post.save
|
@@ -348,17 +403,17 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
348
403
|
end
|
349
404
|
|
350
405
|
def test_delete_association
|
351
|
-
assert_queries(2){posts(:welcome);people(:michael); }
|
406
|
+
assert_queries(2) { posts(:welcome); people(:michael); }
|
352
407
|
|
353
408
|
assert_queries(1) do
|
354
409
|
posts(:welcome).people.delete(people(:michael))
|
355
410
|
end
|
356
411
|
|
357
412
|
assert_queries(1) do
|
358
|
-
|
413
|
+
assert_empty posts(:welcome).people
|
359
414
|
end
|
360
415
|
|
361
|
-
|
416
|
+
assert_empty posts(:welcome).reload.people.reload
|
362
417
|
end
|
363
418
|
|
364
419
|
def test_destroy_association
|
@@ -368,8 +423,8 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
368
423
|
end
|
369
424
|
end
|
370
425
|
|
371
|
-
|
372
|
-
|
426
|
+
assert_empty posts(:welcome).reload.people
|
427
|
+
assert_empty posts(:welcome).people.reload
|
373
428
|
end
|
374
429
|
|
375
430
|
def test_destroy_all
|
@@ -379,8 +434,32 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
379
434
|
end
|
380
435
|
end
|
381
436
|
|
382
|
-
|
383
|
-
|
437
|
+
assert_empty posts(:welcome).reload.people
|
438
|
+
assert_empty posts(:welcome).people.reload
|
439
|
+
end
|
440
|
+
|
441
|
+
def test_destroy_all_on_association_clears_scope
|
442
|
+
post = Post.create!(title: "Rails 6", body: "")
|
443
|
+
people = post.people
|
444
|
+
people.create!(first_name: "Jeb")
|
445
|
+
people.destroy_all
|
446
|
+
assert_nil people.first
|
447
|
+
end
|
448
|
+
|
449
|
+
def test_destroy_on_association_clears_scope
|
450
|
+
post = Post.create!(title: "Rails 6", body: "")
|
451
|
+
people = post.people
|
452
|
+
person = people.create!(first_name: "Jeb")
|
453
|
+
people.destroy(person)
|
454
|
+
assert_nil people.first
|
455
|
+
end
|
456
|
+
|
457
|
+
def test_delete_on_association_clears_scope
|
458
|
+
post = Post.create!(title: "Rails 6", body: "")
|
459
|
+
people = post.people
|
460
|
+
person = people.create!(first_name: "Jeb")
|
461
|
+
people.delete(person)
|
462
|
+
assert_nil people.first
|
384
463
|
end
|
385
464
|
|
386
465
|
def test_should_raise_exception_for_destroying_mismatching_records
|
@@ -394,15 +473,15 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
394
473
|
|
395
474
|
person = people(:michael)
|
396
475
|
job = jobs(:magician)
|
397
|
-
reference = Reference.where(:
|
476
|
+
reference = Reference.where(job_id: job.id, person_id: person.id).first
|
398
477
|
|
399
|
-
assert_no_difference [
|
400
|
-
assert_difference
|
478
|
+
assert_no_difference ["Job.count", "Reference.count"] do
|
479
|
+
assert_difference "person.jobs.count", -1 do
|
401
480
|
person.jobs_with_dependent_nullify.delete(job)
|
402
481
|
end
|
403
482
|
end
|
404
483
|
|
405
|
-
|
484
|
+
assert_nil reference.reload.job_id
|
406
485
|
ensure
|
407
486
|
Reference.make_comments = false
|
408
487
|
end
|
@@ -416,14 +495,14 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
416
495
|
# Make sure we're not deleting everything
|
417
496
|
assert person.jobs.count >= 2
|
418
497
|
|
419
|
-
assert_no_difference
|
420
|
-
assert_difference [
|
498
|
+
assert_no_difference "Job.count" do
|
499
|
+
assert_difference ["person.jobs.count", "Reference.count"], -1 do
|
421
500
|
person.jobs_with_dependent_delete_all.delete(job)
|
422
501
|
end
|
423
502
|
end
|
424
503
|
|
425
504
|
# Check that the destroy callback on Reference did not run
|
426
|
-
|
505
|
+
assert_nil person.reload.comments
|
427
506
|
ensure
|
428
507
|
Reference.make_comments = false
|
429
508
|
end
|
@@ -437,8 +516,8 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
437
516
|
# Make sure we're not deleting everything
|
438
517
|
assert person.jobs.count >= 2
|
439
518
|
|
440
|
-
assert_no_difference
|
441
|
-
assert_difference [
|
519
|
+
assert_no_difference "Job.count" do
|
520
|
+
assert_difference ["person.jobs.count", "Reference.count"], -1 do
|
442
521
|
person.jobs_with_dependent_destroy.delete(job)
|
443
522
|
end
|
444
523
|
end
|
@@ -455,8 +534,8 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
455
534
|
# Create a reference which is not linked to a job. This should not be destroyed.
|
456
535
|
person.references.create!
|
457
536
|
|
458
|
-
assert_no_difference
|
459
|
-
assert_difference
|
537
|
+
assert_no_difference "Job.count" do
|
538
|
+
assert_difference "Reference.count", -person.jobs.count do
|
460
539
|
person.destroy
|
461
540
|
end
|
462
541
|
end
|
@@ -468,8 +547,8 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
468
547
|
# Create a reference which is not linked to a job. This should not be destroyed.
|
469
548
|
person.references.create!
|
470
549
|
|
471
|
-
assert_no_difference
|
472
|
-
assert_difference
|
550
|
+
assert_no_difference "Job.count" do
|
551
|
+
assert_difference "Reference.count", -person.jobs.count do
|
473
552
|
person.destroy
|
474
553
|
end
|
475
554
|
end
|
@@ -480,41 +559,41 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
480
559
|
|
481
560
|
references = person.references.to_a
|
482
561
|
|
483
|
-
assert_no_difference [
|
562
|
+
assert_no_difference ["Reference.count", "Job.count"] do
|
484
563
|
person.destroy
|
485
564
|
end
|
486
565
|
|
487
566
|
references.each do |reference|
|
488
|
-
|
567
|
+
assert_nil reference.reload.job_id
|
489
568
|
end
|
490
569
|
end
|
491
570
|
|
492
571
|
def test_update_counter_caches_on_delete
|
493
572
|
post = posts(:welcome)
|
494
|
-
tag = post.tags.create!(:
|
573
|
+
tag = post.tags.create!(name: "doomed")
|
495
574
|
|
496
|
-
assert_difference [
|
575
|
+
assert_difference ["post.reload.tags_count"], -1 do
|
497
576
|
posts(:welcome).tags.delete(tag)
|
498
577
|
end
|
499
578
|
end
|
500
579
|
|
501
580
|
def test_update_counter_caches_on_delete_with_dependent_destroy
|
502
581
|
post = posts(:welcome)
|
503
|
-
tag = post.tags.create!(:
|
582
|
+
tag = post.tags.create!(name: "doomed")
|
504
583
|
post.update_columns(tags_with_destroy_count: post.tags.count)
|
505
584
|
|
506
|
-
assert_difference [
|
585
|
+
assert_difference ["post.reload.tags_with_destroy_count"], -1 do
|
507
586
|
posts(:welcome).tags_with_destroy.delete(tag)
|
508
587
|
end
|
509
588
|
end
|
510
589
|
|
511
590
|
def test_update_counter_caches_on_delete_with_dependent_nullify
|
512
591
|
post = posts(:welcome)
|
513
|
-
tag = post.tags.create!(:
|
592
|
+
tag = post.tags.create!(name: "doomed")
|
514
593
|
post.update_columns(tags_with_nullify_count: post.tags.count)
|
515
594
|
|
516
|
-
assert_no_difference
|
517
|
-
assert_difference
|
595
|
+
assert_no_difference "post.reload.tags_count" do
|
596
|
+
assert_difference "post.reload.tags_with_nullify_count", -1 do
|
518
597
|
posts(:welcome).tags_with_nullify.delete(tag)
|
519
598
|
end
|
520
599
|
end
|
@@ -522,7 +601,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
522
601
|
|
523
602
|
def test_update_counter_caches_on_replace_association
|
524
603
|
post = posts(:welcome)
|
525
|
-
tag = post.tags.create!(:
|
604
|
+
tag = post.tags.create!(name: "doomed")
|
526
605
|
tag.tagged_posts << posts(:thinking)
|
527
606
|
|
528
607
|
tag.tagged_posts = []
|
@@ -533,15 +612,25 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
533
612
|
|
534
613
|
def test_update_counter_caches_on_destroy
|
535
614
|
post = posts(:welcome)
|
536
|
-
tag = post.tags.create!(name:
|
615
|
+
tag = post.tags.create!(name: "doomed")
|
537
616
|
|
538
|
-
assert_difference
|
617
|
+
assert_difference "post.reload.tags_count", -1 do
|
539
618
|
tag.tagged_posts.destroy(post)
|
540
619
|
end
|
541
620
|
end
|
542
621
|
|
622
|
+
def test_update_counter_caches_on_destroy_with_indestructible_through_record
|
623
|
+
post = posts(:welcome)
|
624
|
+
tag = post.indestructible_tags.create!(name: "doomed")
|
625
|
+
post.update_columns(indestructible_tags_count: post.indestructible_tags.count)
|
626
|
+
|
627
|
+
assert_no_difference "post.reload.indestructible_tags_count" do
|
628
|
+
posts(:welcome).indestructible_tags.destroy(tag)
|
629
|
+
end
|
630
|
+
end
|
631
|
+
|
543
632
|
def test_replace_association
|
544
|
-
assert_queries(4){posts(:welcome);people(:david);people(:michael); posts(:welcome).people.reload}
|
633
|
+
assert_queries(4) { posts(:welcome); people(:david); people(:michael); posts(:welcome).people.reload }
|
545
634
|
|
546
635
|
# 1 query to delete the existing reader (michael)
|
547
636
|
# 1 query to associate the new reader (david)
|
@@ -549,35 +638,45 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
549
638
|
posts(:welcome).people = [people(:david)]
|
550
639
|
end
|
551
640
|
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
641
|
+
assert_no_queries do
|
642
|
+
assert_includes posts(:welcome).people, people(:david)
|
643
|
+
assert_not_includes posts(:welcome).people, people(:michael)
|
644
|
+
end
|
645
|
+
|
646
|
+
assert_includes posts(:welcome).reload.people.reload, people(:david)
|
647
|
+
assert_not_includes posts(:welcome).reload.people.reload, people(:michael)
|
648
|
+
end
|
556
649
|
|
557
|
-
|
558
|
-
|
650
|
+
def test_replace_association_with_duplicates
|
651
|
+
post = posts(:thinking)
|
652
|
+
person = people(:david)
|
653
|
+
|
654
|
+
assert_difference "post.people.count", 2 do
|
655
|
+
post.people = [person]
|
656
|
+
post.people = [person, person]
|
657
|
+
end
|
559
658
|
end
|
560
659
|
|
561
660
|
def test_replace_order_is_preserved
|
562
661
|
posts(:welcome).people.clear
|
563
662
|
posts(:welcome).people = [people(:david), people(:michael)]
|
564
|
-
assert_equal [people(:david).id, people(:michael).id], posts(:welcome).readers.order(
|
663
|
+
assert_equal [people(:david).id, people(:michael).id], posts(:welcome).readers.order("id").map(&:person_id)
|
565
664
|
|
566
665
|
# Test the inverse order in case the first success was a coincidence
|
567
666
|
posts(:welcome).people.clear
|
568
667
|
posts(:welcome).people = [people(:michael), people(:david)]
|
569
|
-
assert_equal [people(:michael).id, people(:david).id], posts(:welcome).readers.order(
|
668
|
+
assert_equal [people(:michael).id, people(:david).id], posts(:welcome).readers.order("id").map(&:person_id)
|
570
669
|
end
|
571
670
|
|
572
671
|
def test_replace_by_id_order_is_preserved
|
573
672
|
posts(:welcome).people.clear
|
574
673
|
posts(:welcome).person_ids = [people(:david).id, people(:michael).id]
|
575
|
-
assert_equal [people(:david).id, people(:michael).id], posts(:welcome).readers.order(
|
674
|
+
assert_equal [people(:david).id, people(:michael).id], posts(:welcome).readers.order("id").map(&:person_id)
|
576
675
|
|
577
676
|
# Test the inverse order in case the first success was a coincidence
|
578
677
|
posts(:welcome).people.clear
|
579
678
|
posts(:welcome).person_ids = [people(:michael).id, people(:david).id]
|
580
|
-
assert_equal [people(:michael).id, people(:david).id], posts(:welcome).readers.order(
|
679
|
+
assert_equal [people(:michael).id, people(:david).id], posts(:welcome).readers.order("id").map(&:person_id)
|
581
680
|
end
|
582
681
|
|
583
682
|
def test_associate_with_create
|
@@ -586,101 +685,107 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
586
685
|
# 1 query for the new record, 1 for the join table record
|
587
686
|
# No need to update the actual collection yet!
|
588
687
|
assert_queries(2) do
|
589
|
-
posts(:thinking).people.create(:
|
688
|
+
posts(:thinking).people.create(first_name: "Jeb")
|
590
689
|
end
|
591
690
|
|
592
691
|
# *Now* we actually need the collection so it's loaded
|
593
692
|
assert_queries(1) do
|
594
|
-
|
693
|
+
assert_includes posts(:thinking).people.collect(&:first_name), "Jeb"
|
595
694
|
end
|
596
695
|
|
597
|
-
|
696
|
+
assert_includes posts(:thinking).reload.people.reload.collect(&:first_name), "Jeb"
|
598
697
|
end
|
599
698
|
|
600
699
|
def test_through_record_is_built_when_created_with_where
|
601
700
|
assert_difference("posts(:thinking).readers.count", 1) do
|
602
|
-
posts(:thinking).people.where(first_name: "Jeb")
|
701
|
+
posts(:thinking).people.where(readers: { skimmer: true }).create(first_name: "Jeb")
|
603
702
|
end
|
703
|
+
reader = posts(:thinking).readers.last
|
704
|
+
assert_equal true, reader.skimmer
|
604
705
|
end
|
605
706
|
|
606
707
|
def test_associate_with_create_and_no_options
|
607
708
|
peeps = posts(:thinking).people.count
|
608
|
-
posts(:thinking).people.create(:
|
709
|
+
posts(:thinking).people.create(first_name: "foo")
|
609
710
|
assert_equal peeps + 1, posts(:thinking).people.count
|
610
711
|
end
|
611
712
|
|
612
713
|
def test_associate_with_create_with_through_having_conditions
|
613
714
|
impatient_people = posts(:thinking).impatient_people.count
|
614
|
-
posts(:thinking).impatient_people.create!(:
|
715
|
+
posts(:thinking).impatient_people.create!(first_name: "foo")
|
615
716
|
assert_equal impatient_people + 1, posts(:thinking).impatient_people.count
|
616
717
|
end
|
617
718
|
|
618
719
|
def test_associate_with_create_exclamation_and_no_options
|
619
720
|
peeps = posts(:thinking).people.count
|
620
|
-
posts(:thinking).people.create!(:
|
721
|
+
posts(:thinking).people.create!(first_name: "foo")
|
621
722
|
assert_equal peeps + 1, posts(:thinking).people.count
|
622
723
|
end
|
623
724
|
|
624
725
|
def test_create_on_new_record
|
625
726
|
p = Post.new
|
626
727
|
|
627
|
-
error = assert_raises(ActiveRecord::RecordNotSaved) { p.people.create(:
|
728
|
+
error = assert_raises(ActiveRecord::RecordNotSaved) { p.people.create(first_name: "mew") }
|
628
729
|
assert_equal "You cannot call create unless the parent is saved", error.message
|
629
730
|
|
630
|
-
error = assert_raises(ActiveRecord::RecordNotSaved) { p.people.create!(:
|
731
|
+
error = assert_raises(ActiveRecord::RecordNotSaved) { p.people.create!(first_name: "snow") }
|
631
732
|
assert_equal "You cannot call create unless the parent is saved", error.message
|
632
733
|
end
|
633
734
|
|
634
735
|
def test_associate_with_create_and_invalid_options
|
635
736
|
firm = companies(:first_firm)
|
636
|
-
assert_no_difference(
|
737
|
+
assert_no_difference("firm.developers.count") { assert_nothing_raised { firm.developers.create(name: "0") } }
|
637
738
|
end
|
638
739
|
|
639
740
|
def test_associate_with_create_and_valid_options
|
640
741
|
firm = companies(:first_firm)
|
641
|
-
assert_difference(
|
742
|
+
assert_difference("firm.developers.count", 1) { firm.developers.create(name: "developer") }
|
642
743
|
end
|
643
744
|
|
644
745
|
def test_associate_with_create_bang_and_invalid_options
|
645
746
|
firm = companies(:first_firm)
|
646
|
-
assert_no_difference(
|
747
|
+
assert_no_difference("firm.developers.count") { assert_raises(ActiveRecord::RecordInvalid) { firm.developers.create!(name: "0") } }
|
647
748
|
end
|
648
749
|
|
649
750
|
def test_associate_with_create_bang_and_valid_options
|
650
751
|
firm = companies(:first_firm)
|
651
|
-
assert_difference(
|
752
|
+
assert_difference("firm.developers.count", 1) { firm.developers.create!(name: "developer") }
|
652
753
|
end
|
653
754
|
|
654
755
|
def test_push_with_invalid_record
|
655
756
|
firm = companies(:first_firm)
|
656
|
-
assert_raises(ActiveRecord::RecordInvalid) { firm.developers << Developer.new(:
|
757
|
+
assert_raises(ActiveRecord::RecordInvalid) { firm.developers << Developer.new(name: "0") }
|
657
758
|
end
|
658
759
|
|
659
760
|
def test_push_with_invalid_join_record
|
660
761
|
repair_validations(Contract) do
|
661
|
-
Contract.validate {|r| r.errors[:base] <<
|
762
|
+
Contract.validate { |r| r.errors[:base] << "Invalid Contract" }
|
662
763
|
|
663
764
|
firm = companies(:first_firm)
|
664
|
-
lifo = Developer.new(:
|
665
|
-
assert_raises(ActiveRecord::RecordInvalid)
|
765
|
+
lifo = Developer.new(name: "lifo")
|
766
|
+
assert_raises(ActiveRecord::RecordInvalid) do
|
767
|
+
assert_deprecated { firm.developers << lifo }
|
768
|
+
end
|
666
769
|
|
667
|
-
lifo = Developer.create!(:
|
668
|
-
assert_raises(ActiveRecord::RecordInvalid)
|
770
|
+
lifo = Developer.create!(name: "lifo")
|
771
|
+
assert_raises(ActiveRecord::RecordInvalid) do
|
772
|
+
assert_deprecated { firm.developers << lifo }
|
773
|
+
end
|
669
774
|
end
|
670
775
|
end
|
671
776
|
|
672
777
|
def test_clear_associations
|
673
|
-
assert_queries(2) { posts(:welcome);posts(:welcome).people.reload }
|
778
|
+
assert_queries(2) { posts(:welcome); posts(:welcome).people.reload }
|
674
779
|
|
675
780
|
assert_queries(1) do
|
676
781
|
posts(:welcome).people.clear
|
677
782
|
end
|
678
783
|
|
679
|
-
|
680
|
-
|
784
|
+
assert_no_queries do
|
785
|
+
assert_empty posts(:welcome).people
|
681
786
|
end
|
682
787
|
|
683
|
-
|
788
|
+
assert_empty posts(:welcome).reload.people.reload
|
684
789
|
end
|
685
790
|
|
686
791
|
def test_association_callback_ordering
|
@@ -694,7 +799,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
694
799
|
[:added, :after, "Michael"]
|
695
800
|
], log.last(2)
|
696
801
|
|
697
|
-
post.people_with_callbacks.push(people(:david), Person.create!(:
|
802
|
+
post.people_with_callbacks.push(people(:david), Person.create!(first_name: "Bob"), Person.new(first_name: "Lary"))
|
698
803
|
assert_equal [
|
699
804
|
[:added, :before, "David"],
|
700
805
|
[:added, :after, "David"],
|
@@ -702,21 +807,21 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
702
807
|
[:added, :after, "Bob"],
|
703
808
|
[:added, :before, "Lary"],
|
704
809
|
[:added, :after, "Lary"]
|
705
|
-
],log.last(6)
|
810
|
+
], log.last(6)
|
706
811
|
|
707
|
-
post.people_with_callbacks.build(:
|
812
|
+
post.people_with_callbacks.build(first_name: "Ted")
|
708
813
|
assert_equal [
|
709
814
|
[:added, :before, "Ted"],
|
710
815
|
[:added, :after, "Ted"]
|
711
816
|
], log.last(2)
|
712
817
|
|
713
|
-
post.people_with_callbacks.create(:
|
818
|
+
post.people_with_callbacks.create(first_name: "Sam")
|
714
819
|
assert_equal [
|
715
820
|
[:added, :before, "Sam"],
|
716
821
|
[:added, :after, "Sam"]
|
717
822
|
], log.last(2)
|
718
823
|
|
719
|
-
post.people_with_callbacks = [people(:michael),people(:david), Person.new(:
|
824
|
+
post.people_with_callbacks = [people(:michael), people(:david), Person.new(first_name: "Julian"), Person.create!(first_name: "Roger")]
|
720
825
|
assert_equal((%w(Ted Bob Sam Lary) * 2).sort, log[-12..-5].collect(&:last).sort)
|
721
826
|
assert_equal [
|
722
827
|
[:added, :before, "Julian"],
|
@@ -724,12 +829,24 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
724
829
|
[:added, :before, "Roger"],
|
725
830
|
[:added, :after, "Roger"]
|
726
831
|
], log.last(4)
|
832
|
+
|
833
|
+
post.people_with_callbacks.build { |person| person.first_name = "Ted" }
|
834
|
+
assert_equal [
|
835
|
+
[:added, :before, "Ted"],
|
836
|
+
[:added, :after, "Ted"]
|
837
|
+
], log.last(2)
|
838
|
+
|
839
|
+
post.people_with_callbacks.create { |person| person.first_name = "Sam" }
|
840
|
+
assert_equal [
|
841
|
+
[:added, :before, "Sam"],
|
842
|
+
[:added, :after, "Sam"]
|
843
|
+
], log.last(2)
|
727
844
|
end
|
728
845
|
|
729
846
|
def test_dynamic_find_should_respect_association_include
|
730
847
|
# SQL error in sort clause if :include is not included
|
731
848
|
# due to Unknown column 'comments.id'
|
732
|
-
assert Person.find(1).posts_with_comments_sorted_by_comment_id.find_by_title(
|
849
|
+
assert Person.find(1).posts_with_comments_sorted_by_comment_id.find_by_title("Welcome to the weblog")
|
733
850
|
end
|
734
851
|
|
735
852
|
def test_count_with_include_should_alias_join_table
|
@@ -745,7 +862,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
745
862
|
end
|
746
863
|
|
747
864
|
def test_get_ids_for_has_many_through_with_conditions_should_not_preload
|
748
|
-
Tagging.create!(:
|
865
|
+
Tagging.create!(taggable_type: "Post", taggable_id: posts(:welcome).id, tag: tags(:misc))
|
749
866
|
assert_not_called(ActiveRecord::Associations::Preloader, :new) do
|
750
867
|
posts(:welcome).misc_tag_ids
|
751
868
|
end
|
@@ -754,7 +871,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
754
871
|
def test_get_ids_for_loaded_associations
|
755
872
|
person = people(:michael)
|
756
873
|
person.posts.reload
|
757
|
-
|
874
|
+
assert_no_queries do
|
758
875
|
person.post_ids
|
759
876
|
person.post_ids
|
760
877
|
end
|
@@ -762,9 +879,9 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
762
879
|
|
763
880
|
def test_get_ids_for_unloaded_associations_does_not_load_them
|
764
881
|
person = people(:michael)
|
765
|
-
|
882
|
+
assert_not_predicate person.posts, :loaded?
|
766
883
|
assert_equal [posts(:welcome).id, posts(:authorless).id].sort, person.post_ids.sort
|
767
|
-
|
884
|
+
assert_not_predicate person.posts, :loaded?
|
768
885
|
end
|
769
886
|
|
770
887
|
def test_association_proxy_transaction_method_starts_transaction_in_association_class
|
@@ -776,16 +893,16 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
776
893
|
end
|
777
894
|
|
778
895
|
def test_has_many_association_through_a_belongs_to_association_where_the_association_doesnt_exist
|
779
|
-
post = Post.create!(:
|
896
|
+
post = Post.create!(title: "TITLE", body: "BODY")
|
780
897
|
assert_equal [], post.author_favorites
|
781
898
|
end
|
782
899
|
|
783
900
|
def test_has_many_association_through_a_belongs_to_association
|
784
901
|
author = authors(:mary)
|
785
|
-
post = Post.create!(:
|
786
|
-
author.author_favorites.create(:
|
787
|
-
author.author_favorites.create(:
|
788
|
-
author.author_favorites.create(:
|
902
|
+
post = Post.create!(author: author, title: "TITLE", body: "BODY")
|
903
|
+
author.author_favorites.create(favorite_author_id: 1)
|
904
|
+
author.author_favorites.create(favorite_author_id: 2)
|
905
|
+
author.author_favorites.create(favorite_author_id: 3)
|
789
906
|
assert_equal post.author.author_favorites, post.author_favorites
|
790
907
|
end
|
791
908
|
|
@@ -809,37 +926,37 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
809
926
|
|
810
927
|
def test_modifying_has_many_through_has_one_reflection_should_raise
|
811
928
|
[
|
812
|
-
lambda { authors(:david).very_special_comments = [VerySpecialComment.create!(:
|
813
|
-
lambda { authors(:david).very_special_comments << VerySpecialComment.create!(:
|
929
|
+
lambda { authors(:david).very_special_comments = [VerySpecialComment.create!(body: "Gorp!", post_id: 1011), VerySpecialComment.create!(body: "Eep!", post_id: 1012)] },
|
930
|
+
lambda { authors(:david).very_special_comments << VerySpecialComment.create!(body: "Hoohah!", post_id: 1013) },
|
814
931
|
lambda { authors(:david).very_special_comments.delete(authors(:david).very_special_comments.first) },
|
815
|
-
].each {|block| assert_raise(ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection, &block) }
|
932
|
+
].each { |block| assert_raise(ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection, &block) }
|
816
933
|
end
|
817
934
|
|
818
935
|
def test_has_many_association_through_a_has_many_association_to_self
|
819
|
-
sarah = Person.create!(:
|
820
|
-
john = Person.create!(:
|
936
|
+
sarah = Person.create!(first_name: "Sarah", primary_contact_id: people(:susan).id, gender: "F", number1_fan_id: 1)
|
937
|
+
john = Person.create!(first_name: "John", primary_contact_id: sarah.id, gender: "M", number1_fan_id: 1)
|
821
938
|
assert_equal sarah.agents, [john]
|
822
|
-
assert_equal people(:susan).agents.flat_map(&:agents), people(:susan).agents_of_agents
|
939
|
+
assert_equal people(:susan).agents.flat_map(&:agents).sort, people(:susan).agents_of_agents.sort
|
823
940
|
end
|
824
941
|
|
825
942
|
def test_associate_existing_with_nonstandard_primary_key_on_belongs_to
|
826
|
-
Categorization.create(:
|
943
|
+
Categorization.create(author: authors(:mary), named_category_name: categories(:general).name)
|
827
944
|
assert_equal categories(:general), authors(:mary).named_categories.first
|
828
945
|
end
|
829
946
|
|
830
947
|
def test_collection_build_with_nonstandard_primary_key_on_belongs_to
|
831
948
|
author = authors(:mary)
|
832
|
-
category = author.named_categories.build(:
|
949
|
+
category = author.named_categories.build(name: "Primary")
|
833
950
|
author.save
|
834
|
-
assert Categorization.exists?(:
|
835
|
-
|
951
|
+
assert Categorization.exists?(author_id: author.id, named_category_name: category.name)
|
952
|
+
assert_includes author.named_categories.reload, category
|
836
953
|
end
|
837
954
|
|
838
955
|
def test_collection_create_with_nonstandard_primary_key_on_belongs_to
|
839
956
|
author = authors(:mary)
|
840
|
-
category = author.named_categories.create(:
|
841
|
-
assert Categorization.exists?(:
|
842
|
-
|
957
|
+
category = author.named_categories.create(name: "Primary")
|
958
|
+
assert Categorization.exists?(author_id: author.id, named_category_name: category.name)
|
959
|
+
assert_includes author.named_categories.reload, category
|
843
960
|
end
|
844
961
|
|
845
962
|
def test_collection_exists
|
@@ -851,10 +968,10 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
851
968
|
|
852
969
|
def test_collection_delete_with_nonstandard_primary_key_on_belongs_to
|
853
970
|
author = authors(:mary)
|
854
|
-
category = author.named_categories.create(:
|
971
|
+
category = author.named_categories.create(name: "Primary")
|
855
972
|
author.named_categories.delete(category)
|
856
|
-
|
857
|
-
|
973
|
+
assert_not Categorization.exists?(author_id: author.id, named_category_name: category.name)
|
974
|
+
assert_empty author.named_categories.reload
|
858
975
|
end
|
859
976
|
|
860
977
|
def test_collection_singular_ids_getter_with_string_primary_keys
|
@@ -871,6 +988,14 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
871
988
|
assert_equal [dev], company.developers
|
872
989
|
end
|
873
990
|
|
991
|
+
def test_collection_singular_ids_setter_with_required_type_cast
|
992
|
+
company = companies(:rails_core)
|
993
|
+
dev = Developer.first
|
994
|
+
|
995
|
+
company.developer_ids = [dev.id.to_s]
|
996
|
+
assert_equal [dev], company.developers
|
997
|
+
end
|
998
|
+
|
874
999
|
def test_collection_singular_ids_setter_with_string_primary_keys
|
875
1000
|
assert_nothing_raised do
|
876
1001
|
book = books(:awdr)
|
@@ -880,34 +1005,35 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
880
1005
|
book.subscriber_ids = []
|
881
1006
|
assert_equal [], book.subscribers.reload
|
882
1007
|
end
|
883
|
-
|
884
1008
|
end
|
885
1009
|
|
886
1010
|
def test_collection_singular_ids_setter_raises_exception_when_invalid_ids_set
|
887
1011
|
company = companies(:rails_core)
|
888
1012
|
ids = [Developer.first.id, -9999]
|
889
1013
|
e = assert_raises(ActiveRecord::RecordNotFound) { company.developer_ids = ids }
|
890
|
-
|
1014
|
+
msg = "Couldn't find all Developers with 'id': (1, -9999) (found 1 results, but was looking for 2). Couldn't find Developer with id -9999."
|
1015
|
+
assert_equal(msg, e.message)
|
891
1016
|
end
|
892
1017
|
|
893
1018
|
def test_collection_singular_ids_through_setter_raises_exception_when_invalid_ids_set
|
894
1019
|
author = authors(:david)
|
895
1020
|
ids = [categories(:general).name, "Unknown"]
|
896
1021
|
e = assert_raises(ActiveRecord::RecordNotFound) { author.essay_category_ids = ids }
|
897
|
-
|
1022
|
+
msg = "Couldn't find all Categories with 'name': (General, Unknown) (found 1 results, but was looking for 2). Couldn't find Category with name Unknown."
|
1023
|
+
assert_equal msg, e.message
|
898
1024
|
end
|
899
1025
|
|
900
1026
|
def test_build_a_model_from_hm_through_association_with_where_clause
|
901
|
-
assert_nothing_raised { books(:awdr).subscribers.where(:
|
1027
|
+
assert_nothing_raised { books(:awdr).subscribers.where(nick: "marklazz").build }
|
902
1028
|
end
|
903
1029
|
|
904
1030
|
def test_attributes_are_being_set_when_initialized_from_hm_through_association_with_where_clause
|
905
|
-
new_subscriber = books(:awdr).subscribers.where(:
|
1031
|
+
new_subscriber = books(:awdr).subscribers.where(nick: "marklazz").build
|
906
1032
|
assert_equal new_subscriber.nick, "marklazz"
|
907
1033
|
end
|
908
1034
|
|
909
1035
|
def test_attributes_are_being_set_when_initialized_from_hm_through_association_with_multiple_where_clauses
|
910
|
-
new_subscriber = books(:awdr).subscribers.where(:
|
1036
|
+
new_subscriber = books(:awdr).subscribers.where(nick: "marklazz").where(name: "Marcelo Giorgi").build
|
911
1037
|
assert_equal new_subscriber.nick, "marklazz"
|
912
1038
|
assert_equal new_subscriber.name, "Marcelo Giorgi"
|
913
1039
|
end
|
@@ -916,19 +1042,19 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
916
1042
|
person = Person.new
|
917
1043
|
reference = person.references.build
|
918
1044
|
job = reference.build_job
|
919
|
-
|
1045
|
+
assert_includes person.jobs, job
|
920
1046
|
end
|
921
1047
|
|
922
1048
|
def test_include_method_in_association_through_should_return_true_for_instance_added_with_nested_builds
|
923
1049
|
author = Author.new
|
924
1050
|
post = author.posts.build
|
925
1051
|
comment = post.comments.build
|
926
|
-
|
1052
|
+
assert_includes author.comments, comment
|
927
1053
|
end
|
928
1054
|
|
929
1055
|
def test_through_association_readonly_should_be_false
|
930
|
-
|
931
|
-
|
1056
|
+
assert_not_predicate people(:michael).posts.first, :readonly?
|
1057
|
+
assert_not_predicate people(:michael).posts.to_a.first, :readonly?
|
932
1058
|
end
|
933
1059
|
|
934
1060
|
def test_can_update_through_association
|
@@ -937,10 +1063,50 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
937
1063
|
end
|
938
1064
|
end
|
939
1065
|
|
1066
|
+
def test_has_many_through_with_source_scope
|
1067
|
+
expected = [readers(:michael_welcome).becomes(LazyReader)]
|
1068
|
+
assert_equal expected, Author.first.lazy_readers_skimmers_or_not
|
1069
|
+
assert_equal expected, Author.preload(:lazy_readers_skimmers_or_not).first.lazy_readers_skimmers_or_not
|
1070
|
+
assert_equal expected, Author.eager_load(:lazy_readers_skimmers_or_not).first.lazy_readers_skimmers_or_not
|
1071
|
+
end
|
1072
|
+
|
1073
|
+
def test_has_many_through_with_through_scope_with_includes
|
1074
|
+
expected = [readers(:bob_welcome).becomes(LazyReader)]
|
1075
|
+
assert_equal expected, Author.last.lazy_readers_skimmers_or_not_2
|
1076
|
+
assert_equal expected, Author.preload(:lazy_readers_skimmers_or_not_2).last.lazy_readers_skimmers_or_not_2
|
1077
|
+
assert_equal expected, Author.eager_load(:lazy_readers_skimmers_or_not_2).last.lazy_readers_skimmers_or_not_2
|
1078
|
+
end
|
1079
|
+
|
1080
|
+
def test_has_many_through_with_through_scope_with_joins
|
1081
|
+
expected = [readers(:bob_welcome).becomes(LazyReader)]
|
1082
|
+
assert_equal expected, Author.last.lazy_readers_skimmers_or_not_3
|
1083
|
+
assert_equal expected, Author.preload(:lazy_readers_skimmers_or_not_3).last.lazy_readers_skimmers_or_not_3
|
1084
|
+
assert_equal expected, Author.eager_load(:lazy_readers_skimmers_or_not_3).last.lazy_readers_skimmers_or_not_3
|
1085
|
+
end
|
1086
|
+
|
1087
|
+
def test_duplicated_has_many_through_with_through_scope_with_joins
|
1088
|
+
Categorization.create!(author: authors(:david), post: posts(:thinking), category: categories(:technology))
|
1089
|
+
|
1090
|
+
expected = [categorizations(:david_welcome_general)]
|
1091
|
+
assert_equal expected, Author.preload(:general_posts, :general_categorizations).first.general_categorizations
|
1092
|
+
assert_equal expected, Author.eager_load(:general_posts, :general_categorizations).first.general_categorizations
|
1093
|
+
|
1094
|
+
expected = [posts(:welcome)]
|
1095
|
+
assert_equal expected, Author.preload(:general_categorizations, :general_posts).first.general_posts
|
1096
|
+
assert_equal expected, Author.eager_load(:general_categorizations, :general_posts).first.general_posts
|
1097
|
+
end
|
1098
|
+
|
1099
|
+
def test_has_many_through_polymorphic_with_rewhere
|
1100
|
+
post = TaggedPost.create!(title: "Tagged", body: "Post")
|
1101
|
+
tag = post.tags.create!(name: "Tag")
|
1102
|
+
assert_equal [tag], TaggedPost.preload(:tags).last.tags
|
1103
|
+
assert_equal [tag], TaggedPost.eager_load(:tags).last.tags
|
1104
|
+
end
|
1105
|
+
|
940
1106
|
def test_has_many_through_polymorphic_with_primary_key_option
|
941
1107
|
assert_equal [categories(:general)], authors(:david).essay_categories
|
942
1108
|
|
943
|
-
authors = Author.joins(:essay_categories).where(
|
1109
|
+
authors = Author.joins(:essay_categories).where("categories.id" => categories(:general).id)
|
944
1110
|
assert_equal authors(:david), authors.first
|
945
1111
|
|
946
1112
|
assert_equal [owners(:blackbeard)], authors(:david).essay_owners
|
@@ -952,7 +1118,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
952
1118
|
def test_has_many_through_with_primary_key_option
|
953
1119
|
assert_equal [categories(:general)], authors(:david).essay_categories_2
|
954
1120
|
|
955
|
-
authors = Author.joins(:essay_categories_2).where(
|
1121
|
+
authors = Author.joins(:essay_categories_2).where("categories.id" => categories(:general).id)
|
956
1122
|
assert_equal authors(:david), authors.first
|
957
1123
|
end
|
958
1124
|
|
@@ -964,30 +1130,30 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
964
1130
|
end
|
965
1131
|
|
966
1132
|
def test_has_many_through_with_default_scope_on_join_model
|
967
|
-
assert_equal posts(:welcome).comments.order(
|
1133
|
+
assert_equal posts(:welcome).comments.order("id").to_a, authors(:david).comments_on_first_posts
|
968
1134
|
end
|
969
1135
|
|
970
1136
|
def test_create_has_many_through_with_default_scope_on_join_model
|
971
|
-
category = authors(:david).special_categories.create(:
|
972
|
-
assert_equal 1, category.categorizations.where(:
|
1137
|
+
category = authors(:david).special_categories.create(name: "Foo")
|
1138
|
+
assert_equal 1, category.categorizations.where(special: true).count
|
973
1139
|
end
|
974
1140
|
|
975
1141
|
def test_joining_has_many_through_with_distinct
|
976
|
-
mary = Author.joins(:unique_categorized_posts).where(:
|
1142
|
+
mary = Author.joins(:unique_categorized_posts).where(id: authors(:mary).id).first
|
977
1143
|
assert_equal 1, mary.unique_categorized_posts.length
|
978
1144
|
assert_equal 1, mary.unique_categorized_post_ids.length
|
979
1145
|
end
|
980
1146
|
|
981
1147
|
def test_joining_has_many_through_belongs_to
|
982
|
-
posts = Post.joins(:author_categorizations).order(
|
983
|
-
where(
|
1148
|
+
posts = Post.joins(:author_categorizations).order("posts.id").
|
1149
|
+
where("categorizations.id" => categorizations(:mary_thinking_sti).id)
|
984
1150
|
|
985
1151
|
assert_equal [posts(:eager_other), posts(:misc_by_mary), posts(:other_by_mary)], posts
|
986
1152
|
end
|
987
1153
|
|
988
1154
|
def test_select_chosen_fields_only
|
989
1155
|
author = authors(:david)
|
990
|
-
assert_equal [
|
1156
|
+
assert_equal ["body", "id"].sort, author.comments.select("comments.body").first.attributes.keys.sort
|
991
1157
|
end
|
992
1158
|
|
993
1159
|
def test_get_has_many_through_belongs_to_ids_with_conditions
|
@@ -1010,12 +1176,12 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
1010
1176
|
post.author_categorizations
|
1011
1177
|
proxy = post.send(:association_instance_get, :author_categorizations)
|
1012
1178
|
|
1013
|
-
|
1179
|
+
assert_not_predicate proxy, :stale_target?
|
1014
1180
|
assert_equal authors(:mary).categorizations.sort_by(&:id), post.author_categorizations.sort_by(&:id)
|
1015
1181
|
|
1016
1182
|
post.author_id = authors(:david).id
|
1017
1183
|
|
1018
|
-
|
1184
|
+
assert_predicate proxy, :stale_target?
|
1019
1185
|
assert_equal authors(:david).categorizations.sort_by(&:id), post.author_categorizations.sort_by(&:id)
|
1020
1186
|
end
|
1021
1187
|
|
@@ -1030,15 +1196,15 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
1030
1196
|
post = posts(:welcome)
|
1031
1197
|
address = author_addresses(:david_address)
|
1032
1198
|
|
1033
|
-
|
1199
|
+
assert_includes post.author_addresses, address
|
1034
1200
|
post.author_addresses.delete(address)
|
1035
|
-
|
1201
|
+
assert_predicate post[:author_count], :nil?
|
1036
1202
|
end
|
1037
1203
|
|
1038
1204
|
def test_primary_key_option_on_source
|
1039
1205
|
post = posts(:welcome)
|
1040
1206
|
category = categories(:general)
|
1041
|
-
Categorization.create!(:
|
1207
|
+
Categorization.create!(post_id: post.id, named_category_name: category.name)
|
1042
1208
|
|
1043
1209
|
assert_equal [category], post.named_categories
|
1044
1210
|
assert_equal [category.name], post.named_category_ids # checks when target loaded
|
@@ -1047,48 +1213,48 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
1047
1213
|
|
1048
1214
|
def test_create_should_not_raise_exception_when_join_record_has_errors
|
1049
1215
|
repair_validations(Categorization) do
|
1050
|
-
Categorization.validate { |r| r.errors[:base] <<
|
1051
|
-
Category.create(:
|
1216
|
+
Categorization.validate { |r| r.errors[:base] << "Invalid Categorization" }
|
1217
|
+
assert_deprecated { Category.create(name: "Fishing", authors: [Author.first]) }
|
1052
1218
|
end
|
1053
1219
|
end
|
1054
1220
|
|
1055
1221
|
def test_assign_array_to_new_record_builds_join_records
|
1056
|
-
c = Category.new(:
|
1222
|
+
c = Category.new(name: "Fishing", authors: [Author.first])
|
1057
1223
|
assert_equal 1, c.categorizations.size
|
1058
1224
|
end
|
1059
1225
|
|
1060
1226
|
def test_create_bang_should_raise_exception_when_join_record_has_errors
|
1061
1227
|
repair_validations(Categorization) do
|
1062
|
-
Categorization.validate { |r| r.errors[:base] <<
|
1228
|
+
Categorization.validate { |r| r.errors[:base] << "Invalid Categorization" }
|
1063
1229
|
assert_raises(ActiveRecord::RecordInvalid) do
|
1064
|
-
Category.create!(:
|
1230
|
+
assert_deprecated { Category.create!(name: "Fishing", authors: [Author.first]) }
|
1065
1231
|
end
|
1066
1232
|
end
|
1067
1233
|
end
|
1068
1234
|
|
1069
1235
|
def test_save_bang_should_raise_exception_when_join_record_has_errors
|
1070
1236
|
repair_validations(Categorization) do
|
1071
|
-
Categorization.validate { |r| r.errors[:base] <<
|
1072
|
-
c = Category.new(:
|
1237
|
+
Categorization.validate { |r| r.errors[:base] << "Invalid Categorization" }
|
1238
|
+
c = Category.new(name: "Fishing", authors: [Author.first])
|
1073
1239
|
assert_raises(ActiveRecord::RecordInvalid) do
|
1074
|
-
c.save!
|
1240
|
+
assert_deprecated { c.save! }
|
1075
1241
|
end
|
1076
1242
|
end
|
1077
1243
|
end
|
1078
1244
|
|
1079
1245
|
def test_save_returns_falsy_when_join_record_has_errors
|
1080
1246
|
repair_validations(Categorization) do
|
1081
|
-
Categorization.validate { |r| r.errors[:base] <<
|
1082
|
-
c = Category.new(:
|
1083
|
-
assert_not c.save
|
1247
|
+
Categorization.validate { |r| r.errors[:base] << "Invalid Categorization" }
|
1248
|
+
c = Category.new(name: "Fishing", authors: [Author.first])
|
1249
|
+
assert_deprecated { assert_not c.save }
|
1084
1250
|
end
|
1085
1251
|
end
|
1086
1252
|
|
1087
1253
|
def test_preloading_empty_through_association_via_joins
|
1088
|
-
person = Person.create!(:
|
1089
|
-
person = Person.where(:
|
1254
|
+
person = Person.create!(first_name: "Gaga")
|
1255
|
+
person = Person.where(id: person.id).where("readers.id = 1 or 1=1").references(:readers).includes(:posts).to_a.first
|
1090
1256
|
|
1091
|
-
assert person.posts.loaded?,
|
1257
|
+
assert person.posts.loaded?, "person.posts should be loaded"
|
1092
1258
|
assert_equal [], person.posts
|
1093
1259
|
end
|
1094
1260
|
|
@@ -1109,13 +1275,13 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
1109
1275
|
end
|
1110
1276
|
|
1111
1277
|
def test_has_many_through_with_polymorphic_source
|
1112
|
-
post = tags(:general).tagged_posts.create! :
|
1278
|
+
post = tags(:general).tagged_posts.create! title: "foo", body: "bar"
|
1113
1279
|
assert_equal [tags(:general)], post.reload.tags
|
1114
1280
|
end
|
1115
1281
|
|
1116
1282
|
def test_has_many_through_obeys_order_on_through_association
|
1117
1283
|
owner = owners(:blackbeard)
|
1118
|
-
|
1284
|
+
assert_includes owner.toys.to_sql, "pets.name desc"
|
1119
1285
|
assert_equal ["parrot", "bulbul"], owner.toys.map { |r| r.pet.name }
|
1120
1286
|
end
|
1121
1287
|
|
@@ -1148,9 +1314,9 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
1148
1314
|
def test_has_many_through_associations_on_new_records_use_null_relations
|
1149
1315
|
person = Person.new
|
1150
1316
|
|
1151
|
-
assert_no_queries
|
1317
|
+
assert_no_queries do
|
1152
1318
|
assert_equal [], person.posts
|
1153
|
-
assert_equal [], person.posts.where(body:
|
1319
|
+
assert_equal [], person.posts.where(body: "omg")
|
1154
1320
|
assert_equal [], person.posts.pluck(:body)
|
1155
1321
|
assert_equal 0, person.posts.sum(:tags_count)
|
1156
1322
|
assert_equal 0, person.posts.count
|
@@ -1182,9 +1348,9 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
1182
1348
|
end
|
1183
1349
|
|
1184
1350
|
def test_has_many_through_unscope_default_scope
|
1185
|
-
post = Post.create!(:
|
1186
|
-
Reader.create! :
|
1187
|
-
LazyReader.create! :
|
1351
|
+
post = Post.create!(title: "Beaches", body: "I like beaches!")
|
1352
|
+
Reader.create! person: people(:david), post: post
|
1353
|
+
LazyReader.create! person: people(:susan), post: post
|
1188
1354
|
|
1189
1355
|
assert_equal 2, post.people.to_a.size
|
1190
1356
|
assert_equal 1, post.lazy_people.to_a.size
|
@@ -1194,8 +1360,8 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
1194
1360
|
end
|
1195
1361
|
|
1196
1362
|
def test_has_many_through_add_with_sti_middle_relation
|
1197
|
-
club = SuperClub.create!(name:
|
1198
|
-
member = Member.create!(name:
|
1363
|
+
club = SuperClub.create!(name: "Fight Club")
|
1364
|
+
member = Member.create!(name: "Tyler Durden")
|
1199
1365
|
|
1200
1366
|
club.members << member
|
1201
1367
|
assert_equal 1, SuperMembership.where(member_id: member.id, club_id: club.id).count
|
@@ -1216,12 +1382,6 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
1216
1382
|
assert_nil Club.new.special_favourites.distinct_value
|
1217
1383
|
end
|
1218
1384
|
|
1219
|
-
def test_association_force_reload_with_only_true_is_deprecated
|
1220
|
-
post = Post.find(1)
|
1221
|
-
|
1222
|
-
assert_deprecated { post.people(true) }
|
1223
|
-
end
|
1224
|
-
|
1225
1385
|
def test_has_many_through_do_not_cache_association_reader_if_the_though_method_has_default_scopes
|
1226
1386
|
member = Member.create!
|
1227
1387
|
club = Club.create!
|
@@ -1250,6 +1410,33 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
1250
1410
|
TenantMembership.current_member = nil
|
1251
1411
|
end
|
1252
1412
|
|
1413
|
+
def test_has_many_through_with_scope_that_has_joined_same_table_with_parent_relation
|
1414
|
+
assert_equal authors(:david), Author.joins(:comments_for_first_author).take
|
1415
|
+
end
|
1416
|
+
|
1417
|
+
def test_has_many_through_with_left_joined_same_table_with_through_table
|
1418
|
+
assert_equal [comments(:eager_other_comment1)], authors(:mary).comments.left_joins(:post)
|
1419
|
+
end
|
1420
|
+
|
1421
|
+
def test_has_many_through_with_unscope_should_affect_to_through_scope
|
1422
|
+
assert_equal [comments(:eager_other_comment1)], authors(:mary).unordered_comments
|
1423
|
+
end
|
1424
|
+
|
1425
|
+
def test_has_many_through_with_scope_should_accept_string_and_hash_join
|
1426
|
+
assert_equal authors(:david), Author.joins({ comments_for_first_author: :post }, "inner join posts posts_alias on authors.id = posts_alias.author_id").eager_load(:categories).take
|
1427
|
+
end
|
1428
|
+
|
1429
|
+
def test_has_many_through_with_scope_should_respect_table_alias
|
1430
|
+
family = Family.create!
|
1431
|
+
users = 3.times.map { User.create! }
|
1432
|
+
FamilyTree.create!(member: users[0], family: family)
|
1433
|
+
FamilyTree.create!(member: users[1], family: family)
|
1434
|
+
FamilyTree.create!(member: users[2], family: family, token: "wat")
|
1435
|
+
|
1436
|
+
assert_equal 2, users[0].family_members.to_a.size
|
1437
|
+
assert_equal 0, users[2].family_members.to_a.size
|
1438
|
+
end
|
1439
|
+
|
1253
1440
|
def test_through_scope_is_affected_by_unscoping
|
1254
1441
|
author = authors(:david)
|
1255
1442
|
|
@@ -1268,4 +1455,126 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
1268
1455
|
assert_equal expected.sort_by(&:id), author.comments_on_first_posts.sort_by(&:id)
|
1269
1456
|
end
|
1270
1457
|
end
|
1458
|
+
|
1459
|
+
def test_incorrectly_ordered_through_associations
|
1460
|
+
assert_raises(ActiveRecord::HasManyThroughOrderError) do
|
1461
|
+
DeveloperWithIncorrectlyOrderedHasManyThrough.create(
|
1462
|
+
companies: [Company.create]
|
1463
|
+
)
|
1464
|
+
end
|
1465
|
+
end
|
1466
|
+
|
1467
|
+
def test_has_many_through_update_ids_with_conditions
|
1468
|
+
author = Author.create!(name: "Bill")
|
1469
|
+
category = categories(:general)
|
1470
|
+
|
1471
|
+
author.update(
|
1472
|
+
special_categories_with_condition_ids: [category.id],
|
1473
|
+
nonspecial_categories_with_condition_ids: [category.id]
|
1474
|
+
)
|
1475
|
+
|
1476
|
+
assert_equal [category.id], author.special_categories_with_condition_ids
|
1477
|
+
assert_equal [category.id], author.nonspecial_categories_with_condition_ids
|
1478
|
+
|
1479
|
+
author.update(nonspecial_categories_with_condition_ids: [])
|
1480
|
+
author.reload
|
1481
|
+
|
1482
|
+
assert_equal [category.id], author.special_categories_with_condition_ids
|
1483
|
+
assert_equal [], author.nonspecial_categories_with_condition_ids
|
1484
|
+
end
|
1485
|
+
|
1486
|
+
def test_single_has_many_through_association_with_unpersisted_parent_instance
|
1487
|
+
post_with_single_has_many_through = Class.new(Post) do
|
1488
|
+
def self.name; "PostWithSingleHasManyThrough"; end
|
1489
|
+
has_many :subscriptions, through: :author
|
1490
|
+
end
|
1491
|
+
post = post_with_single_has_many_through.new
|
1492
|
+
|
1493
|
+
post.author = authors(:mary)
|
1494
|
+
book1 = Book.create!(name: "essays on single has many through associations 1")
|
1495
|
+
post.author.books << book1
|
1496
|
+
subscription1 = Subscription.first
|
1497
|
+
book1.subscriptions << subscription1
|
1498
|
+
assert_equal [subscription1], post.subscriptions.to_a
|
1499
|
+
|
1500
|
+
post.author = authors(:bob)
|
1501
|
+
book2 = Book.create!(name: "essays on single has many through associations 2")
|
1502
|
+
post.author.books << book2
|
1503
|
+
subscription2 = Subscription.second
|
1504
|
+
book2.subscriptions << subscription2
|
1505
|
+
assert_equal [subscription2], post.subscriptions.to_a
|
1506
|
+
end
|
1507
|
+
|
1508
|
+
def test_nested_has_many_through_association_with_unpersisted_parent_instance
|
1509
|
+
post_with_nested_has_many_through = Class.new(Post) do
|
1510
|
+
def self.name; "PostWithNestedHasManyThrough"; end
|
1511
|
+
has_many :books, through: :author
|
1512
|
+
has_many :subscriptions, through: :books
|
1513
|
+
end
|
1514
|
+
post = post_with_nested_has_many_through.new
|
1515
|
+
|
1516
|
+
post.author = authors(:mary)
|
1517
|
+
book1 = Book.create!(name: "essays on nested has many through associations 1")
|
1518
|
+
post.author.books << book1
|
1519
|
+
subscription1 = Subscription.first
|
1520
|
+
book1.subscriptions << subscription1
|
1521
|
+
assert_equal [subscription1], post.subscriptions.to_a
|
1522
|
+
|
1523
|
+
post.author = authors(:bob)
|
1524
|
+
book2 = Book.create!(name: "essays on nested has many through associations 2")
|
1525
|
+
post.author.books << book2
|
1526
|
+
subscription2 = Subscription.second
|
1527
|
+
book2.subscriptions << subscription2
|
1528
|
+
assert_equal [subscription2], post.subscriptions.to_a
|
1529
|
+
end
|
1530
|
+
|
1531
|
+
def test_child_is_visible_to_join_model_in_add_association_callbacks
|
1532
|
+
[:before_add, :after_add].each do |callback_name|
|
1533
|
+
sentient_treasure = Class.new(Treasure) do
|
1534
|
+
def self.name; "SentientTreasure"; end
|
1535
|
+
|
1536
|
+
has_many :pet_treasures, foreign_key: :treasure_id, callback_name => :check_pet!
|
1537
|
+
has_many :pets, through: :pet_treasures
|
1538
|
+
|
1539
|
+
def check_pet!(added)
|
1540
|
+
raise "No pet!" if added.pet.nil?
|
1541
|
+
end
|
1542
|
+
end
|
1543
|
+
|
1544
|
+
treasure = sentient_treasure.new
|
1545
|
+
assert_nothing_raised { treasure.pets << pets(:mochi) }
|
1546
|
+
end
|
1547
|
+
end
|
1548
|
+
|
1549
|
+
def test_circular_autosave_association_correctly_saves_multiple_records
|
1550
|
+
cs180 = Seminar.new(name: "CS180")
|
1551
|
+
fall = Session.new(name: "Fall")
|
1552
|
+
sections = [
|
1553
|
+
cs180.sections.build(short_name: "A"),
|
1554
|
+
cs180.sections.build(short_name: "B"),
|
1555
|
+
]
|
1556
|
+
fall.sections << sections
|
1557
|
+
fall.save!
|
1558
|
+
fall.reload
|
1559
|
+
assert_equal sections, fall.sections.sort_by(&:id)
|
1560
|
+
end
|
1561
|
+
|
1562
|
+
private
|
1563
|
+
def make_model(name)
|
1564
|
+
Class.new(ActiveRecord::Base) { define_singleton_method(:name) { name } }
|
1565
|
+
end
|
1566
|
+
|
1567
|
+
def make_no_pk_hm_t
|
1568
|
+
lesson = make_model "Lesson"
|
1569
|
+
student = make_model "Student"
|
1570
|
+
|
1571
|
+
lesson_student = make_model "LessonStudent"
|
1572
|
+
lesson_student.table_name = "lessons_students"
|
1573
|
+
|
1574
|
+
lesson_student.belongs_to :lesson, anonymous_class: lesson
|
1575
|
+
lesson_student.belongs_to :student, anonymous_class: student
|
1576
|
+
lesson.has_many :lesson_students, anonymous_class: lesson_student
|
1577
|
+
lesson.has_many :students, through: :lesson_students, anonymous_class: student
|
1578
|
+
[lesson, lesson_student, student]
|
1579
|
+
end
|
1271
1580
|
end
|