ibm_db 5.2.0-x86-mingw32 → 5.3.2-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES +9 -0
- data/LICENSE +55 -18
- data/ext/Makefile +15 -13
- data/ext/ibm_db.c +62 -57
- 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 +1463 -1279
- data/lib/ibm_db.so +1 -0
- data/lib/mswin32/rb3x/i386/ruby30/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 +190 -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
|