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,61 +1,63 @@
|
|
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
|
31
|
-
require
|
32
|
-
require
|
33
|
-
require
|
34
|
-
require
|
35
|
-
require
|
36
|
-
require
|
37
|
-
require
|
38
|
-
require
|
39
|
-
require
|
40
|
-
require
|
4
|
+
require "models/developer"
|
5
|
+
require "models/computer"
|
6
|
+
require "models/project"
|
7
|
+
require "models/company"
|
8
|
+
require "models/contract"
|
9
|
+
require "models/topic"
|
10
|
+
require "models/reply"
|
11
|
+
require "models/category"
|
12
|
+
require "models/image"
|
13
|
+
require "models/post"
|
14
|
+
require "models/author"
|
15
|
+
require "models/essay"
|
16
|
+
require "models/comment"
|
17
|
+
require "models/person"
|
18
|
+
require "models/reader"
|
19
|
+
require "models/tagging"
|
20
|
+
require "models/tag"
|
21
|
+
require "models/invoice"
|
22
|
+
require "models/line_item"
|
23
|
+
require "models/car"
|
24
|
+
require "models/bulb"
|
25
|
+
require "models/engine"
|
26
|
+
require "models/categorization"
|
27
|
+
require "models/minivan"
|
28
|
+
require "models/speedometer"
|
29
|
+
require "models/reference"
|
30
|
+
require "models/job"
|
31
|
+
require "models/college"
|
32
|
+
require "models/student"
|
33
|
+
require "models/pirate"
|
34
|
+
require "models/ship"
|
35
|
+
require "models/ship_part"
|
36
|
+
require "models/treasure"
|
37
|
+
require "models/parrot"
|
38
|
+
require "models/tyre"
|
39
|
+
require "models/subscriber"
|
40
|
+
require "models/subscription"
|
41
|
+
require "models/zine"
|
42
|
+
require "models/interest"
|
41
43
|
|
42
44
|
class HasManyAssociationsTestForReorderWithJoinDependency < ActiveRecord::TestCase
|
43
|
-
fixtures :authors, :posts, :comments
|
45
|
+
fixtures :authors, :author_addresses, :posts, :comments
|
44
46
|
|
45
47
|
def test_should_generate_valid_sql
|
46
48
|
author = authors(:david)
|
47
49
|
# this can fail on adapters which require ORDER BY expressions to be included in the SELECT expression
|
48
50
|
# if the reorder clauses are not correctly handled
|
49
|
-
assert author.posts_with_comments_sorted_by_comment_id.where(
|
51
|
+
assert author.posts_with_comments_sorted_by_comment_id.where("comments.id > 0").reorder("posts.comments_count": :desc, "posts.tags_count": :desc).last
|
50
52
|
end
|
51
53
|
end
|
52
54
|
|
53
55
|
class HasManyAssociationsTestPrimaryKeys < ActiveRecord::TestCase
|
54
|
-
fixtures :authors, :essays, :subscribers, :subscriptions, :people
|
56
|
+
fixtures :authors, :author_addresses, :essays, :subscribers, :subscriptions, :people
|
55
57
|
|
56
58
|
def test_custom_primary_key_on_new_record_should_fetch_with_query
|
57
|
-
subscriber = Subscriber.new(nick:
|
58
|
-
|
59
|
+
subscriber = Subscriber.new(nick: "webster132")
|
60
|
+
assert_not_predicate subscriber.subscriptions, :loaded?
|
59
61
|
|
60
62
|
assert_queries 1 do
|
61
63
|
assert_equal 2, subscriber.subscriptions.size
|
@@ -65,8 +67,8 @@ class HasManyAssociationsTestPrimaryKeys < ActiveRecord::TestCase
|
|
65
67
|
end
|
66
68
|
|
67
69
|
def test_association_primary_key_on_new_record_should_fetch_with_query
|
68
|
-
author = Author.new(:
|
69
|
-
|
70
|
+
author = Author.new(name: "David")
|
71
|
+
assert_not_predicate author.essays, :loaded?
|
70
72
|
|
71
73
|
assert_queries 1 do
|
72
74
|
assert_equal 1, author.essays.size
|
@@ -95,13 +97,13 @@ class HasManyAssociationsTestPrimaryKeys < ActiveRecord::TestCase
|
|
95
97
|
david = people(:david)
|
96
98
|
|
97
99
|
assert_equal ["A Modest Proposal"], david.essays.map(&:name)
|
98
|
-
david.essays = [Essay.create!(name: "Remote Work"
|
100
|
+
david.essays = [Essay.create!(name: "Remote Work")]
|
99
101
|
assert_equal ["Remote Work"], david.essays.map(&:name)
|
100
102
|
end
|
101
103
|
|
102
104
|
def test_blank_custom_primary_key_on_new_record_should_not_run_queries
|
103
105
|
author = Author.new
|
104
|
-
|
106
|
+
assert_not_predicate author.essays, :loaded?
|
105
107
|
|
106
108
|
assert_queries 0 do
|
107
109
|
assert_equal 0, author.essays.size
|
@@ -111,8 +113,8 @@ end
|
|
111
113
|
|
112
114
|
class HasManyAssociationsTest < ActiveRecord::TestCase
|
113
115
|
fixtures :accounts, :categories, :companies, :developers, :projects,
|
114
|
-
:developers_projects, :topics, :authors, :comments,
|
115
|
-
:posts, :readers, :taggings, :cars, :
|
116
|
+
:developers_projects, :topics, :authors, :author_addresses, :comments,
|
117
|
+
:posts, :readers, :taggings, :cars, :tags,
|
116
118
|
:categorizations, :zines, :interests
|
117
119
|
|
118
120
|
def setup
|
@@ -127,14 +129,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
127
129
|
|
128
130
|
def test_anonymous_has_many
|
129
131
|
developer = Class.new(ActiveRecord::Base) {
|
130
|
-
self.table_name =
|
132
|
+
self.table_name = "developers"
|
131
133
|
dev = self
|
132
134
|
|
133
135
|
developer_project = Class.new(ActiveRecord::Base) {
|
134
|
-
self.table_name =
|
135
|
-
belongs_to :developer, :
|
136
|
+
self.table_name = "developers_projects"
|
137
|
+
belongs_to :developer, anonymous_class: dev
|
136
138
|
}
|
137
|
-
has_many :developer_projects, :
|
139
|
+
has_many :developer_projects, anonymous_class: developer_project, foreign_key: "developer_id"
|
138
140
|
}
|
139
141
|
dev = developer.first
|
140
142
|
named = Developer.find(dev.id)
|
@@ -146,20 +148,20 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
146
148
|
def test_default_scope_on_relations_is_not_cached
|
147
149
|
counter = 0
|
148
150
|
posts = Class.new(ActiveRecord::Base) {
|
149
|
-
self.table_name =
|
150
|
-
self.inheritance_column =
|
151
|
+
self.table_name = "posts"
|
152
|
+
self.inheritance_column = "not_there"
|
151
153
|
post = self
|
152
154
|
|
153
155
|
comments = Class.new(ActiveRecord::Base) {
|
154
|
-
self.table_name =
|
155
|
-
self.inheritance_column =
|
156
|
-
belongs_to :post, :
|
156
|
+
self.table_name = "comments"
|
157
|
+
self.inheritance_column = "not_there"
|
158
|
+
belongs_to :post, anonymous_class: post
|
157
159
|
default_scope -> {
|
158
160
|
counter += 1
|
159
|
-
where("id = :inc", :
|
161
|
+
where("id = :inc", inc: counter)
|
160
162
|
}
|
161
163
|
}
|
162
|
-
has_many :comments, :
|
164
|
+
has_many :comments, anonymous_class: comments, foreign_key: "post_id"
|
163
165
|
}
|
164
166
|
assert_equal 0, counter
|
165
167
|
post = posts.first
|
@@ -170,15 +172,15 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
170
172
|
end
|
171
173
|
|
172
174
|
def test_has_many_build_with_options
|
173
|
-
college = College.create(name:
|
174
|
-
Student.create(active: true, college_id: college.id, name:
|
175
|
+
college = College.create(name: "UFMT")
|
176
|
+
Student.create(active: true, college_id: college.id, name: "Sarah")
|
175
177
|
|
176
178
|
assert_equal college.students, Student.where(active: true, college_id: college.id)
|
177
179
|
end
|
178
180
|
|
179
181
|
def test_add_record_to_collection_should_change_its_updated_at
|
180
|
-
ship = Ship.create(name:
|
181
|
-
part = ShipPart.create(name:
|
182
|
+
ship = Ship.create(name: "dauntless")
|
183
|
+
part = ShipPart.create(name: "cockpit")
|
182
184
|
updated_at = part.updated_at
|
183
185
|
|
184
186
|
travel(1.second) do
|
@@ -192,80 +194,131 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
192
194
|
def test_clear_collection_should_not_change_updated_at
|
193
195
|
# GH#17161: .clear calls delete_all (and returns the association),
|
194
196
|
# which is intended to not touch associated objects's updated_at field
|
195
|
-
ship = Ship.create(name:
|
196
|
-
part = ShipPart.create(name:
|
197
|
+
ship = Ship.create(name: "dauntless")
|
198
|
+
part = ShipPart.create(name: "cockpit", ship_id: ship.id)
|
197
199
|
|
198
200
|
ship.parts.clear
|
199
201
|
part.reload
|
200
202
|
|
201
|
-
|
202
|
-
|
203
|
+
assert_nil part.ship
|
204
|
+
assert_not_predicate part, :updated_at_changed?
|
203
205
|
end
|
204
206
|
|
205
207
|
def test_create_from_association_should_respect_default_scope
|
206
|
-
car = Car.create(:
|
207
|
-
assert_equal
|
208
|
+
car = Car.create(name: "honda")
|
209
|
+
assert_equal "honda", car.name
|
208
210
|
|
209
211
|
bulb = Bulb.create
|
210
|
-
assert_equal
|
212
|
+
assert_equal "defaulty", bulb.name
|
211
213
|
|
212
214
|
bulb = car.bulbs.build
|
213
|
-
assert_equal
|
215
|
+
assert_equal "defaulty", bulb.name
|
214
216
|
|
215
217
|
bulb = car.bulbs.create
|
216
|
-
assert_equal
|
218
|
+
assert_equal "defaulty", bulb.name
|
219
|
+
|
220
|
+
bulb = car.bulbs.create!
|
221
|
+
assert_equal "defaulty", bulb.name
|
217
222
|
end
|
218
223
|
|
219
224
|
def test_build_and_create_from_association_should_respect_passed_attributes_over_default_scope
|
220
|
-
car = Car.create(name:
|
225
|
+
car = Car.create(name: "honda")
|
226
|
+
|
227
|
+
bulb = car.bulbs.where(name: "exotic").build
|
228
|
+
assert_equal "exotic", bulb.name
|
229
|
+
assert_nil bulb.count_after_create
|
230
|
+
|
231
|
+
bulb = car.bulbs.where(name: "exotic").create
|
232
|
+
assert_equal "exotic", bulb.name
|
233
|
+
assert_equal 1, bulb.count_after_create
|
234
|
+
|
235
|
+
bulb = car.bulbs.where(name: "exotic").create!
|
236
|
+
assert_equal "exotic", bulb.name
|
237
|
+
assert_equal 2, bulb.count_after_create
|
238
|
+
|
239
|
+
bulb = car.bulbs.build(name: "exotic")
|
240
|
+
assert_equal "exotic", bulb.name
|
221
241
|
|
222
|
-
bulb = car.bulbs.
|
223
|
-
assert_equal
|
242
|
+
bulb = car.bulbs.create(name: "exotic")
|
243
|
+
assert_equal "exotic", bulb.name
|
224
244
|
|
225
|
-
bulb = car.bulbs.create(name:
|
226
|
-
assert_equal
|
245
|
+
bulb = car.bulbs.create!(name: "exotic")
|
246
|
+
assert_equal "exotic", bulb.name
|
227
247
|
|
228
248
|
bulb = car.awesome_bulbs.build(frickinawesome: false)
|
229
249
|
assert_equal false, bulb.frickinawesome
|
230
250
|
|
231
251
|
bulb = car.awesome_bulbs.create(frickinawesome: false)
|
232
252
|
assert_equal false, bulb.frickinawesome
|
253
|
+
|
254
|
+
bulb = car.awesome_bulbs.create!(frickinawesome: false)
|
255
|
+
assert_equal false, bulb.frickinawesome
|
256
|
+
end
|
257
|
+
|
258
|
+
def test_build_and_create_from_association_should_respect_unscope_over_default_scope
|
259
|
+
car = Car.create(name: "honda")
|
260
|
+
|
261
|
+
bulb = car.bulbs.unscope(where: :name).build
|
262
|
+
assert_nil bulb.name
|
263
|
+
|
264
|
+
bulb = car.bulbs.unscope(where: :name).create
|
265
|
+
assert_nil bulb.name
|
266
|
+
|
267
|
+
bulb = car.bulbs.unscope(where: :name).create!
|
268
|
+
assert_nil bulb.name
|
269
|
+
|
270
|
+
bulb = car.awesome_bulbs.unscope(where: :frickinawesome).build
|
271
|
+
assert_equal false, bulb.frickinawesome
|
272
|
+
|
273
|
+
bulb = car.awesome_bulbs.unscope(where: :frickinawesome).create
|
274
|
+
assert_equal false, bulb.frickinawesome
|
275
|
+
|
276
|
+
bulb = car.awesome_bulbs.unscope(where: :frickinawesome).create!
|
277
|
+
assert_equal false, bulb.frickinawesome
|
233
278
|
end
|
234
279
|
|
235
280
|
def test_build_from_association_should_respect_scope
|
236
281
|
author = Author.new
|
237
282
|
|
238
283
|
post = author.thinking_posts.build
|
239
|
-
assert_equal
|
284
|
+
assert_equal "So I was thinking", post.title
|
240
285
|
end
|
241
286
|
|
242
287
|
def test_create_from_association_with_nil_values_should_work
|
243
|
-
car = Car.create(:
|
288
|
+
car = Car.create(name: "honda")
|
244
289
|
|
245
290
|
bulb = car.bulbs.new(nil)
|
246
|
-
assert_equal
|
291
|
+
assert_equal "defaulty", bulb.name
|
247
292
|
|
248
293
|
bulb = car.bulbs.build(nil)
|
249
|
-
assert_equal
|
294
|
+
assert_equal "defaulty", bulb.name
|
250
295
|
|
251
296
|
bulb = car.bulbs.create(nil)
|
252
|
-
assert_equal
|
297
|
+
assert_equal "defaulty", bulb.name
|
298
|
+
end
|
299
|
+
|
300
|
+
def test_build_from_association_sets_inverse_instance
|
301
|
+
car = Car.new(name: "honda")
|
302
|
+
|
303
|
+
bulb = car.bulbs.build
|
304
|
+
assert_equal car, bulb.car
|
253
305
|
end
|
254
306
|
|
255
307
|
def test_do_not_call_callbacks_for_delete_all
|
256
|
-
car = Car.create(:
|
308
|
+
car = Car.create(name: "honda")
|
257
309
|
car.funky_bulbs.create!
|
258
|
-
|
259
|
-
assert_equal
|
310
|
+
assert_equal 1, car.funky_bulbs.count
|
311
|
+
assert_equal 1, car.reload.funky_bulbs.delete_all
|
312
|
+
assert_equal 0, car.funky_bulbs.count, "bulbs should have been deleted using :delete_all strategy"
|
260
313
|
end
|
261
314
|
|
262
315
|
def test_delete_all_on_association_is_the_same_as_not_loaded
|
263
316
|
author = authors :david
|
264
|
-
author.thinking_posts.create!(:
|
317
|
+
author.thinking_posts.create!(body: "test")
|
265
318
|
author.reload
|
266
319
|
expected_sql = capture_sql { author.thinking_posts.delete_all }
|
267
320
|
|
268
|
-
author.thinking_posts.create!(:
|
321
|
+
author.thinking_posts.create!(body: "test")
|
269
322
|
author.reload
|
270
323
|
author.thinking_posts.inspect
|
271
324
|
loaded_sql = capture_sql { author.thinking_posts.delete_all }
|
@@ -274,17 +327,25 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
274
327
|
|
275
328
|
def test_delete_all_on_association_with_nil_dependency_is_the_same_as_not_loaded
|
276
329
|
author = authors :david
|
277
|
-
author.posts.create!(:
|
330
|
+
author.posts.create!(title: "test", body: "body")
|
278
331
|
author.reload
|
279
332
|
expected_sql = capture_sql { author.posts.delete_all }
|
280
333
|
|
281
|
-
author.posts.create!(:
|
334
|
+
author.posts.create!(title: "test", body: "body")
|
282
335
|
author.reload
|
283
336
|
author.posts.to_a
|
284
337
|
loaded_sql = capture_sql { author.posts.delete_all }
|
285
338
|
assert_equal(expected_sql, loaded_sql)
|
286
339
|
end
|
287
340
|
|
341
|
+
def test_delete_all_on_association_clears_scope
|
342
|
+
author = Author.create!(name: "Gannon")
|
343
|
+
posts = author.posts
|
344
|
+
posts.create!(title: "test", body: "body")
|
345
|
+
posts.delete_all
|
346
|
+
assert_nil posts.first
|
347
|
+
end
|
348
|
+
|
288
349
|
def test_building_the_associated_object_with_implicit_sti_base_class
|
289
350
|
firm = DependentFirm.new
|
290
351
|
company = firm.companies.build
|
@@ -293,55 +354,99 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
293
354
|
|
294
355
|
def test_building_the_associated_object_with_explicit_sti_base_class
|
295
356
|
firm = DependentFirm.new
|
296
|
-
company = firm.companies.build(:
|
357
|
+
company = firm.companies.build(type: "Company")
|
297
358
|
assert_kind_of Company, company, "Expected #{company.class} to be a Company"
|
298
359
|
end
|
299
360
|
|
300
361
|
def test_building_the_associated_object_with_sti_subclass
|
301
362
|
firm = DependentFirm.new
|
302
|
-
company = firm.companies.build(:
|
363
|
+
company = firm.companies.build(type: "Client")
|
303
364
|
assert_kind_of Client, company, "Expected #{company.class} to be a Client"
|
304
365
|
end
|
305
366
|
|
306
367
|
def test_building_the_associated_object_with_an_invalid_type
|
307
368
|
firm = DependentFirm.new
|
308
|
-
assert_raise(ActiveRecord::SubclassNotFound) { firm.companies.build(:
|
369
|
+
assert_raise(ActiveRecord::SubclassNotFound) { firm.companies.build(type: "Invalid") }
|
309
370
|
end
|
310
371
|
|
311
372
|
def test_building_the_associated_object_with_an_unrelated_type
|
312
373
|
firm = DependentFirm.new
|
313
|
-
assert_raise(ActiveRecord::SubclassNotFound) { firm.companies.build(:
|
374
|
+
assert_raise(ActiveRecord::SubclassNotFound) { firm.companies.build(type: "Account") }
|
375
|
+
end
|
376
|
+
|
377
|
+
test "build the association with an array" do
|
378
|
+
speedometer = Speedometer.new(speedometer_id: "a")
|
379
|
+
data = [{ name: "first" }, { name: "second" }]
|
380
|
+
speedometer.minivans.where(color: "blue").build(data)
|
381
|
+
|
382
|
+
assert_equal 2, speedometer.minivans.size
|
383
|
+
assert speedometer.save
|
384
|
+
|
385
|
+
speedometer.reload
|
386
|
+
|
387
|
+
assert_equal ["first", "second"], speedometer.minivans.map(&:name)
|
388
|
+
assert_equal ["blue", "blue"], speedometer.minivans.map(&:color)
|
314
389
|
end
|
315
390
|
|
316
|
-
test "
|
391
|
+
test "new the association with an array" do
|
317
392
|
speedometer = Speedometer.new(speedometer_id: "a")
|
318
|
-
data = [{name: "first"}, {name: "second"}]
|
319
|
-
speedometer.minivans.
|
393
|
+
data = [{ name: "first" }, { name: "second" }]
|
394
|
+
speedometer.minivans.where(color: "blue").new(data)
|
320
395
|
|
321
396
|
assert_equal 2, speedometer.minivans.size
|
322
397
|
assert speedometer.save
|
323
|
-
|
398
|
+
|
399
|
+
speedometer.reload
|
400
|
+
|
401
|
+
assert_equal ["first", "second"], speedometer.minivans.map(&:name)
|
402
|
+
assert_equal ["blue", "blue"], speedometer.minivans.map(&:color)
|
403
|
+
end
|
404
|
+
|
405
|
+
test "create the association with an array" do
|
406
|
+
speedometer = Speedometer.create!(speedometer_id: "a")
|
407
|
+
data = [{ name: "first" }, { name: "second" }]
|
408
|
+
speedometer.minivans.where(color: "blue").create(data)
|
409
|
+
|
410
|
+
assert_equal 2, speedometer.minivans.size
|
411
|
+
|
412
|
+
speedometer.reload
|
413
|
+
|
414
|
+
assert_equal ["first", "second"], speedometer.minivans.map(&:name)
|
415
|
+
assert_equal ["blue", "blue"], speedometer.minivans.map(&:color)
|
416
|
+
end
|
417
|
+
|
418
|
+
test "create! the association with an array" do
|
419
|
+
speedometer = Speedometer.create!(speedometer_id: "a")
|
420
|
+
data = [{ name: "first" }, { name: "second" }]
|
421
|
+
speedometer.minivans.where(color: "blue").create!(data)
|
422
|
+
|
423
|
+
assert_equal 2, speedometer.minivans.size
|
424
|
+
|
425
|
+
speedometer.reload
|
426
|
+
|
427
|
+
assert_equal ["first", "second"], speedometer.minivans.map(&:name)
|
428
|
+
assert_equal ["blue", "blue"], speedometer.minivans.map(&:color)
|
324
429
|
end
|
325
430
|
|
326
431
|
def test_association_keys_bypass_attribute_protection
|
327
|
-
car = Car.create(:
|
432
|
+
car = Car.create(name: "honda")
|
328
433
|
|
329
434
|
bulb = car.bulbs.new
|
330
435
|
assert_equal car.id, bulb.car_id
|
331
436
|
|
332
|
-
bulb = car.bulbs.new :
|
437
|
+
bulb = car.bulbs.new car_id: car.id + 1
|
333
438
|
assert_equal car.id, bulb.car_id
|
334
439
|
|
335
440
|
bulb = car.bulbs.build
|
336
441
|
assert_equal car.id, bulb.car_id
|
337
442
|
|
338
|
-
bulb = car.bulbs.build :
|
443
|
+
bulb = car.bulbs.build car_id: car.id + 1
|
339
444
|
assert_equal car.id, bulb.car_id
|
340
445
|
|
341
446
|
bulb = car.bulbs.create
|
342
447
|
assert_equal car.id, bulb.car_id
|
343
448
|
|
344
|
-
bulb = car.bulbs.create :
|
449
|
+
bulb = car.bulbs.create car_id: car.id + 1
|
345
450
|
assert_equal car.id, bulb.car_id
|
346
451
|
end
|
347
452
|
|
@@ -351,22 +456,43 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
351
456
|
line_item = invoice.line_items.new
|
352
457
|
assert_equal invoice.id, line_item.invoice_id
|
353
458
|
|
354
|
-
line_item = invoice.line_items.new :
|
459
|
+
line_item = invoice.line_items.new invoice_id: invoice.id + 1
|
355
460
|
assert_equal invoice.id, line_item.invoice_id
|
356
461
|
|
357
462
|
line_item = invoice.line_items.build
|
358
463
|
assert_equal invoice.id, line_item.invoice_id
|
359
464
|
|
360
|
-
line_item = invoice.line_items.build :
|
465
|
+
line_item = invoice.line_items.build invoice_id: invoice.id + 1
|
361
466
|
assert_equal invoice.id, line_item.invoice_id
|
362
467
|
|
363
468
|
line_item = invoice.line_items.create
|
364
469
|
assert_equal invoice.id, line_item.invoice_id
|
365
470
|
|
366
|
-
line_item = invoice.line_items.create :
|
471
|
+
line_item = invoice.line_items.create invoice_id: invoice.id + 1
|
367
472
|
assert_equal invoice.id, line_item.invoice_id
|
368
473
|
end
|
369
474
|
|
475
|
+
class SpecialAuthor < ActiveRecord::Base
|
476
|
+
self.table_name = "authors"
|
477
|
+
has_many :books, class_name: "SpecialBook", foreign_key: :author_id
|
478
|
+
end
|
479
|
+
|
480
|
+
class SpecialBook < ActiveRecord::Base
|
481
|
+
self.table_name = "books"
|
482
|
+
|
483
|
+
belongs_to :author
|
484
|
+
enum last_read: { unread: 0, reading: 2, read: 3, forgotten: nil }
|
485
|
+
end
|
486
|
+
|
487
|
+
def test_association_enum_works_properly
|
488
|
+
author = SpecialAuthor.create!(name: "Test")
|
489
|
+
book = SpecialBook.create!(last_read: "reading")
|
490
|
+
author.books << book
|
491
|
+
|
492
|
+
assert_equal "reading", book.last_read
|
493
|
+
assert_not_equal 0, SpecialAuthor.joins(:books).where(books: { last_read: "reading" }).count
|
494
|
+
end
|
495
|
+
|
370
496
|
# When creating objects on the association, we must not do it within a scope (even though it
|
371
497
|
# would be convenient), because this would cause that scope to be applied to any callbacks etc.
|
372
498
|
def test_build_and_create_should_not_happen_within_scope
|
@@ -384,64 +510,100 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
384
510
|
end
|
385
511
|
|
386
512
|
def test_no_sql_should_be_fired_if_association_already_loaded
|
387
|
-
Car.create(:
|
513
|
+
Car.create(name: "honda")
|
388
514
|
bulbs = Car.first.bulbs
|
389
515
|
bulbs.to_a # to load all instances of bulbs
|
390
516
|
|
391
517
|
assert_no_queries do
|
392
518
|
bulbs.first()
|
393
|
-
bulbs.first({})
|
394
519
|
end
|
395
520
|
|
396
521
|
assert_no_queries do
|
397
522
|
bulbs.second()
|
398
|
-
bulbs.second({})
|
399
523
|
end
|
400
524
|
|
401
525
|
assert_no_queries do
|
402
526
|
bulbs.third()
|
403
|
-
bulbs.third({})
|
404
527
|
end
|
405
528
|
|
406
529
|
assert_no_queries do
|
407
530
|
bulbs.fourth()
|
408
|
-
bulbs.fourth({})
|
409
531
|
end
|
410
532
|
|
411
533
|
assert_no_queries do
|
412
534
|
bulbs.fifth()
|
413
|
-
bulbs.fifth({})
|
414
535
|
end
|
415
536
|
|
416
537
|
assert_no_queries do
|
417
538
|
bulbs.forty_two()
|
418
|
-
bulbs.forty_two({})
|
419
539
|
end
|
420
540
|
|
421
541
|
assert_no_queries do
|
422
542
|
bulbs.third_to_last()
|
423
|
-
bulbs.third_to_last({})
|
424
543
|
end
|
425
544
|
|
426
545
|
assert_no_queries do
|
427
546
|
bulbs.second_to_last()
|
428
|
-
bulbs.second_to_last({})
|
429
547
|
end
|
430
548
|
|
431
549
|
assert_no_queries do
|
432
550
|
bulbs.last()
|
433
|
-
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|
554
|
+
def test_finder_method_with_dirty_target
|
555
|
+
company = companies(:first_firm)
|
556
|
+
new_clients = []
|
557
|
+
|
558
|
+
assert_queries(0) do
|
559
|
+
new_clients << company.clients_of_firm.build(name: "Another Client")
|
560
|
+
new_clients << company.clients_of_firm.build(name: "Another Client II")
|
561
|
+
new_clients << company.clients_of_firm.build(name: "Another Client III")
|
562
|
+
end
|
563
|
+
|
564
|
+
assert_not_predicate company.clients_of_firm, :loaded?
|
565
|
+
assert_queries(1) do
|
566
|
+
assert_same new_clients[0], company.clients_of_firm.third
|
567
|
+
assert_same new_clients[1], company.clients_of_firm.fourth
|
568
|
+
assert_same new_clients[2], company.clients_of_firm.fifth
|
569
|
+
assert_same new_clients[0], company.clients_of_firm.third_to_last
|
570
|
+
assert_same new_clients[1], company.clients_of_firm.second_to_last
|
571
|
+
assert_same new_clients[2], company.clients_of_firm.last
|
572
|
+
end
|
573
|
+
end
|
574
|
+
|
575
|
+
def test_finder_bang_method_with_dirty_target
|
576
|
+
company = companies(:first_firm)
|
577
|
+
new_clients = []
|
578
|
+
|
579
|
+
assert_queries(0) do
|
580
|
+
new_clients << company.clients_of_firm.build(name: "Another Client")
|
581
|
+
new_clients << company.clients_of_firm.build(name: "Another Client II")
|
582
|
+
new_clients << company.clients_of_firm.build(name: "Another Client III")
|
583
|
+
end
|
584
|
+
|
585
|
+
assert_not_predicate company.clients_of_firm, :loaded?
|
586
|
+
assert_queries(1) do
|
587
|
+
assert_same new_clients[0], company.clients_of_firm.third!
|
588
|
+
assert_same new_clients[1], company.clients_of_firm.fourth!
|
589
|
+
assert_same new_clients[2], company.clients_of_firm.fifth!
|
590
|
+
assert_same new_clients[0], company.clients_of_firm.third_to_last!
|
591
|
+
assert_same new_clients[1], company.clients_of_firm.second_to_last!
|
592
|
+
assert_same new_clients[2], company.clients_of_firm.last!
|
434
593
|
end
|
435
594
|
end
|
436
595
|
|
437
596
|
def test_create_resets_cached_counters
|
438
|
-
|
597
|
+
Reader.delete_all
|
598
|
+
|
599
|
+
person = Person.create!(first_name: "tenderlove")
|
600
|
+
|
439
601
|
post = Post.first
|
440
602
|
|
441
603
|
assert_equal [], person.readers
|
442
604
|
assert_nil person.readers.find_by_post_id(post.id)
|
443
605
|
|
444
|
-
person.readers.create(:
|
606
|
+
person.readers.create(post_id: post.id)
|
445
607
|
|
446
608
|
assert_equal 1, person.readers.count
|
447
609
|
assert_equal 1, person.readers.length
|
@@ -451,43 +613,34 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
451
613
|
|
452
614
|
def test_update_all_respects_association_scope
|
453
615
|
person = Person.new
|
454
|
-
person.first_name =
|
616
|
+
person.first_name = "Naruto"
|
455
617
|
person.references << Reference.new
|
456
|
-
person.id = 10
|
457
|
-
person.references
|
458
618
|
person.save!
|
459
619
|
assert_equal 1, person.references.update_all(favourite: true)
|
460
620
|
end
|
461
621
|
|
462
622
|
def test_exists_respects_association_scope
|
463
623
|
person = Person.new
|
464
|
-
person.first_name =
|
624
|
+
person.first_name = "Sasuke"
|
465
625
|
person.references << Reference.new
|
466
|
-
person.id = 10
|
467
|
-
person.references
|
468
626
|
person.save!
|
469
627
|
assert_predicate person.references, :exists?
|
470
628
|
end
|
471
629
|
|
472
|
-
def force_signal37_to_load_all_clients_of_firm
|
473
|
-
companies(:first_firm).clients_of_firm.each {|f| }
|
474
|
-
end
|
475
|
-
|
476
|
-
# sometimes tests on Oracle fail if ORDER BY is not provided therefore add always :order with :first
|
477
630
|
def test_counting_with_counter_sql
|
478
|
-
assert_equal 3, Firm.
|
631
|
+
assert_equal 3, Firm.first.clients.count
|
479
632
|
end
|
480
633
|
|
481
634
|
def test_counting
|
482
|
-
assert_equal 3, Firm.
|
635
|
+
assert_equal 3, Firm.first.plain_clients.count
|
483
636
|
end
|
484
637
|
|
485
638
|
def test_counting_with_single_hash
|
486
|
-
assert_equal 1, Firm.
|
639
|
+
assert_equal 1, Firm.first.plain_clients.where(name: "Microsoft").count
|
487
640
|
end
|
488
641
|
|
489
642
|
def test_counting_with_column_name_and_hash
|
490
|
-
assert_equal 3, Firm.
|
643
|
+
assert_equal 3, Firm.first.plain_clients.count(:name)
|
491
644
|
end
|
492
645
|
|
493
646
|
def test_counting_with_association_limit
|
@@ -497,11 +650,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
497
650
|
end
|
498
651
|
|
499
652
|
def test_finding
|
500
|
-
assert_equal 3, Firm.
|
653
|
+
assert_equal 3, Firm.first.clients.length
|
501
654
|
end
|
502
655
|
|
503
656
|
def test_finding_array_compatibility
|
504
|
-
assert_equal 3, Firm.order(:id).find{|f| f.id > 0}.clients.length
|
657
|
+
assert_equal 3, Firm.order(:id).find { |f| f.id > 0 }.clients.length
|
505
658
|
end
|
506
659
|
|
507
660
|
def test_find_many_with_merged_options
|
@@ -511,13 +664,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
511
664
|
end
|
512
665
|
|
513
666
|
def test_find_should_append_to_association_order
|
514
|
-
ordered_clients =
|
515
|
-
assert_equal [
|
667
|
+
ordered_clients = companies(:first_firm).clients_sorted_desc.order("companies.id")
|
668
|
+
assert_equal ["id DESC", "companies.id"], ordered_clients.order_values
|
516
669
|
end
|
517
670
|
|
518
671
|
def test_dynamic_find_should_respect_association_order
|
519
672
|
assert_equal companies(:another_first_firm_client), companies(:first_firm).clients_sorted_desc.where("type = 'Client'").first
|
520
|
-
assert_equal companies(:another_first_firm_client), companies(:first_firm).clients_sorted_desc.find_by_type(
|
673
|
+
assert_equal companies(:another_first_firm_client), companies(:first_firm).clients_sorted_desc.find_by_type("Client")
|
521
674
|
end
|
522
675
|
|
523
676
|
def test_taking
|
@@ -537,16 +690,28 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
537
690
|
end
|
538
691
|
|
539
692
|
def test_taking_with_a_number
|
693
|
+
klass = Class.new(Author) do
|
694
|
+
has_many :posts, -> { order(:id) }
|
695
|
+
|
696
|
+
def self.name
|
697
|
+
"Author"
|
698
|
+
end
|
699
|
+
end
|
700
|
+
|
540
701
|
# taking from unloaded Relation
|
541
|
-
bob =
|
702
|
+
bob = klass.find(authors(:bob).id)
|
703
|
+
new_post = bob.posts.build
|
704
|
+
assert_not_predicate bob.posts, :loaded?
|
542
705
|
assert_equal [posts(:misc_by_bob)], bob.posts.take(1)
|
543
|
-
bob = Author.find(authors(:bob).id)
|
544
706
|
assert_equal [posts(:misc_by_bob), posts(:other_by_bob)], bob.posts.take(2)
|
707
|
+
assert_equal [posts(:misc_by_bob), posts(:other_by_bob), new_post], bob.posts.take(3)
|
545
708
|
|
546
709
|
# taking from loaded Relation
|
547
|
-
bob.posts.
|
548
|
-
|
549
|
-
assert_equal [posts(:misc_by_bob)
|
710
|
+
bob.posts.load
|
711
|
+
assert_predicate bob.posts, :loaded?
|
712
|
+
assert_equal [posts(:misc_by_bob)], bob.posts.take(1)
|
713
|
+
assert_equal [posts(:misc_by_bob), posts(:other_by_bob)], bob.posts.take(2)
|
714
|
+
assert_equal [posts(:misc_by_bob), posts(:other_by_bob), new_post], bob.posts.take(3)
|
550
715
|
end
|
551
716
|
|
552
717
|
def test_taking_with_inverse_of
|
@@ -565,27 +730,27 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
565
730
|
end
|
566
731
|
|
567
732
|
def test_finding_default_orders
|
568
|
-
assert_equal "Summit", Firm.
|
733
|
+
assert_equal "Summit", Firm.first.clients.first.name
|
569
734
|
end
|
570
735
|
|
571
736
|
def test_finding_with_different_class_name_and_order
|
572
|
-
assert_equal "Apex", Firm.
|
737
|
+
assert_equal "Apex", Firm.first.clients_sorted_desc.first.name
|
573
738
|
end
|
574
739
|
|
575
740
|
def test_finding_with_foreign_key
|
576
|
-
assert_equal "Microsoft", Firm.
|
741
|
+
assert_equal "Microsoft", Firm.first.clients_of_firm.first.name
|
577
742
|
end
|
578
743
|
|
579
744
|
def test_finding_with_condition
|
580
|
-
assert_equal "Microsoft", Firm.
|
745
|
+
assert_equal "Microsoft", Firm.first.clients_like_ms.first.name
|
581
746
|
end
|
582
747
|
|
583
748
|
def test_finding_with_condition_hash
|
584
|
-
assert_equal "Microsoft", Firm.
|
749
|
+
assert_equal "Microsoft", Firm.first.clients_like_ms_with_hash_conditions.first.name
|
585
750
|
end
|
586
751
|
|
587
752
|
def test_finding_using_primary_key
|
588
|
-
assert_equal "Summit", Firm.
|
753
|
+
assert_equal "Summit", Firm.first.clients_using_primary_key.first.name
|
589
754
|
end
|
590
755
|
|
591
756
|
def test_update_all_on_association_accessed_before_save
|
@@ -608,7 +773,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
608
773
|
end
|
609
774
|
|
610
775
|
def test_find_ids
|
611
|
-
firm = Firm.
|
776
|
+
firm = Firm.first
|
612
777
|
|
613
778
|
assert_raise(ActiveRecord::RecordNotFound) { firm.clients.find }
|
614
779
|
|
@@ -628,7 +793,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
628
793
|
end
|
629
794
|
|
630
795
|
def test_find_one_message_on_primary_key
|
631
|
-
firm = Firm.
|
796
|
+
firm = Firm.first
|
632
797
|
|
633
798
|
e = assert_raises(ActiveRecord::RecordNotFound) do
|
634
799
|
firm.clients.find(0)
|
@@ -642,6 +807,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
642
807
|
def test_find_ids_and_inverse_of
|
643
808
|
force_signal37_to_load_all_clients_of_firm
|
644
809
|
|
810
|
+
assert_predicate companies(:first_firm).clients_of_firm, :loaded?
|
811
|
+
|
645
812
|
firm = companies(:first_firm)
|
646
813
|
client = firm.clients_of_firm.find(3)
|
647
814
|
assert_kind_of Client, client
|
@@ -652,7 +819,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
652
819
|
end
|
653
820
|
|
654
821
|
def test_find_all
|
655
|
-
firm = Firm.
|
822
|
+
firm = Firm.first
|
656
823
|
assert_equal 3, firm.clients.where("#{QUOTED_TYPE} = 'Client'").to_a.length
|
657
824
|
assert_equal 1, firm.clients.where("name = 'Summit'").to_a.length
|
658
825
|
end
|
@@ -660,67 +827,143 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
660
827
|
def test_find_each
|
661
828
|
firm = companies(:first_firm)
|
662
829
|
|
663
|
-
|
830
|
+
assert_not_predicate firm.clients, :loaded?
|
664
831
|
|
665
832
|
assert_queries(4) do
|
666
|
-
firm.clients.find_each(:
|
833
|
+
firm.clients.find_each(batch_size: 1) { |c| assert_equal firm.id, c.firm_id }
|
667
834
|
end
|
668
835
|
|
669
|
-
|
836
|
+
assert_not_predicate firm.clients, :loaded?
|
670
837
|
end
|
671
838
|
|
672
839
|
def test_find_each_with_conditions
|
673
840
|
firm = companies(:first_firm)
|
674
841
|
|
675
842
|
assert_queries(2) do
|
676
|
-
firm.clients.where(name:
|
843
|
+
firm.clients.where(name: "Microsoft").find_each(batch_size: 1) do |c|
|
677
844
|
assert_equal firm.id, c.firm_id
|
678
845
|
assert_equal "Microsoft", c.name
|
679
846
|
end
|
680
847
|
end
|
681
848
|
|
682
|
-
|
849
|
+
assert_not_predicate firm.clients, :loaded?
|
683
850
|
end
|
684
851
|
|
685
852
|
def test_find_in_batches
|
686
853
|
firm = companies(:first_firm)
|
687
854
|
|
688
|
-
|
855
|
+
assert_not_predicate firm.clients, :loaded?
|
689
856
|
|
690
857
|
assert_queries(2) do
|
691
|
-
firm.clients.find_in_batches(:
|
692
|
-
clients.each {|c| assert_equal firm.id, c.firm_id }
|
858
|
+
firm.clients.find_in_batches(batch_size: 2) do |clients|
|
859
|
+
clients.each { |c| assert_equal firm.id, c.firm_id }
|
693
860
|
end
|
694
861
|
end
|
695
862
|
|
696
|
-
|
863
|
+
assert_not_predicate firm.clients, :loaded?
|
697
864
|
end
|
698
865
|
|
699
866
|
def test_find_all_sanitized
|
700
|
-
|
701
|
-
firm = Firm.all.merge!(:order => "id").first
|
867
|
+
firm = Firm.first
|
702
868
|
summit = firm.clients.where("name = 'Summit'").to_a
|
703
869
|
assert_equal summit, firm.clients.where("name = ?", "Summit").to_a
|
704
|
-
assert_equal summit, firm.clients.where("name = :name",
|
870
|
+
assert_equal summit, firm.clients.where("name = :name", name: "Summit").to_a
|
705
871
|
end
|
706
872
|
|
707
873
|
def test_find_first
|
708
|
-
firm = Firm.
|
874
|
+
firm = Firm.first
|
709
875
|
client2 = Client.find(2)
|
710
876
|
assert_equal firm.clients.first, firm.clients.order("id").first
|
711
877
|
assert_equal client2, firm.clients.where("#{QUOTED_TYPE} = 'Client'").order("id").first
|
712
878
|
end
|
713
879
|
|
714
880
|
def test_find_first_sanitized
|
715
|
-
firm = Firm.
|
881
|
+
firm = Firm.first
|
716
882
|
client2 = Client.find(2)
|
717
|
-
assert_equal client2, firm.clients.
|
718
|
-
assert_equal client2, firm.clients.
|
883
|
+
assert_equal client2, firm.clients.where("#{QUOTED_TYPE} = ?", "Client").first
|
884
|
+
assert_equal client2, firm.clients.where("#{QUOTED_TYPE} = :type", type: "Client").first
|
885
|
+
end
|
886
|
+
|
887
|
+
def test_find_first_after_reset_scope
|
888
|
+
firm = Firm.first
|
889
|
+
collection = firm.clients
|
890
|
+
|
891
|
+
original_object = collection.first
|
892
|
+
assert_same original_object, collection.first, "Expected second call to #first to cache the same object"
|
893
|
+
|
894
|
+
# It should return a different object, since the association has been reloaded
|
895
|
+
assert_not_same original_object, firm.clients.first, "Expected #first to return a new object"
|
896
|
+
end
|
897
|
+
|
898
|
+
def test_find_first_after_reset
|
899
|
+
firm = Firm.first
|
900
|
+
collection = firm.clients
|
901
|
+
|
902
|
+
original_object = collection.first
|
903
|
+
assert_same original_object, collection.first, "Expected second call to #first to cache the same object"
|
904
|
+
collection.reset
|
905
|
+
|
906
|
+
# It should return a different object, since the association has been reloaded
|
907
|
+
assert_not_same original_object, collection.first, "Expected #first after #reset to return a new object"
|
908
|
+
end
|
909
|
+
|
910
|
+
def test_find_first_after_reload
|
911
|
+
firm = Firm.first
|
912
|
+
collection = firm.clients
|
913
|
+
|
914
|
+
original_object = collection.first
|
915
|
+
assert_same original_object, collection.first, "Expected second call to #first to cache the same object"
|
916
|
+
collection.reload
|
917
|
+
|
918
|
+
# It should return a different object, since the association has been reloaded
|
919
|
+
assert_not_same original_object, collection.first, "Expected #first after #reload to return a new object"
|
920
|
+
end
|
921
|
+
|
922
|
+
def test_reload_with_query_cache
|
923
|
+
connection = ActiveRecord::Base.connection
|
924
|
+
connection.enable_query_cache!
|
925
|
+
connection.clear_query_cache
|
926
|
+
|
927
|
+
# Populate the cache with a query
|
928
|
+
firm = Firm.first
|
929
|
+
# Populate the cache with a second query
|
930
|
+
firm.clients.load
|
931
|
+
|
932
|
+
assert_equal 2, connection.query_cache.size
|
933
|
+
|
934
|
+
# Clear the cache and fetch the clients again, populating the cache with a query
|
935
|
+
assert_queries(1) { firm.clients.reload }
|
936
|
+
# This query is cached, so it shouldn't make a real SQL query
|
937
|
+
assert_queries(0) { firm.clients.load }
|
938
|
+
|
939
|
+
assert_equal 1, connection.query_cache.size
|
940
|
+
ensure
|
941
|
+
ActiveRecord::Base.connection.disable_query_cache!
|
942
|
+
end
|
943
|
+
|
944
|
+
def test_reloading_unloaded_associations_with_query_cache
|
945
|
+
connection = ActiveRecord::Base.connection
|
946
|
+
connection.enable_query_cache!
|
947
|
+
connection.clear_query_cache
|
948
|
+
|
949
|
+
firm = Firm.create!(name: "firm name")
|
950
|
+
client = firm.clients.create!(name: "client name")
|
951
|
+
firm.clients.to_a # add request to cache
|
952
|
+
|
953
|
+
connection.uncached do
|
954
|
+
client.update!(name: "new client name")
|
955
|
+
end
|
956
|
+
|
957
|
+
firm = Firm.find(firm.id)
|
958
|
+
|
959
|
+
assert_equal [client.name], firm.clients.reload.map(&:name)
|
960
|
+
ensure
|
961
|
+
ActiveRecord::Base.connection.disable_query_cache!
|
719
962
|
end
|
720
963
|
|
721
964
|
def test_find_all_with_include_and_conditions
|
722
965
|
assert_nothing_raised do
|
723
|
-
Developer.all.merge!(:
|
966
|
+
Developer.all.merge!(joins: :audit_logs, where: { "audit_logs.message" => nil, :name => "Smith" }).to_a
|
724
967
|
end
|
725
968
|
end
|
726
969
|
|
@@ -730,8 +973,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
730
973
|
end
|
731
974
|
|
732
975
|
def test_find_grouped
|
733
|
-
all_clients_of_firm1 = Client.all.merge!(:
|
734
|
-
grouped_clients_of_firm1 = Client.all.merge!(:
|
976
|
+
all_clients_of_firm1 = Client.all.merge!(where: "firm_id = 1").to_a
|
977
|
+
grouped_clients_of_firm1 = Client.all.merge!(where: "firm_id = 1", group: "firm_id", select: "firm_id, count(id) as clients_count").to_a
|
735
978
|
assert_equal 3, all_clients_of_firm1.size
|
736
979
|
assert_equal 1, grouped_clients_of_firm1.size
|
737
980
|
end
|
@@ -744,7 +987,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
744
987
|
end
|
745
988
|
|
746
989
|
def test_find_scoped_grouped_having
|
747
|
-
assert_equal
|
990
|
+
assert_equal 2, authors(:david).popular_grouped_posts.length
|
748
991
|
assert_equal 0, authors(:mary).popular_grouped_posts.length
|
749
992
|
end
|
750
993
|
|
@@ -753,19 +996,28 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
753
996
|
end
|
754
997
|
|
755
998
|
def test_select_query_method
|
756
|
-
assert_equal [
|
999
|
+
assert_equal ["id", "body"], posts(:welcome).comments.select(:id, :body).first.attributes.keys
|
757
1000
|
end
|
758
1001
|
|
759
1002
|
def test_select_with_block
|
760
1003
|
assert_equal [1], posts(:welcome).comments.select { |c| c.id == 1 }.map(&:id)
|
761
1004
|
end
|
762
1005
|
|
1006
|
+
def test_select_with_block_and_dirty_target
|
1007
|
+
assert_equal 2, posts(:welcome).comments.select { true }.size
|
1008
|
+
posts(:welcome).comments.build
|
1009
|
+
assert_equal 3, posts(:welcome).comments.select { true }.size
|
1010
|
+
end
|
1011
|
+
|
763
1012
|
def test_select_without_foreign_key
|
764
1013
|
assert_equal companies(:first_firm).accounts.first.credit_limit, companies(:first_firm).accounts.select(:credit_limit).first.credit_limit
|
765
1014
|
end
|
766
1015
|
|
767
1016
|
def test_adding
|
768
1017
|
force_signal37_to_load_all_clients_of_firm
|
1018
|
+
|
1019
|
+
assert_predicate companies(:first_firm).clients_of_firm, :loaded?
|
1020
|
+
|
769
1021
|
natural = Client.new("name" => "Natural Company")
|
770
1022
|
companies(:first_firm).clients_of_firm << natural
|
771
1023
|
assert_equal 3, companies(:first_firm).clients_of_firm.size # checking via the collection
|
@@ -776,7 +1028,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
776
1028
|
def test_adding_using_create
|
777
1029
|
first_firm = companies(:first_firm)
|
778
1030
|
assert_equal 3, first_firm.plain_clients.size
|
779
|
-
first_firm.plain_clients.create(:
|
1031
|
+
first_firm.plain_clients.create(name: "Natural Company")
|
780
1032
|
assert_equal 4, first_firm.plain_clients.length
|
781
1033
|
assert_equal 4, first_firm.plain_clients.size
|
782
1034
|
end
|
@@ -784,7 +1036,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
784
1036
|
def test_create_with_bang_on_has_many_when_parent_is_new_raises
|
785
1037
|
error = assert_raise(ActiveRecord::RecordNotSaved) do
|
786
1038
|
firm = Firm.new
|
787
|
-
firm.plain_clients.create! :
|
1039
|
+
firm.plain_clients.create! name: "Whoever"
|
788
1040
|
end
|
789
1041
|
|
790
1042
|
assert_equal "You cannot call create unless the parent is saved", error.message
|
@@ -793,7 +1045,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
793
1045
|
def test_regular_create_on_has_many_when_parent_is_new_raises
|
794
1046
|
error = assert_raise(ActiveRecord::RecordNotSaved) do
|
795
1047
|
firm = Firm.new
|
796
|
-
firm.plain_clients.create :
|
1048
|
+
firm.plain_clients.create name: "Whoever"
|
797
1049
|
end
|
798
1050
|
|
799
1051
|
assert_equal "You cannot call create unless the parent is saved", error.message
|
@@ -801,7 +1053,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
801
1053
|
|
802
1054
|
def test_create_with_bang_on_has_many_raises_when_record_not_saved
|
803
1055
|
assert_raise(ActiveRecord::RecordInvalid) do
|
804
|
-
firm = Firm.
|
1056
|
+
firm = Firm.first
|
805
1057
|
firm.plain_clients.create!
|
806
1058
|
end
|
807
1059
|
end
|
@@ -822,26 +1074,30 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
822
1074
|
|
823
1075
|
def test_adding_a_collection
|
824
1076
|
force_signal37_to_load_all_clients_of_firm
|
825
|
-
|
1077
|
+
|
1078
|
+
assert_predicate companies(:first_firm).clients_of_firm, :loaded?
|
1079
|
+
|
1080
|
+
result = companies(:first_firm).clients_of_firm.concat([Client.new("name" => "Natural Company"), Client.new("name" => "Apple")])
|
826
1081
|
assert_equal 4, companies(:first_firm).clients_of_firm.size
|
827
1082
|
assert_equal 4, companies(:first_firm).clients_of_firm.reload.size
|
1083
|
+
assert_equal companies(:first_firm).clients_of_firm, result
|
828
1084
|
end
|
829
1085
|
|
830
1086
|
def test_transactions_when_adding_to_persisted
|
831
|
-
good = Client.new(:
|
832
|
-
bad = Client.new(:
|
1087
|
+
good = Client.new(name: "Good")
|
1088
|
+
bad = Client.new(name: "Bad", raise_on_save: true)
|
833
1089
|
|
834
1090
|
begin
|
835
1091
|
companies(:first_firm).clients_of_firm.concat(good, bad)
|
836
1092
|
rescue Client::RaisedOnSave
|
837
1093
|
end
|
838
1094
|
|
839
|
-
|
1095
|
+
assert_not_includes companies(:first_firm).clients_of_firm.reload, good
|
840
1096
|
end
|
841
1097
|
|
842
1098
|
def test_transactions_when_adding_to_new_record
|
843
|
-
|
844
|
-
|
1099
|
+
firm = Firm.new
|
1100
|
+
assert_queries(0) do
|
845
1101
|
firm.clients_of_firm.concat(Client.new("name" => "Natural Company"))
|
846
1102
|
end
|
847
1103
|
end
|
@@ -855,21 +1111,23 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
855
1111
|
|
856
1112
|
def test_new_aliased_to_build
|
857
1113
|
company = companies(:first_firm)
|
858
|
-
|
859
|
-
|
1114
|
+
|
1115
|
+
new_client = assert_queries(0) { company.clients_of_firm.new("name" => "Another Client") }
|
1116
|
+
assert_not_predicate company.clients_of_firm, :loaded?
|
860
1117
|
|
861
1118
|
assert_equal "Another Client", new_client.name
|
862
|
-
|
1119
|
+
assert_not_predicate new_client, :persisted?
|
863
1120
|
assert_equal new_client, company.clients_of_firm.last
|
864
1121
|
end
|
865
1122
|
|
866
1123
|
def test_build
|
867
1124
|
company = companies(:first_firm)
|
868
|
-
|
869
|
-
|
1125
|
+
|
1126
|
+
new_client = assert_queries(0) { company.clients_of_firm.build("name" => "Another Client") }
|
1127
|
+
assert_not_predicate company.clients_of_firm, :loaded?
|
870
1128
|
|
871
1129
|
assert_equal "Another Client", new_client.name
|
872
|
-
|
1130
|
+
assert_not_predicate new_client, :persisted?
|
873
1131
|
assert_equal new_client, company.clients_of_firm.last
|
874
1132
|
end
|
875
1133
|
|
@@ -878,13 +1136,34 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
878
1136
|
company.clients_of_firm.build("name" => "Another Client")
|
879
1137
|
company.clients_of_firm.build("name" => "Yet Another Client")
|
880
1138
|
assert_equal 4, company.clients_of_firm.size
|
1139
|
+
assert_equal 4, company.clients_of_firm.uniq.size
|
881
1140
|
end
|
882
1141
|
|
883
1142
|
def test_collection_not_empty_after_building
|
884
1143
|
company = companies(:first_firm)
|
885
|
-
|
1144
|
+
assert_empty company.contracts
|
886
1145
|
company.contracts.build
|
887
|
-
|
1146
|
+
assert_not_empty company.contracts
|
1147
|
+
end
|
1148
|
+
|
1149
|
+
def test_collection_size_with_dirty_target
|
1150
|
+
post = posts(:thinking)
|
1151
|
+
assert_equal [], post.reader_ids
|
1152
|
+
assert_equal 0, post.readers.size
|
1153
|
+
post.readers.reset
|
1154
|
+
post.readers.build
|
1155
|
+
assert_equal [nil], post.reader_ids
|
1156
|
+
assert_equal 1, post.readers.size
|
1157
|
+
end
|
1158
|
+
|
1159
|
+
def test_collection_empty_with_dirty_target
|
1160
|
+
post = posts(:thinking)
|
1161
|
+
assert_equal [], post.reader_ids
|
1162
|
+
assert_empty post.readers
|
1163
|
+
post.readers.reset
|
1164
|
+
post.readers.build
|
1165
|
+
assert_equal [nil], post.reader_ids
|
1166
|
+
assert_not_empty post.readers
|
888
1167
|
end
|
889
1168
|
|
890
1169
|
def test_collection_size_twice_for_regressions
|
@@ -901,24 +1180,24 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
901
1180
|
|
902
1181
|
def test_build_many
|
903
1182
|
company = companies(:first_firm)
|
904
|
-
|
1183
|
+
|
1184
|
+
new_clients = assert_queries(0) { company.clients_of_firm.build([{ "name" => "Another Client" }, { "name" => "Another Client II" }]) }
|
905
1185
|
assert_equal 2, new_clients.size
|
906
1186
|
end
|
907
1187
|
|
908
1188
|
def test_build_followed_by_save_does_not_load_target
|
909
1189
|
companies(:first_firm).clients_of_firm.build("name" => "Another Client")
|
910
1190
|
assert companies(:first_firm).save
|
911
|
-
|
1191
|
+
assert_not_predicate companies(:first_firm).clients_of_firm, :loaded?
|
912
1192
|
end
|
913
1193
|
|
914
1194
|
def test_build_without_loading_association
|
915
1195
|
first_topic = topics(:first)
|
916
|
-
Reply.column_names
|
917
1196
|
|
918
1197
|
assert_equal 1, first_topic.replies.length
|
919
1198
|
|
920
|
-
|
921
|
-
first_topic.replies.build(:
|
1199
|
+
assert_queries(0) do
|
1200
|
+
first_topic.replies.build(title: "Not saved", content: "Superstars")
|
922
1201
|
assert_equal 2, first_topic.replies.size
|
923
1202
|
end
|
924
1203
|
|
@@ -927,18 +1206,20 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
927
1206
|
|
928
1207
|
def test_build_via_block
|
929
1208
|
company = companies(:first_firm)
|
930
|
-
|
931
|
-
|
1209
|
+
|
1210
|
+
new_client = assert_queries(0) { company.clients_of_firm.build { |client| client.name = "Another Client" } }
|
1211
|
+
assert_not_predicate company.clients_of_firm, :loaded?
|
932
1212
|
|
933
1213
|
assert_equal "Another Client", new_client.name
|
934
|
-
|
1214
|
+
assert_not_predicate new_client, :persisted?
|
935
1215
|
assert_equal new_client, company.clients_of_firm.last
|
936
1216
|
end
|
937
1217
|
|
938
1218
|
def test_build_many_via_block
|
939
1219
|
company = companies(:first_firm)
|
940
|
-
|
941
|
-
|
1220
|
+
|
1221
|
+
new_clients = assert_queries(0) do
|
1222
|
+
company.clients_of_firm.build([{ "name" => "Another Client" }, { "name" => "Another Client II" }]) do |client|
|
942
1223
|
client.name = "changed"
|
943
1224
|
end
|
944
1225
|
end
|
@@ -949,15 +1230,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
949
1230
|
end
|
950
1231
|
|
951
1232
|
def test_create_without_loading_association
|
952
|
-
first_firm
|
953
|
-
Firm.column_names
|
954
|
-
Client.column_names
|
1233
|
+
first_firm = companies(:first_firm)
|
955
1234
|
|
956
1235
|
assert_equal 2, first_firm.clients_of_firm.size
|
957
1236
|
first_firm.clients_of_firm.reset
|
958
1237
|
|
959
1238
|
assert_queries(1) do
|
960
|
-
first_firm.clients_of_firm.create(:
|
1239
|
+
first_firm.clients_of_firm.create(name: "Superstars")
|
961
1240
|
end
|
962
1241
|
|
963
1242
|
assert_equal 3, first_firm.clients_of_firm.size
|
@@ -965,25 +1244,31 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
965
1244
|
|
966
1245
|
def test_create
|
967
1246
|
force_signal37_to_load_all_clients_of_firm
|
1247
|
+
|
1248
|
+
assert_predicate companies(:first_firm).clients_of_firm, :loaded?
|
1249
|
+
|
968
1250
|
new_client = companies(:first_firm).clients_of_firm.create("name" => "Another Client")
|
969
|
-
|
1251
|
+
assert_predicate new_client, :persisted?
|
970
1252
|
assert_equal new_client, companies(:first_firm).clients_of_firm.last
|
971
1253
|
assert_equal new_client, companies(:first_firm).clients_of_firm.reload.last
|
972
1254
|
end
|
973
1255
|
|
974
1256
|
def test_create_many
|
975
|
-
companies(:first_firm).clients_of_firm.create([{"name" => "Another Client"}, {"name" => "Another Client II"}])
|
1257
|
+
companies(:first_firm).clients_of_firm.create([{ "name" => "Another Client" }, { "name" => "Another Client II" }])
|
976
1258
|
assert_equal 4, companies(:first_firm).clients_of_firm.reload.size
|
977
1259
|
end
|
978
1260
|
|
979
1261
|
def test_create_followed_by_save_does_not_load_target
|
980
1262
|
companies(:first_firm).clients_of_firm.create("name" => "Another Client")
|
981
1263
|
assert companies(:first_firm).save
|
982
|
-
|
1264
|
+
assert_not_predicate companies(:first_firm).clients_of_firm, :loaded?
|
983
1265
|
end
|
984
1266
|
|
985
1267
|
def test_deleting
|
986
1268
|
force_signal37_to_load_all_clients_of_firm
|
1269
|
+
|
1270
|
+
assert_predicate companies(:first_firm).clients_of_firm, :loaded?
|
1271
|
+
|
987
1272
|
companies(:first_firm).clients_of_firm.delete(companies(:first_firm).clients_of_firm.first)
|
988
1273
|
assert_equal 1, companies(:first_firm).clients_of_firm.size
|
989
1274
|
assert_equal 1, companies(:first_firm).clients_of_firm.reload.size
|
@@ -1000,15 +1285,15 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1000
1285
|
def test_has_many_without_counter_cache_option
|
1001
1286
|
# Ship has a conventionally named `treasures_count` column, but the counter_cache
|
1002
1287
|
# option is not given on the association.
|
1003
|
-
ship = Ship.create(name:
|
1288
|
+
ship = Ship.create!(name: "Countless", treasures_count: 10)
|
1004
1289
|
|
1005
|
-
|
1290
|
+
assert_not_predicate Ship.reflect_on_association(:treasures), :has_cached_counter?
|
1006
1291
|
|
1007
1292
|
# Count should come from sql count() of treasures rather than treasures_count attribute
|
1008
1293
|
assert_equal ship.treasures.size, 0
|
1009
1294
|
|
1010
1295
|
assert_no_difference lambda { ship.reload.treasures_count }, "treasures_count should not be changed" do
|
1011
|
-
ship.treasures.create(name:
|
1296
|
+
ship.treasures.create(name: "Gold")
|
1012
1297
|
end
|
1013
1298
|
|
1014
1299
|
assert_no_difference lambda { ship.reload.treasures_count }, "treasures_count should not be changed" do
|
@@ -1055,6 +1340,38 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1055
1340
|
assert_equal 2, topic.reload.replies.size
|
1056
1341
|
end
|
1057
1342
|
|
1343
|
+
def test_counter_cache_updates_in_memory_after_update_with_inverse_of_disabled
|
1344
|
+
topic = Topic.create!(title: "Zoom-zoom-zoom")
|
1345
|
+
|
1346
|
+
assert_equal 0, topic.replies_count
|
1347
|
+
|
1348
|
+
reply1 = Reply.create!(title: "re: zoom", content: "speedy quick!")
|
1349
|
+
reply2 = Reply.create!(title: "re: zoom 2", content: "OMG lol!")
|
1350
|
+
|
1351
|
+
assert_queries(4) do
|
1352
|
+
topic.replies << [reply1, reply2]
|
1353
|
+
end
|
1354
|
+
|
1355
|
+
assert_equal 2, topic.replies_count
|
1356
|
+
assert_equal 2, topic.reload.replies_count
|
1357
|
+
end
|
1358
|
+
|
1359
|
+
def test_counter_cache_updates_in_memory_after_update_with_inverse_of_enabled
|
1360
|
+
category = Category.create!(name: "Counter Cache")
|
1361
|
+
|
1362
|
+
assert_nil category.categorizations_count
|
1363
|
+
|
1364
|
+
categorization1 = Categorization.create!
|
1365
|
+
categorization2 = Categorization.create!
|
1366
|
+
|
1367
|
+
assert_queries(4) do
|
1368
|
+
category.categorizations << [categorization1, categorization2]
|
1369
|
+
end
|
1370
|
+
|
1371
|
+
assert_equal 2, category.categorizations_count
|
1372
|
+
assert_equal 2, category.reload.categorizations_count
|
1373
|
+
end
|
1374
|
+
|
1058
1375
|
def test_pushing_association_updates_counter_cache
|
1059
1376
|
topic = Topic.order("id ASC").first
|
1060
1377
|
reply = Reply.create!
|
@@ -1092,8 +1409,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1092
1409
|
|
1093
1410
|
def test_calling_empty_with_counter_cache
|
1094
1411
|
post = posts(:welcome)
|
1095
|
-
|
1096
|
-
|
1412
|
+
assert_no_queries do
|
1413
|
+
assert_not_empty post.comments
|
1097
1414
|
end
|
1098
1415
|
end
|
1099
1416
|
|
@@ -1105,20 +1422,20 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1105
1422
|
end
|
1106
1423
|
end
|
1107
1424
|
|
1108
|
-
def
|
1425
|
+
def test_calling_update_on_id_changes_the_counter_cache
|
1109
1426
|
topic = Topic.order("id ASC").first
|
1110
1427
|
original_count = topic.replies.to_a.size
|
1111
1428
|
assert_equal original_count, topic.replies_count
|
1112
1429
|
|
1113
1430
|
first_reply = topic.replies.first
|
1114
|
-
first_reply.
|
1431
|
+
first_reply.update(parent_id: nil)
|
1115
1432
|
assert_equal original_count - 1, topic.reload.replies_count
|
1116
1433
|
|
1117
|
-
first_reply.
|
1434
|
+
first_reply.update(parent_id: topic.id)
|
1118
1435
|
assert_equal original_count, topic.reload.replies_count
|
1119
1436
|
end
|
1120
1437
|
|
1121
|
-
def
|
1438
|
+
def test_calling_update_changing_ids_doesnt_change_counter_cache
|
1122
1439
|
topic1 = Topic.find(1)
|
1123
1440
|
topic2 = Topic.find(3)
|
1124
1441
|
original_count1 = topic1.replies.to_a.size
|
@@ -1127,17 +1444,20 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1127
1444
|
reply1 = topic1.replies.first
|
1128
1445
|
reply2 = topic2.replies.first
|
1129
1446
|
|
1130
|
-
reply1.
|
1447
|
+
reply1.update(parent_id: topic2.id)
|
1131
1448
|
assert_equal original_count1 - 1, topic1.reload.replies_count
|
1132
1449
|
assert_equal original_count2 + 1, topic2.reload.replies_count
|
1133
1450
|
|
1134
|
-
reply2.
|
1451
|
+
reply2.update(parent_id: topic1.id)
|
1135
1452
|
assert_equal original_count1, topic1.reload.replies_count
|
1136
1453
|
assert_equal original_count2, topic2.reload.replies_count
|
1137
1454
|
end
|
1138
1455
|
|
1139
1456
|
def test_deleting_a_collection
|
1140
1457
|
force_signal37_to_load_all_clients_of_firm
|
1458
|
+
|
1459
|
+
assert_predicate companies(:first_firm).clients_of_firm, :loaded?
|
1460
|
+
|
1141
1461
|
companies(:first_firm).clients_of_firm.create("name" => "Another Client")
|
1142
1462
|
assert_equal 3, companies(:first_firm).clients_of_firm.size
|
1143
1463
|
companies(:first_firm).clients_of_firm.delete([companies(:first_firm).clients_of_firm[0], companies(:first_firm).clients_of_firm[1], companies(:first_firm).clients_of_firm[2]])
|
@@ -1147,17 +1467,23 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1147
1467
|
|
1148
1468
|
def test_delete_all
|
1149
1469
|
force_signal37_to_load_all_clients_of_firm
|
1470
|
+
|
1471
|
+
assert_predicate companies(:first_firm).clients_of_firm, :loaded?
|
1472
|
+
|
1150
1473
|
companies(:first_firm).dependent_clients_of_firm.create("name" => "Another Client")
|
1151
1474
|
clients = companies(:first_firm).dependent_clients_of_firm.to_a
|
1152
1475
|
assert_equal 3, clients.count
|
1153
1476
|
|
1154
1477
|
assert_difference "Client.count", -(clients.count) do
|
1155
|
-
companies(:first_firm).dependent_clients_of_firm.delete_all
|
1478
|
+
assert_equal clients.count, companies(:first_firm).dependent_clients_of_firm.delete_all
|
1156
1479
|
end
|
1157
1480
|
end
|
1158
1481
|
|
1159
1482
|
def test_delete_all_with_not_yet_loaded_association_collection
|
1160
1483
|
force_signal37_to_load_all_clients_of_firm
|
1484
|
+
|
1485
|
+
assert_predicate companies(:first_firm).clients_of_firm, :loaded?
|
1486
|
+
|
1161
1487
|
companies(:first_firm).clients_of_firm.create("name" => "Another Client")
|
1162
1488
|
assert_equal 3, companies(:first_firm).clients_of_firm.size
|
1163
1489
|
companies(:first_firm).clients_of_firm.reset
|
@@ -1167,8 +1493,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1167
1493
|
end
|
1168
1494
|
|
1169
1495
|
def test_transaction_when_deleting_persisted
|
1170
|
-
good = Client.new(:
|
1171
|
-
bad = Client.new(:
|
1496
|
+
good = Client.new(name: "Good")
|
1497
|
+
bad = Client.new(name: "Bad", raise_on_destroy: true)
|
1172
1498
|
|
1173
1499
|
companies(:first_firm).clients_of_firm = [good, bad]
|
1174
1500
|
|
@@ -1181,8 +1507,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1181
1507
|
end
|
1182
1508
|
|
1183
1509
|
def test_transaction_when_deleting_new_record
|
1184
|
-
|
1185
|
-
|
1510
|
+
firm = Firm.new
|
1511
|
+
assert_queries(0) do
|
1186
1512
|
client = Client.new("name" => "New Client")
|
1187
1513
|
firm.clients_of_firm << client
|
1188
1514
|
firm.clients_of_firm.destroy(client)
|
@@ -1209,7 +1535,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1209
1535
|
def test_clearing_updates_counter_cache
|
1210
1536
|
topic = Topic.first
|
1211
1537
|
|
1212
|
-
assert_difference
|
1538
|
+
assert_difference "topic.reload.replies_count", -1 do
|
1213
1539
|
topic.replies.clear
|
1214
1540
|
end
|
1215
1541
|
end
|
@@ -1218,7 +1544,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1218
1544
|
car = Car.first
|
1219
1545
|
car.engines.create!
|
1220
1546
|
|
1221
|
-
assert_difference
|
1547
|
+
assert_difference "car.reload.engines_count", -1 do
|
1222
1548
|
car.engines.clear
|
1223
1549
|
end
|
1224
1550
|
end
|
@@ -1243,10 +1569,20 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1243
1569
|
def test_delete_all_with_option_delete_all
|
1244
1570
|
firm = companies(:first_firm)
|
1245
1571
|
client_id = firm.dependent_clients_of_firm.first.id
|
1246
|
-
firm.dependent_clients_of_firm.
|
1572
|
+
count = firm.dependent_clients_of_firm.count
|
1573
|
+
assert_equal count, firm.dependent_clients_of_firm.delete_all(:delete_all)
|
1247
1574
|
assert_nil Client.find_by_id(client_id)
|
1248
1575
|
end
|
1249
1576
|
|
1577
|
+
def test_delete_all_with_option_nullify
|
1578
|
+
firm = companies(:first_firm)
|
1579
|
+
client_id = firm.dependent_clients_of_firm.first.id
|
1580
|
+
count = firm.dependent_clients_of_firm.count
|
1581
|
+
assert_equal firm, Client.find(client_id).firm
|
1582
|
+
assert_equal count, firm.dependent_clients_of_firm.delete_all(:nullify)
|
1583
|
+
assert_nil Client.find(client_id).firm
|
1584
|
+
end
|
1585
|
+
|
1250
1586
|
def test_delete_all_accepts_limited_parameters
|
1251
1587
|
firm = companies(:first_firm)
|
1252
1588
|
assert_raise(ArgumentError) do
|
@@ -1276,8 +1612,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1276
1612
|
|
1277
1613
|
def test_dependent_association_respects_optional_conditions_on_delete
|
1278
1614
|
firm = companies(:odegy)
|
1279
|
-
Client.create(:
|
1280
|
-
Client.create(:
|
1615
|
+
Client.create(client_of: firm.id, name: "BigShot Inc.")
|
1616
|
+
Client.create(client_of: firm.id, name: "SmallTime Inc.")
|
1281
1617
|
# only one of two clients is included in the association due to the :conditions key
|
1282
1618
|
assert_equal 2, Client.where(client_of: firm.id).size
|
1283
1619
|
assert_equal 1, firm.dependent_conditional_clients_of_firm.size
|
@@ -1288,8 +1624,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1288
1624
|
|
1289
1625
|
def test_dependent_association_respects_optional_sanitized_conditions_on_delete
|
1290
1626
|
firm = companies(:odegy)
|
1291
|
-
Client.create(:
|
1292
|
-
Client.create(:
|
1627
|
+
Client.create(client_of: firm.id, name: "BigShot Inc.")
|
1628
|
+
Client.create(client_of: firm.id, name: "SmallTime Inc.")
|
1293
1629
|
# only one of two clients is included in the association due to the :conditions key
|
1294
1630
|
assert_equal 2, Client.where(client_of: firm.id).size
|
1295
1631
|
assert_equal 1, firm.dependent_sanitized_conditional_clients_of_firm.size
|
@@ -1300,11 +1636,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1300
1636
|
|
1301
1637
|
def test_dependent_association_respects_optional_hash_conditions_on_delete
|
1302
1638
|
firm = companies(:odegy)
|
1303
|
-
Client.create(:
|
1304
|
-
Client.create(:
|
1639
|
+
Client.create(client_of: firm.id, name: "BigShot Inc.")
|
1640
|
+
Client.create(client_of: firm.id, name: "SmallTime Inc.")
|
1305
1641
|
# only one of two clients is included in the association due to the :conditions key
|
1306
1642
|
assert_equal 2, Client.where(client_of: firm.id).size
|
1307
|
-
assert_equal 1, firm.
|
1643
|
+
assert_equal 1, firm.dependent_hash_conditional_clients_of_firm.size
|
1308
1644
|
firm.destroy
|
1309
1645
|
# only the correctly associated client should have been deleted
|
1310
1646
|
assert_equal 1, Client.where(client_of: firm.id).size
|
@@ -1326,13 +1662,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1326
1662
|
def test_creation_respects_hash_condition
|
1327
1663
|
ms_client = companies(:first_firm).clients_like_ms_with_hash_conditions.build
|
1328
1664
|
|
1329
|
-
assert
|
1330
|
-
assert_equal
|
1665
|
+
assert ms_client.save
|
1666
|
+
assert_equal "Microsoft", ms_client.name
|
1331
1667
|
|
1332
1668
|
another_ms_client = companies(:first_firm).clients_like_ms_with_hash_conditions.create
|
1333
1669
|
|
1334
|
-
|
1335
|
-
assert_equal
|
1670
|
+
assert_predicate another_ms_client, :persisted?
|
1671
|
+
assert_equal "Microsoft", another_ms_client.name
|
1336
1672
|
end
|
1337
1673
|
|
1338
1674
|
def test_clearing_without_initial_access
|
@@ -1346,7 +1682,10 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1346
1682
|
|
1347
1683
|
def test_deleting_a_item_which_is_not_in_the_collection
|
1348
1684
|
force_signal37_to_load_all_clients_of_firm
|
1349
|
-
|
1685
|
+
|
1686
|
+
assert_predicate companies(:first_firm).clients_of_firm, :loaded?
|
1687
|
+
|
1688
|
+
summit = Client.find_by_name("Summit")
|
1350
1689
|
companies(:first_firm).clients_of_firm.delete(summit)
|
1351
1690
|
assert_equal 2, companies(:first_firm).clients_of_firm.size
|
1352
1691
|
assert_equal 2, companies(:first_firm).clients_of_firm.reload.size
|
@@ -1356,7 +1695,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1356
1695
|
def test_deleting_by_integer_id
|
1357
1696
|
david = Developer.find(1)
|
1358
1697
|
|
1359
|
-
assert_difference
|
1698
|
+
assert_difference "david.projects.count", -1 do
|
1360
1699
|
assert_equal 1, david.projects.delete(1).size
|
1361
1700
|
end
|
1362
1701
|
|
@@ -1366,8 +1705,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1366
1705
|
def test_deleting_by_string_id
|
1367
1706
|
david = Developer.find(1)
|
1368
1707
|
|
1369
|
-
assert_difference
|
1370
|
-
assert_equal 1, david.projects.delete(
|
1708
|
+
assert_difference "david.projects.count", -1 do
|
1709
|
+
assert_equal 1, david.projects.delete("1").size
|
1371
1710
|
end
|
1372
1711
|
|
1373
1712
|
assert_equal 1, david.projects.size
|
@@ -1382,6 +1721,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1382
1721
|
def test_destroying
|
1383
1722
|
force_signal37_to_load_all_clients_of_firm
|
1384
1723
|
|
1724
|
+
assert_predicate companies(:first_firm).clients_of_firm, :loaded?
|
1725
|
+
|
1385
1726
|
assert_difference "Client.count", -1 do
|
1386
1727
|
companies(:first_firm).clients_of_firm.destroy(companies(:first_firm).clients_of_firm.first)
|
1387
1728
|
end
|
@@ -1393,6 +1734,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1393
1734
|
def test_destroying_by_integer_id
|
1394
1735
|
force_signal37_to_load_all_clients_of_firm
|
1395
1736
|
|
1737
|
+
assert_predicate companies(:first_firm).clients_of_firm, :loaded?
|
1738
|
+
|
1396
1739
|
assert_difference "Client.count", -1 do
|
1397
1740
|
companies(:first_firm).clients_of_firm.destroy(companies(:first_firm).clients_of_firm.first.id)
|
1398
1741
|
end
|
@@ -1404,6 +1747,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1404
1747
|
def test_destroying_by_string_id
|
1405
1748
|
force_signal37_to_load_all_clients_of_firm
|
1406
1749
|
|
1750
|
+
assert_predicate companies(:first_firm).clients_of_firm, :loaded?
|
1751
|
+
|
1407
1752
|
assert_difference "Client.count", -1 do
|
1408
1753
|
companies(:first_firm).clients_of_firm.destroy(companies(:first_firm).clients_of_firm.first.id.to_s)
|
1409
1754
|
end
|
@@ -1414,6 +1759,9 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1414
1759
|
|
1415
1760
|
def test_destroying_a_collection
|
1416
1761
|
force_signal37_to_load_all_clients_of_firm
|
1762
|
+
|
1763
|
+
assert_predicate companies(:first_firm).clients_of_firm, :loaded?
|
1764
|
+
|
1417
1765
|
companies(:first_firm).clients_of_firm.create("name" => "Another Client")
|
1418
1766
|
assert_equal 3, companies(:first_firm).clients_of_firm.size
|
1419
1767
|
|
@@ -1427,8 +1775,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1427
1775
|
|
1428
1776
|
def test_destroy_all
|
1429
1777
|
force_signal37_to_load_all_clients_of_firm
|
1778
|
+
|
1779
|
+
assert_predicate companies(:first_firm).clients_of_firm, :loaded?
|
1780
|
+
|
1430
1781
|
clients = companies(:first_firm).clients_of_firm.to_a
|
1431
|
-
|
1782
|
+
assert_not clients.empty?, "37signals has clients after load"
|
1432
1783
|
destroyed = companies(:first_firm).clients_of_firm.destroy_all
|
1433
1784
|
assert_equal clients.sort_by(&:id), destroyed.sort_by(&:id)
|
1434
1785
|
assert destroyed.all?(&:frozen?), "destroyed clients should be frozen"
|
@@ -1436,21 +1787,52 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1436
1787
|
assert companies(:first_firm).clients_of_firm.reload.empty?, "37signals has no clients after destroy all and refresh"
|
1437
1788
|
end
|
1438
1789
|
|
1790
|
+
def test_destroy_all_on_association_clears_scope
|
1791
|
+
author = Author.create!(name: "Gannon")
|
1792
|
+
posts = author.posts
|
1793
|
+
posts.create!(title: "test", body: "body")
|
1794
|
+
posts.destroy_all
|
1795
|
+
assert_nil posts.first
|
1796
|
+
end
|
1797
|
+
|
1798
|
+
def test_destroy_all_on_desynced_counter_cache_association
|
1799
|
+
category = categories(:general)
|
1800
|
+
assert_operator category.categorizations.count, :>, 0
|
1801
|
+
|
1802
|
+
category.categorizations.destroy_all
|
1803
|
+
assert_equal 0, category.categorizations.count
|
1804
|
+
end
|
1805
|
+
|
1806
|
+
def test_destroy_on_association_clears_scope
|
1807
|
+
author = Author.create!(name: "Gannon")
|
1808
|
+
posts = author.posts
|
1809
|
+
post = posts.create!(title: "test", body: "body")
|
1810
|
+
posts.destroy(post)
|
1811
|
+
assert_nil posts.first
|
1812
|
+
end
|
1813
|
+
|
1814
|
+
def test_delete_on_association_clears_scope
|
1815
|
+
author = Author.create!(name: "Gannon")
|
1816
|
+
posts = author.posts
|
1817
|
+
post = posts.create!(title: "test", body: "body")
|
1818
|
+
posts.delete(post)
|
1819
|
+
assert_nil posts.first
|
1820
|
+
end
|
1821
|
+
|
1439
1822
|
def test_dependence
|
1440
1823
|
firm = companies(:first_firm)
|
1441
1824
|
assert_equal 3, firm.clients.size
|
1442
1825
|
firm.destroy
|
1443
|
-
|
1826
|
+
assert_empty Client.all.merge!(where: "firm_id=#{firm.id}").to_a
|
1444
1827
|
end
|
1445
1828
|
|
1446
1829
|
def test_dependence_for_associations_with_hash_condition
|
1447
1830
|
david = authors(:david)
|
1448
|
-
assert_difference(
|
1831
|
+
assert_difference("Post.count", -1) { assert david.destroy }
|
1449
1832
|
end
|
1450
1833
|
|
1451
1834
|
def test_destroy_dependent_when_deleted_from_association
|
1452
|
-
|
1453
|
-
firm = Firm.all.merge!(:order => "id").first
|
1835
|
+
firm = Firm.first
|
1454
1836
|
assert_equal 3, firm.clients.size
|
1455
1837
|
|
1456
1838
|
client = firm.clients.first
|
@@ -1477,7 +1859,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1477
1859
|
|
1478
1860
|
firm.destroy rescue "do nothing"
|
1479
1861
|
|
1480
|
-
assert_equal 3, Client.all.merge!(:
|
1862
|
+
assert_equal 3, Client.all.merge!(where: "firm_id=#{firm.id}").to_a.size
|
1481
1863
|
end
|
1482
1864
|
|
1483
1865
|
def test_dependence_on_account
|
@@ -1491,7 +1873,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1491
1873
|
|
1492
1874
|
core = companies(:rails_core)
|
1493
1875
|
assert_equal accounts(:rails_core_account), core.account
|
1494
|
-
assert_equal companies(:leetsoft, :jadedpixel), core.companies
|
1876
|
+
assert_equal companies(:leetsoft, :jadedpixel).sort_by(&:id), core.companies.sort_by(&:id)
|
1495
1877
|
core.destroy
|
1496
1878
|
assert_nil accounts(:rails_core_account).reload.firm_id
|
1497
1879
|
assert_nil companies(:leetsoft).reload.client_of
|
@@ -1500,66 +1882,62 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1500
1882
|
assert_equal num_accounts, Account.count
|
1501
1883
|
end
|
1502
1884
|
|
1503
|
-
def
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
assert_raise(ActiveRecord::DeleteRestrictionError) { firm.destroy }
|
1509
|
-
assert RestrictedWithExceptionFirm.exists?(:name => 'restrict')
|
1510
|
-
assert firm.companies.exists?(:name => 'child')
|
1511
|
-
end
|
1512
|
-
|
1513
|
-
def test_restrict_with_error_is_deprecated_using_key_many
|
1514
|
-
I18n.backend = I18n::Backend::Simple.new
|
1515
|
-
I18n.backend.store_translations :en, activerecord: { errors: { messages: { restrict_dependent_destroy: { many: 'message for deprecated key' } } } }
|
1885
|
+
def test_depends_and_nullify_on_polymorphic_assoc
|
1886
|
+
author = PersonWithPolymorphicDependentNullifyComments.create!(first_name: "Laertis")
|
1887
|
+
comment = posts(:welcome).comments.first
|
1888
|
+
comment.author = author
|
1889
|
+
comment.save!
|
1516
1890
|
|
1517
|
-
|
1518
|
-
|
1891
|
+
assert_equal comment.author_id, author.id
|
1892
|
+
assert_equal comment.author_type, author.class.name
|
1519
1893
|
|
1520
|
-
|
1894
|
+
author.destroy
|
1895
|
+
comment.reload
|
1521
1896
|
|
1522
|
-
|
1897
|
+
assert_nil comment.author_id
|
1898
|
+
assert_nil comment.author_type
|
1899
|
+
end
|
1523
1900
|
|
1524
|
-
|
1901
|
+
def test_restrict_with_exception
|
1902
|
+
firm = RestrictedWithExceptionFirm.create!(name: "restrict")
|
1903
|
+
firm.companies.create(name: "child")
|
1525
1904
|
|
1526
|
-
|
1527
|
-
|
1528
|
-
assert
|
1529
|
-
|
1530
|
-
I18n.backend.reload!
|
1905
|
+
assert_not_empty firm.companies
|
1906
|
+
assert_raise(ActiveRecord::DeleteRestrictionError) { firm.destroy }
|
1907
|
+
assert RestrictedWithExceptionFirm.exists?(name: "restrict")
|
1908
|
+
assert firm.companies.exists?(name: "child")
|
1531
1909
|
end
|
1532
1910
|
|
1533
1911
|
def test_restrict_with_error
|
1534
|
-
firm = RestrictedWithErrorFirm.create!(:
|
1535
|
-
firm.companies.create(:
|
1912
|
+
firm = RestrictedWithErrorFirm.create!(name: "restrict")
|
1913
|
+
firm.companies.create(name: "child")
|
1536
1914
|
|
1537
|
-
|
1915
|
+
assert_not_empty firm.companies
|
1538
1916
|
|
1539
1917
|
firm.destroy
|
1540
1918
|
|
1541
|
-
|
1919
|
+
assert_not_empty firm.errors
|
1542
1920
|
|
1543
1921
|
assert_equal "Cannot delete record because dependent companies exist", firm.errors[:base].first
|
1544
|
-
assert RestrictedWithErrorFirm.exists?(:
|
1545
|
-
assert firm.companies.exists?(:
|
1922
|
+
assert RestrictedWithErrorFirm.exists?(name: "restrict")
|
1923
|
+
assert firm.companies.exists?(name: "child")
|
1546
1924
|
end
|
1547
1925
|
|
1548
1926
|
def test_restrict_with_error_with_locale
|
1549
1927
|
I18n.backend = I18n::Backend::Simple.new
|
1550
|
-
I18n.backend.store_translations
|
1551
|
-
firm = RestrictedWithErrorFirm.create!(name:
|
1552
|
-
firm.companies.create(name:
|
1928
|
+
I18n.backend.store_translations "en", activerecord: { attributes: { restricted_with_error_firm: { companies: "client companies" } } }
|
1929
|
+
firm = RestrictedWithErrorFirm.create!(name: "restrict")
|
1930
|
+
firm.companies.create(name: "child")
|
1553
1931
|
|
1554
|
-
|
1932
|
+
assert_not_empty firm.companies
|
1555
1933
|
|
1556
1934
|
firm.destroy
|
1557
1935
|
|
1558
|
-
|
1936
|
+
assert_not_empty firm.errors
|
1559
1937
|
|
1560
1938
|
assert_equal "Cannot delete record because dependent client companies exist", firm.errors[:base].first
|
1561
|
-
assert RestrictedWithErrorFirm.exists?(name:
|
1562
|
-
assert firm.companies.exists?(name:
|
1939
|
+
assert RestrictedWithErrorFirm.exists?(name: "restrict")
|
1940
|
+
assert firm.companies.exists?(name: "child")
|
1563
1941
|
ensure
|
1564
1942
|
I18n.backend.reload!
|
1565
1943
|
end
|
@@ -1569,10 +1947,10 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1569
1947
|
end
|
1570
1948
|
|
1571
1949
|
def test_included_in_collection_for_new_records
|
1572
|
-
client = Client.create(:
|
1950
|
+
client = Client.create(name: "Persisted")
|
1573
1951
|
assert_nil client.client_of
|
1574
1952
|
assert_equal false, Firm.new.clients_of_firm.include?(client),
|
1575
|
-
|
1953
|
+
"includes a client that does not belong to any firm"
|
1576
1954
|
end
|
1577
1955
|
|
1578
1956
|
def test_adding_array_and_collection
|
@@ -1580,7 +1958,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1580
1958
|
end
|
1581
1959
|
|
1582
1960
|
def test_replace_with_less
|
1583
|
-
firm = Firm.
|
1961
|
+
firm = Firm.first
|
1584
1962
|
firm.clients = [companies(:first_client)]
|
1585
1963
|
assert firm.save, "Could not save firm"
|
1586
1964
|
firm.reload
|
@@ -1594,7 +1972,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1594
1972
|
end
|
1595
1973
|
|
1596
1974
|
def test_replace_with_new
|
1597
|
-
firm = Firm.
|
1975
|
+
firm = Firm.first
|
1598
1976
|
firm.clients = [companies(:second_client), Client.new("name" => "New Client")]
|
1599
1977
|
firm.save
|
1600
1978
|
firm.reload
|
@@ -1607,8 +1985,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1607
1985
|
account = Account.new
|
1608
1986
|
orig_accounts = firm.accounts.to_a
|
1609
1987
|
|
1610
|
-
|
1611
|
-
|
1988
|
+
assert_not_predicate account, :valid?
|
1989
|
+
assert_not_empty orig_accounts
|
1612
1990
|
error = assert_raise ActiveRecord::RecordNotSaved do
|
1613
1991
|
firm.accounts = [account]
|
1614
1992
|
end
|
@@ -1623,16 +2001,16 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1623
2001
|
firm.clients = []
|
1624
2002
|
firm.save
|
1625
2003
|
|
1626
|
-
|
2004
|
+
assert_no_queries do
|
1627
2005
|
firm.clients = []
|
1628
2006
|
end
|
1629
2007
|
|
1630
|
-
assert_equal [], firm.
|
2008
|
+
assert_equal [], firm.public_send("clients=", [])
|
1631
2009
|
end
|
1632
2010
|
|
1633
2011
|
def test_transactions_when_replacing_on_persisted
|
1634
|
-
good = Client.new(:
|
1635
|
-
bad = Client.new(:
|
2012
|
+
good = Client.new(name: "Good")
|
2013
|
+
bad = Client.new(name: "Bad", raise_on_save: true)
|
1636
2014
|
|
1637
2015
|
companies(:first_firm).clients_of_firm = [good]
|
1638
2016
|
|
@@ -1645,8 +2023,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1645
2023
|
end
|
1646
2024
|
|
1647
2025
|
def test_transactions_when_replacing_on_new_record
|
1648
|
-
|
1649
|
-
|
2026
|
+
firm = Firm.new
|
2027
|
+
assert_queries(0) do
|
1650
2028
|
firm.clients_of_firm = [Client.new("name" => "New Client")]
|
1651
2029
|
end
|
1652
2030
|
end
|
@@ -1658,7 +2036,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1658
2036
|
def test_get_ids_for_loaded_associations
|
1659
2037
|
company = companies(:first_firm)
|
1660
2038
|
company.clients.reload
|
1661
|
-
|
2039
|
+
assert_no_queries do
|
1662
2040
|
company.client_ids
|
1663
2041
|
company.client_ids
|
1664
2042
|
end
|
@@ -1666,9 +2044,29 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1666
2044
|
|
1667
2045
|
def test_get_ids_for_unloaded_associations_does_not_load_them
|
1668
2046
|
company = companies(:first_firm)
|
1669
|
-
|
2047
|
+
assert_not_predicate company.clients, :loaded?
|
1670
2048
|
assert_equal [companies(:first_client).id, companies(:second_client).id, companies(:another_first_firm_client).id], company.client_ids
|
1671
|
-
|
2049
|
+
assert_not_predicate company.clients, :loaded?
|
2050
|
+
end
|
2051
|
+
|
2052
|
+
def test_counter_cache_on_unloaded_association
|
2053
|
+
car = Car.create(name: "My AppliCar")
|
2054
|
+
assert_equal 0, car.engines.size
|
2055
|
+
end
|
2056
|
+
|
2057
|
+
def test_ids_reader_cache_not_used_for_size_when_association_is_dirty
|
2058
|
+
firm = Firm.create!(name: "Startup")
|
2059
|
+
assert_equal 0, firm.client_ids.size
|
2060
|
+
firm.clients.build
|
2061
|
+
assert_equal 1, firm.clients.size
|
2062
|
+
end
|
2063
|
+
|
2064
|
+
def test_ids_reader_cache_should_be_cleared_when_collection_is_deleted
|
2065
|
+
firm = companies(:first_firm)
|
2066
|
+
assert_equal [2, 3, 11], firm.client_ids
|
2067
|
+
client = firm.clients.first
|
2068
|
+
firm.clients.delete(client)
|
2069
|
+
assert_equal [3, 11], firm.client_ids
|
1672
2070
|
end
|
1673
2071
|
|
1674
2072
|
def test_get_ids_ignores_include_option
|
@@ -1680,9 +2078,6 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1680
2078
|
end
|
1681
2079
|
|
1682
2080
|
def test_get_ids_for_association_on_new_record_does_not_try_to_find_records
|
1683
|
-
Company.columns # Load schema information so we don't query below
|
1684
|
-
Contract.columns # if running just this test.
|
1685
|
-
|
1686
2081
|
company = Company.new
|
1687
2082
|
assert_queries(0) do
|
1688
2083
|
company.contract_ids
|
@@ -1695,7 +2090,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1695
2090
|
contract_a = Contract.create!
|
1696
2091
|
contract_b = Contract.create!
|
1697
2092
|
Contract.create! # another contract
|
1698
|
-
company = Company.new(:
|
2093
|
+
company = Company.new(name: "Some Company")
|
1699
2094
|
|
1700
2095
|
company.contract_ids = [contract_a.id, contract_b.id]
|
1701
2096
|
assert_equal [contract_a.id, contract_b.id], company.contract_ids
|
@@ -1707,8 +2102,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1707
2102
|
end
|
1708
2103
|
|
1709
2104
|
def test_assign_ids_ignoring_blanks
|
1710
|
-
firm = Firm.create!(:
|
1711
|
-
firm.client_ids = [companies(:first_client).id, nil, companies(:second_client).id,
|
2105
|
+
firm = Firm.create!(name: "Apple")
|
2106
|
+
firm.client_ids = [companies(:first_client).id, nil, companies(:second_client).id, ""]
|
1712
2107
|
firm.save!
|
1713
2108
|
|
1714
2109
|
assert_equal 2, firm.clients.reload.size
|
@@ -1723,19 +2118,28 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1723
2118
|
[
|
1724
2119
|
lambda { authors(:mary).comment_ids = [comments(:greetings).id, comments(:more_greetings).id] },
|
1725
2120
|
lambda { authors(:mary).comments = [comments(:greetings), comments(:more_greetings)] },
|
1726
|
-
lambda { authors(:mary).comments << Comment.create!(:
|
2121
|
+
lambda { authors(:mary).comments << Comment.create!(body: "Yay", post_id: 424242) },
|
1727
2122
|
lambda { authors(:mary).comments.delete(authors(:mary).comments.first) },
|
1728
|
-
].each {|block| assert_raise(ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection, &block) }
|
2123
|
+
].each { |block| assert_raise(ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection, &block) }
|
2124
|
+
end
|
2125
|
+
|
2126
|
+
def test_associations_order_should_be_priority_over_throughs_order
|
2127
|
+
original = authors(:david)
|
2128
|
+
expected = [13, 12, 10, 9, 8, 7, 6, 5, 3, 2, 1]
|
2129
|
+
assert_equal expected, original.comments_desc.map(&:id)
|
2130
|
+
preloaded = Author.includes(:comments_desc).find(original.id)
|
2131
|
+
assert_equal expected, preloaded.comments_desc.map(&:id)
|
2132
|
+
assert_equal original.posts_sorted_by_id.first.comments.map(&:id), preloaded.posts_sorted_by_id.first.comments.map(&:id)
|
1729
2133
|
end
|
1730
2134
|
|
1731
2135
|
def test_dynamic_find_should_respect_association_order_for_through
|
1732
2136
|
assert_equal Comment.find(10), authors(:david).comments_desc.where("comments.type = 'SpecialComment'").first
|
1733
|
-
assert_equal Comment.find(10), authors(:david).comments_desc.find_by_type(
|
2137
|
+
assert_equal Comment.find(10), authors(:david).comments_desc.find_by_type("SpecialComment")
|
1734
2138
|
end
|
1735
2139
|
|
1736
2140
|
def test_has_many_through_respects_hash_conditions
|
1737
|
-
assert_equal authors(:david).hello_posts, authors(:david).hello_posts_with_hash_conditions
|
1738
|
-
assert_equal authors(:david).hello_post_comments, authors(:david).hello_post_comments_with_hash_conditions
|
2141
|
+
assert_equal authors(:david).hello_posts.sort_by(&:id), authors(:david).hello_posts_with_hash_conditions.sort_by(&:id)
|
2142
|
+
assert_equal authors(:david).hello_post_comments.sort_by(&:id), authors(:david).hello_post_comments_with_hash_conditions.sort_by(&:id)
|
1739
2143
|
end
|
1740
2144
|
|
1741
2145
|
def test_include_uses_array_include_after_loaded
|
@@ -1745,7 +2149,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1745
2149
|
client = firm.clients.first
|
1746
2150
|
|
1747
2151
|
assert_no_queries do
|
1748
|
-
|
2152
|
+
assert_predicate firm.clients, :loaded?
|
1749
2153
|
assert_equal true, firm.clients.include?(client)
|
1750
2154
|
end
|
1751
2155
|
end
|
@@ -1755,18 +2159,18 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1755
2159
|
client = firm.clients.first
|
1756
2160
|
|
1757
2161
|
firm.reload
|
1758
|
-
|
2162
|
+
assert_not_predicate firm.clients, :loaded?
|
1759
2163
|
assert_queries(1) do
|
1760
2164
|
assert_equal true, firm.clients.include?(client)
|
1761
2165
|
end
|
1762
|
-
|
2166
|
+
assert_not_predicate firm.clients, :loaded?
|
1763
2167
|
end
|
1764
2168
|
|
1765
2169
|
def test_include_returns_false_for_non_matching_record_to_verify_scoping
|
1766
2170
|
firm = companies(:first_firm)
|
1767
|
-
client = Client.create!(:
|
2171
|
+
client = Client.create!(name: "Not Associated")
|
1768
2172
|
|
1769
|
-
|
2173
|
+
assert_not_predicate firm.clients, :loaded?
|
1770
2174
|
assert_equal false, firm.clients.include?(client)
|
1771
2175
|
end
|
1772
2176
|
|
@@ -1775,15 +2179,15 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1775
2179
|
firm.clients.first
|
1776
2180
|
firm.clients.second
|
1777
2181
|
firm.clients.last
|
1778
|
-
|
2182
|
+
assert_not_predicate firm.clients, :loaded?
|
1779
2183
|
end
|
1780
2184
|
|
1781
2185
|
def test_calling_first_or_last_on_loaded_association_should_not_fetch_with_query
|
1782
2186
|
firm = companies(:first_firm)
|
1783
2187
|
firm.clients.load_target
|
1784
|
-
|
2188
|
+
assert_predicate firm.clients, :loaded?
|
1785
2189
|
|
1786
|
-
assert_no_queries
|
2190
|
+
assert_no_queries do
|
1787
2191
|
firm.clients.first
|
1788
2192
|
assert_equal 2, firm.clients.first(2).size
|
1789
2193
|
firm.clients.last
|
@@ -1791,10 +2195,10 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1791
2195
|
end
|
1792
2196
|
end
|
1793
2197
|
|
1794
|
-
def
|
2198
|
+
def test_calling_first_nth_or_last_on_existing_record_with_build_should_load_association
|
1795
2199
|
firm = companies(:first_firm)
|
1796
|
-
firm.clients.build(:
|
1797
|
-
|
2200
|
+
firm.clients.build(name: "Foo")
|
2201
|
+
assert_not_predicate firm.clients, :loaded?
|
1798
2202
|
|
1799
2203
|
assert_queries 1 do
|
1800
2204
|
firm.clients.first
|
@@ -1802,13 +2206,31 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1802
2206
|
firm.clients.last
|
1803
2207
|
end
|
1804
2208
|
|
1805
|
-
|
2209
|
+
assert_predicate firm.clients, :loaded?
|
2210
|
+
|
2211
|
+
author = Author.create!(name: "Carl")
|
2212
|
+
third = topics(:third)
|
2213
|
+
fourth = topics(:fourth).becomes(Topic)
|
2214
|
+
|
2215
|
+
new_topic = author.topics_without_type.build
|
2216
|
+
|
2217
|
+
assert_not_predicate author.topics_without_type, :loaded?
|
2218
|
+
|
2219
|
+
assert_queries(1) do
|
2220
|
+
if current_adapter?(:Mysql2Adapter, :SQLite3Adapter)
|
2221
|
+
assert_equal fourth, author.topics_without_type.first
|
2222
|
+
assert_equal third, author.topics_without_type.second
|
2223
|
+
end
|
2224
|
+
assert_equal new_topic, author.topics_without_type.last
|
2225
|
+
end
|
2226
|
+
|
2227
|
+
assert_predicate author.topics_without_type, :loaded?
|
1806
2228
|
end
|
1807
2229
|
|
1808
2230
|
def test_calling_first_nth_or_last_on_existing_record_with_create_should_not_load_association
|
1809
2231
|
firm = companies(:first_firm)
|
1810
|
-
firm.clients.create(:
|
1811
|
-
|
2232
|
+
firm.clients.create(name: "Foo")
|
2233
|
+
assert_not_predicate firm.clients, :loaded?
|
1812
2234
|
|
1813
2235
|
assert_queries 3 do
|
1814
2236
|
firm.clients.first
|
@@ -1816,7 +2238,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1816
2238
|
firm.clients.last
|
1817
2239
|
end
|
1818
2240
|
|
1819
|
-
|
2241
|
+
assert_not_predicate firm.clients, :loaded?
|
1820
2242
|
end
|
1821
2243
|
|
1822
2244
|
def test_calling_first_nth_or_last_on_new_record_should_not_run_queries
|
@@ -1831,15 +2253,15 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1831
2253
|
|
1832
2254
|
def test_calling_first_or_last_with_integer_on_association_should_not_load_association
|
1833
2255
|
firm = companies(:first_firm)
|
1834
|
-
firm.clients.create(:
|
1835
|
-
|
2256
|
+
firm.clients.create(name: "Foo")
|
2257
|
+
assert_not_predicate firm.clients, :loaded?
|
1836
2258
|
|
1837
2259
|
assert_queries 2 do
|
1838
2260
|
firm.clients.first(2)
|
1839
2261
|
firm.clients.last(2)
|
1840
2262
|
end
|
1841
2263
|
|
1842
|
-
|
2264
|
+
assert_not_predicate firm.clients, :loaded?
|
1843
2265
|
end
|
1844
2266
|
|
1845
2267
|
def test_calling_many_should_count_instead_of_loading_association
|
@@ -1847,37 +2269,38 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1847
2269
|
assert_queries(1) do
|
1848
2270
|
firm.clients.many? # use count query
|
1849
2271
|
end
|
1850
|
-
|
2272
|
+
assert_not_predicate firm.clients, :loaded?
|
1851
2273
|
end
|
1852
2274
|
|
1853
2275
|
def test_calling_many_on_loaded_association_should_not_use_query
|
1854
2276
|
firm = companies(:first_firm)
|
1855
|
-
firm.clients.
|
2277
|
+
firm.clients.load # force load
|
1856
2278
|
assert_no_queries { assert firm.clients.many? }
|
1857
2279
|
end
|
1858
2280
|
|
1859
2281
|
def test_calling_many_should_defer_to_collection_if_using_a_block
|
1860
2282
|
firm = companies(:first_firm)
|
1861
2283
|
assert_queries(1) do
|
1862
|
-
firm.clients
|
1863
|
-
|
2284
|
+
assert_not_called(firm.clients, :size) do
|
2285
|
+
firm.clients.many? { true }
|
2286
|
+
end
|
1864
2287
|
end
|
1865
|
-
|
2288
|
+
assert_predicate firm.clients, :loaded?
|
1866
2289
|
end
|
1867
2290
|
|
1868
2291
|
def test_calling_many_should_return_false_if_none_or_one
|
1869
2292
|
firm = companies(:another_firm)
|
1870
|
-
|
2293
|
+
assert_not_predicate firm.clients_like_ms, :many?
|
1871
2294
|
assert_equal 0, firm.clients_like_ms.size
|
1872
2295
|
|
1873
2296
|
firm = companies(:first_firm)
|
1874
|
-
|
2297
|
+
assert_not_predicate firm.limited_clients, :many?
|
1875
2298
|
assert_equal 1, firm.limited_clients.size
|
1876
2299
|
end
|
1877
2300
|
|
1878
2301
|
def test_calling_many_should_return_true_if_more_than_one
|
1879
2302
|
firm = companies(:first_firm)
|
1880
|
-
|
2303
|
+
assert_predicate firm.clients, :many?
|
1881
2304
|
assert_equal 3, firm.clients.size
|
1882
2305
|
end
|
1883
2306
|
|
@@ -1886,33 +2309,34 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1886
2309
|
assert_queries(1) do
|
1887
2310
|
firm.clients.none? # use count query
|
1888
2311
|
end
|
1889
|
-
|
2312
|
+
assert_not_predicate firm.clients, :loaded?
|
1890
2313
|
end
|
1891
2314
|
|
1892
2315
|
def test_calling_none_on_loaded_association_should_not_use_query
|
1893
2316
|
firm = companies(:first_firm)
|
1894
|
-
firm.clients.
|
1895
|
-
assert_no_queries {
|
2317
|
+
firm.clients.load # force load
|
2318
|
+
assert_no_queries { assert_not firm.clients.none? }
|
1896
2319
|
end
|
1897
2320
|
|
1898
2321
|
def test_calling_none_should_defer_to_collection_if_using_a_block
|
1899
2322
|
firm = companies(:first_firm)
|
1900
2323
|
assert_queries(1) do
|
1901
|
-
firm.clients
|
1902
|
-
|
2324
|
+
assert_not_called(firm.clients, :size) do
|
2325
|
+
firm.clients.none? { true }
|
2326
|
+
end
|
1903
2327
|
end
|
1904
|
-
|
2328
|
+
assert_predicate firm.clients, :loaded?
|
1905
2329
|
end
|
1906
2330
|
|
1907
2331
|
def test_calling_none_should_return_true_if_none
|
1908
2332
|
firm = companies(:another_firm)
|
1909
|
-
|
2333
|
+
assert_predicate firm.clients_like_ms, :none?
|
1910
2334
|
assert_equal 0, firm.clients_like_ms.size
|
1911
2335
|
end
|
1912
2336
|
|
1913
2337
|
def test_calling_none_should_return_false_if_any
|
1914
2338
|
firm = companies(:first_firm)
|
1915
|
-
|
2339
|
+
assert_not_predicate firm.limited_clients, :none?
|
1916
2340
|
assert_equal 1, firm.limited_clients.size
|
1917
2341
|
end
|
1918
2342
|
|
@@ -1921,39 +2345,40 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1921
2345
|
assert_queries(1) do
|
1922
2346
|
firm.clients.one? # use count query
|
1923
2347
|
end
|
1924
|
-
|
2348
|
+
assert_not_predicate firm.clients, :loaded?
|
1925
2349
|
end
|
1926
2350
|
|
1927
2351
|
def test_calling_one_on_loaded_association_should_not_use_query
|
1928
2352
|
firm = companies(:first_firm)
|
1929
|
-
firm.clients.
|
1930
|
-
assert_no_queries {
|
2353
|
+
firm.clients.load # force load
|
2354
|
+
assert_no_queries { assert_not firm.clients.one? }
|
1931
2355
|
end
|
1932
2356
|
|
1933
2357
|
def test_calling_one_should_defer_to_collection_if_using_a_block
|
1934
2358
|
firm = companies(:first_firm)
|
1935
2359
|
assert_queries(1) do
|
1936
|
-
firm.clients
|
1937
|
-
|
2360
|
+
assert_not_called(firm.clients, :size) do
|
2361
|
+
firm.clients.one? { true }
|
2362
|
+
end
|
1938
2363
|
end
|
1939
|
-
|
2364
|
+
assert_predicate firm.clients, :loaded?
|
1940
2365
|
end
|
1941
2366
|
|
1942
2367
|
def test_calling_one_should_return_false_if_zero
|
1943
2368
|
firm = companies(:another_firm)
|
1944
|
-
|
2369
|
+
assert_not_predicate firm.clients_like_ms, :one?
|
1945
2370
|
assert_equal 0, firm.clients_like_ms.size
|
1946
2371
|
end
|
1947
2372
|
|
1948
2373
|
def test_calling_one_should_return_true_if_one
|
1949
2374
|
firm = companies(:first_firm)
|
1950
|
-
|
2375
|
+
assert_predicate firm.limited_clients, :one?
|
1951
2376
|
assert_equal 1, firm.limited_clients.size
|
1952
2377
|
end
|
1953
2378
|
|
1954
2379
|
def test_calling_one_should_return_false_if_more_than_one
|
1955
2380
|
firm = companies(:first_firm)
|
1956
|
-
|
2381
|
+
assert_not_predicate firm.clients, :one?
|
1957
2382
|
assert_equal 3, firm.clients.size
|
1958
2383
|
end
|
1959
2384
|
|
@@ -1961,13 +2386,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1961
2386
|
old = ActiveRecord::Base.store_full_sti_class
|
1962
2387
|
ActiveRecord::Base.store_full_sti_class = true
|
1963
2388
|
|
1964
|
-
firm = Namespaced::Firm.create(
|
1965
|
-
firm.clients.create(
|
2389
|
+
firm = Namespaced::Firm.create(name: "Some Company")
|
2390
|
+
firm.clients.create(name: "Some Client")
|
1966
2391
|
|
1967
2392
|
stats = Namespaced::Firm.all.merge!(
|
1968
|
-
:
|
1969
|
-
:
|
1970
|
-
:
|
2393
|
+
select: "#{Namespaced::Firm.table_name}.id, COUNT(#{Namespaced::Client.table_name}.id) AS num_clients",
|
2394
|
+
joins: :clients,
|
2395
|
+
group: "#{Namespaced::Firm.table_name}.id"
|
1971
2396
|
).find firm.id
|
1972
2397
|
assert_equal 1, stats.num_clients.to_i
|
1973
2398
|
ensure
|
@@ -1975,9 +2400,10 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1975
2400
|
end
|
1976
2401
|
|
1977
2402
|
def test_association_proxy_transaction_method_starts_transaction_in_association_class
|
1978
|
-
Comment
|
1979
|
-
|
1980
|
-
|
2403
|
+
assert_called(Comment, :transaction) do
|
2404
|
+
Post.first.comments.transaction do
|
2405
|
+
# nothing
|
2406
|
+
end
|
1981
2407
|
end
|
1982
2408
|
end
|
1983
2409
|
|
@@ -1986,43 +2412,45 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
1986
2412
|
assert_equal client_association.new.attributes, client_association.send(:new).attributes
|
1987
2413
|
end
|
1988
2414
|
|
1989
|
-
def test_respond_to_private_class_methods
|
1990
|
-
client_association = companies(:first_firm).clients
|
1991
|
-
assert !client_association.respond_to?(:private_method)
|
1992
|
-
assert client_association.respond_to?(:private_method, true)
|
1993
|
-
end
|
1994
|
-
|
1995
2415
|
def test_creating_using_primary_key
|
1996
|
-
firm = Firm.
|
1997
|
-
client = firm.clients_using_primary_key.create!(:
|
2416
|
+
firm = Firm.first
|
2417
|
+
client = firm.clients_using_primary_key.create!(name: "test")
|
1998
2418
|
assert_equal firm.name, client.firm_name
|
1999
2419
|
end
|
2000
2420
|
|
2001
2421
|
def test_defining_has_many_association_with_delete_all_dependency_lazily_evaluates_target_class
|
2002
|
-
|
2003
|
-
|
2004
|
-
|
2005
|
-
|
2006
|
-
|
2007
|
-
|
2422
|
+
assert_not_called_on_instance_of(
|
2423
|
+
ActiveRecord::Reflection::AssociationReflection,
|
2424
|
+
:class_name,
|
2425
|
+
) do
|
2426
|
+
class_eval(<<-EOF, __FILE__, __LINE__ + 1)
|
2427
|
+
class DeleteAllModel < ActiveRecord::Base
|
2428
|
+
has_many :nonentities, :dependent => :delete_all
|
2429
|
+
end
|
2430
|
+
EOF
|
2431
|
+
end
|
2008
2432
|
end
|
2009
2433
|
|
2010
2434
|
def test_defining_has_many_association_with_nullify_dependency_lazily_evaluates_target_class
|
2011
|
-
|
2012
|
-
|
2013
|
-
|
2014
|
-
|
2015
|
-
|
2016
|
-
|
2435
|
+
assert_not_called_on_instance_of(
|
2436
|
+
ActiveRecord::Reflection::AssociationReflection,
|
2437
|
+
:class_name,
|
2438
|
+
) do
|
2439
|
+
class_eval(<<-EOF, __FILE__, __LINE__ + 1)
|
2440
|
+
class NullifyModel < ActiveRecord::Base
|
2441
|
+
has_many :nonentities, :dependent => :nullify
|
2442
|
+
end
|
2443
|
+
EOF
|
2444
|
+
end
|
2017
2445
|
end
|
2018
2446
|
|
2019
2447
|
def test_attributes_are_being_set_when_initialized_from_has_many_association_with_where_clause
|
2020
|
-
new_comment = posts(:welcome).comments.where(:
|
2448
|
+
new_comment = posts(:welcome).comments.where(body: "Some content").build
|
2021
2449
|
assert_equal new_comment.body, "Some content"
|
2022
2450
|
end
|
2023
2451
|
|
2024
2452
|
def test_attributes_are_being_set_when_initialized_from_has_many_association_with_multiple_where_clauses
|
2025
|
-
new_comment = posts(:welcome).comments.where(:
|
2453
|
+
new_comment = posts(:welcome).comments.where(body: "Some content").where(type: "SpecialComment").build
|
2026
2454
|
assert_equal new_comment.body, "Some content"
|
2027
2455
|
assert_equal new_comment.type, "SpecialComment"
|
2028
2456
|
assert_equal new_comment.post_id, posts(:welcome).id
|
@@ -2036,7 +2464,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2036
2464
|
|
2037
2465
|
def test_load_target_respects_protected_attributes
|
2038
2466
|
topic = Topic.create!
|
2039
|
-
reply = topic.replies.create(:
|
2467
|
+
reply = topic.replies.create(title: "reply 1")
|
2040
2468
|
reply.approved = false
|
2041
2469
|
reply.save!
|
2042
2470
|
|
@@ -2059,11 +2487,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2059
2487
|
ary = topics(:first).replies.to_a
|
2060
2488
|
target = topics(:first).replies.target
|
2061
2489
|
|
2062
|
-
|
2490
|
+
assert_not_same target, ary
|
2063
2491
|
end
|
2064
2492
|
|
2065
2493
|
def test_merging_with_custom_attribute_writer
|
2066
|
-
bulb = Bulb.new(:
|
2494
|
+
bulb = Bulb.new(color: "red")
|
2067
2495
|
assert_equal "RED!", bulb.color
|
2068
2496
|
|
2069
2497
|
car = Car.create!
|
@@ -2073,26 +2501,34 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2073
2501
|
end
|
2074
2502
|
|
2075
2503
|
def test_abstract_class_with_polymorphic_has_many
|
2076
|
-
post = SubStiPost.create! :
|
2077
|
-
tagging = Tagging.create! :
|
2504
|
+
post = SubStiPost.create! title: "fooo", body: "baa"
|
2505
|
+
tagging = Tagging.create! taggable: post
|
2078
2506
|
assert_equal [tagging], post.taggings
|
2079
2507
|
end
|
2080
2508
|
|
2081
2509
|
def test_with_polymorphic_has_many_with_custom_columns_name
|
2082
|
-
post = Post.create! :
|
2510
|
+
post = Post.create! title: "foo", body: "bar"
|
2083
2511
|
image = Image.create!
|
2084
2512
|
|
2085
2513
|
post.images << image
|
2086
2514
|
|
2087
2515
|
assert_equal [image], post.images
|
2516
|
+
assert_equal post, image.imageable
|
2088
2517
|
end
|
2089
2518
|
|
2090
2519
|
def test_build_with_polymorphic_has_many_does_not_allow_to_override_type_and_id
|
2091
2520
|
welcome = posts(:welcome)
|
2092
|
-
tagging = welcome.taggings.build(:
|
2521
|
+
tagging = welcome.taggings.build(taggable_id: 99, taggable_type: "ShouldNotChange")
|
2093
2522
|
|
2094
2523
|
assert_equal welcome.id, tagging.taggable_id
|
2095
|
-
assert_equal
|
2524
|
+
assert_equal "Post", tagging.taggable_type
|
2525
|
+
end
|
2526
|
+
|
2527
|
+
def test_build_from_polymorphic_association_sets_inverse_instance
|
2528
|
+
post = Post.new
|
2529
|
+
tagging = post.taggings.build
|
2530
|
+
|
2531
|
+
assert_equal post, tagging.taggable
|
2096
2532
|
end
|
2097
2533
|
|
2098
2534
|
def test_dont_call_save_callbacks_twice_on_has_many
|
@@ -2104,30 +2540,30 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2104
2540
|
end
|
2105
2541
|
|
2106
2542
|
def test_association_attributes_are_available_to_after_initialize
|
2107
|
-
car = Car.create(:
|
2543
|
+
car = Car.create(name: "honda")
|
2108
2544
|
bulb = car.bulbs.build
|
2109
2545
|
|
2110
|
-
assert_equal car.id, bulb.attributes_after_initialize[
|
2546
|
+
assert_equal car.id, bulb.attributes_after_initialize["car_id"]
|
2111
2547
|
end
|
2112
2548
|
|
2113
2549
|
def test_attributes_are_set_when_initialized_from_has_many_null_relationship
|
2114
|
-
car = Car.new name:
|
2115
|
-
bulb = car.bulbs.where(name:
|
2116
|
-
assert_equal
|
2550
|
+
car = Car.new name: "honda"
|
2551
|
+
bulb = car.bulbs.where(name: "headlight").first_or_initialize
|
2552
|
+
assert_equal "headlight", bulb.name
|
2117
2553
|
end
|
2118
2554
|
|
2119
2555
|
def test_attributes_are_set_when_initialized_from_polymorphic_has_many_null_relationship
|
2120
|
-
post = Post.new title:
|
2121
|
-
tag = Tag.create!(name:
|
2556
|
+
post = Post.new title: "title", body: "bar"
|
2557
|
+
tag = Tag.create!(name: "foo")
|
2122
2558
|
|
2123
2559
|
tagging = post.taggings.where(tag: tag).first_or_initialize
|
2124
2560
|
|
2125
2561
|
assert_equal tag.id, tagging.tag_id
|
2126
|
-
assert_equal
|
2562
|
+
assert_equal "Post", tagging.taggable_type
|
2127
2563
|
end
|
2128
2564
|
|
2129
2565
|
def test_replace
|
2130
|
-
car = Car.create(:
|
2566
|
+
car = Car.create(name: "honda")
|
2131
2567
|
bulb1 = car.bulbs.create
|
2132
2568
|
bulb2 = Bulb.create
|
2133
2569
|
|
@@ -2138,7 +2574,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2138
2574
|
end
|
2139
2575
|
|
2140
2576
|
def test_replace_returns_target
|
2141
|
-
car = Car.create(:
|
2577
|
+
car = Car.create(name: "honda")
|
2142
2578
|
bulb1 = car.bulbs.create
|
2143
2579
|
bulb2 = car.bulbs.create
|
2144
2580
|
bulb3 = Bulb.create
|
@@ -2152,18 +2588,48 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2152
2588
|
def test_collection_association_with_private_kernel_method
|
2153
2589
|
firm = companies(:first_firm)
|
2154
2590
|
assert_equal [accounts(:signals37)], firm.accounts.open
|
2591
|
+
assert_equal [accounts(:signals37)], firm.accounts.available
|
2592
|
+
end
|
2593
|
+
|
2594
|
+
def test_association_with_or_doesnt_set_inverse_instance_key
|
2595
|
+
firm = companies(:first_firm)
|
2596
|
+
accounts = firm.accounts.or(Account.where(firm_id: nil)).order(:id)
|
2597
|
+
assert_equal [firm.id, nil], accounts.map(&:firm_id)
|
2598
|
+
end
|
2599
|
+
|
2600
|
+
def test_association_with_rewhere_doesnt_set_inverse_instance_key
|
2601
|
+
firm = companies(:first_firm)
|
2602
|
+
accounts = firm.accounts.rewhere(firm_id: [firm.id, nil]).order(:id)
|
2603
|
+
assert_equal [firm.id, nil], accounts.map(&:firm_id)
|
2155
2604
|
end
|
2156
2605
|
|
2157
2606
|
test "first_or_initialize adds the record to the association" do
|
2158
|
-
firm = Firm.create! name:
|
2159
|
-
client = firm.clients_of_firm.first_or_initialize
|
2607
|
+
firm = Firm.create! name: "omg"
|
2608
|
+
client = firm.clients_of_firm.where(name: "lol").first_or_initialize do
|
2609
|
+
assert_equal 5, Client.count
|
2610
|
+
end
|
2611
|
+
assert_equal "lol", client.name
|
2160
2612
|
assert_equal [client], firm.clients_of_firm
|
2161
2613
|
end
|
2162
2614
|
|
2163
2615
|
test "first_or_create adds the record to the association" do
|
2164
|
-
firm = Firm.create! name:
|
2616
|
+
firm = Firm.create! name: "omg"
|
2617
|
+
firm.clients_of_firm.load_target
|
2618
|
+
client = firm.clients_of_firm.where(name: "lol").first_or_create do
|
2619
|
+
assert_equal 5, Client.count
|
2620
|
+
end
|
2621
|
+
assert_equal "lol", client.name
|
2622
|
+
assert_equal [client], firm.clients_of_firm
|
2623
|
+
assert_equal [client], firm.reload.clients_of_firm
|
2624
|
+
end
|
2625
|
+
|
2626
|
+
test "first_or_create! adds the record to the association" do
|
2627
|
+
firm = Firm.create! name: "omg"
|
2165
2628
|
firm.clients_of_firm.load_target
|
2166
|
-
client = firm.clients_of_firm.
|
2629
|
+
client = firm.clients_of_firm.where(name: "lol").first_or_create! do
|
2630
|
+
assert_equal 5, Client.count
|
2631
|
+
end
|
2632
|
+
assert_equal "lol", client.name
|
2167
2633
|
assert_equal [client], firm.clients_of_firm
|
2168
2634
|
assert_equal [client], firm.reload.clients_of_firm
|
2169
2635
|
end
|
@@ -2172,7 +2638,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2172
2638
|
post = posts(:welcome)
|
2173
2639
|
|
2174
2640
|
assert post.taggings_with_delete_all.count > 0
|
2175
|
-
|
2641
|
+
assert_not_predicate post.taggings_with_delete_all, :loaded?
|
2176
2642
|
|
2177
2643
|
# 2 queries: one DELETE and another to update the counter cache
|
2178
2644
|
assert_queries(2) do
|
@@ -2183,9 +2649,9 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2183
2649
|
test "has many associations on new records use null relations" do
|
2184
2650
|
post = Post.new
|
2185
2651
|
|
2186
|
-
assert_no_queries
|
2652
|
+
assert_no_queries do
|
2187
2653
|
assert_equal [], post.comments
|
2188
|
-
assert_equal [], post.comments.where(body:
|
2654
|
+
assert_equal [], post.comments.where(body: "omg")
|
2189
2655
|
assert_equal [], post.comments.pluck(:body)
|
2190
2656
|
assert_equal 0, post.comments.sum(:id)
|
2191
2657
|
assert_equal 0, post.comments.count
|
@@ -2194,34 +2660,34 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2194
2660
|
|
2195
2661
|
test "collection proxy respects default scope" do
|
2196
2662
|
author = authors(:mary)
|
2197
|
-
|
2663
|
+
assert_not_predicate author.first_posts, :exists?
|
2198
2664
|
end
|
2199
2665
|
|
2200
2666
|
test "association with extend option" do
|
2201
2667
|
post = posts(:welcome)
|
2202
|
-
assert_equal "lifo",
|
2203
|
-
assert_equal "hello", post.comments_with_extend.greeting
|
2668
|
+
assert_equal "lifo", post.comments_with_extend.author
|
2669
|
+
assert_equal "hello :)", post.comments_with_extend.greeting
|
2204
2670
|
end
|
2205
2671
|
|
2206
2672
|
test "association with extend option with multiple extensions" do
|
2207
2673
|
post = posts(:welcome)
|
2208
|
-
assert_equal "lifo",
|
2209
|
-
assert_equal "hullo", post.comments_with_extend_2.greeting
|
2674
|
+
assert_equal "lifo", post.comments_with_extend_2.author
|
2675
|
+
assert_equal "hullo :)", post.comments_with_extend_2.greeting
|
2210
2676
|
end
|
2211
2677
|
|
2212
2678
|
test "extend option affects per association" do
|
2213
2679
|
post = posts(:welcome)
|
2214
|
-
assert_equal "lifo",
|
2215
|
-
assert_equal "lifo",
|
2216
|
-
assert_equal "hello", post.comments_with_extend.greeting
|
2217
|
-
assert_equal "hullo", post.comments_with_extend_2.greeting
|
2680
|
+
assert_equal "lifo", post.comments_with_extend.author
|
2681
|
+
assert_equal "lifo", post.comments_with_extend_2.author
|
2682
|
+
assert_equal "hello :)", post.comments_with_extend.greeting
|
2683
|
+
assert_equal "hullo :)", post.comments_with_extend_2.greeting
|
2218
2684
|
end
|
2219
2685
|
|
2220
2686
|
test "delete record with complex joins" do
|
2221
2687
|
david = authors(:david)
|
2222
2688
|
|
2223
2689
|
post = david.posts.first
|
2224
|
-
post.type =
|
2690
|
+
post.type = "PostWithSpecialCategorization"
|
2225
2691
|
post.save
|
2226
2692
|
|
2227
2693
|
categorization = post.categorizations.first
|
@@ -2234,8 +2700,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2234
2700
|
end
|
2235
2701
|
|
2236
2702
|
test "does not duplicate associations when used with natural primary keys" do
|
2237
|
-
speedometer = Speedometer.create!(id:
|
2238
|
-
speedometer.minivans.create!(minivan_id:
|
2703
|
+
speedometer = Speedometer.create!(id: "4")
|
2704
|
+
speedometer.minivans.create!(minivan_id: "a-van-red", name: "a van", color: "red")
|
2239
2705
|
|
2240
2706
|
assert_equal 1, speedometer.minivans.to_a.size, "Only one association should be present:\n#{speedometer.minivans.to_a}"
|
2241
2707
|
assert_equal 1, speedometer.reload.minivans.to_a.size
|
@@ -2248,10 +2714,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2248
2714
|
|
2249
2715
|
assert_equal [bulb1], car.bulbs
|
2250
2716
|
assert_equal [bulb1, bulb2], car.all_bulbs.sort_by(&:id)
|
2717
|
+
assert_equal [bulb1, bulb2], Car.includes(:all_bulbs).find(car.id).all_bulbs.sort_by(&:id)
|
2718
|
+
assert_equal [bulb1, bulb2], Car.eager_load(:all_bulbs).find(car.id).all_bulbs.sort_by(&:id)
|
2251
2719
|
end
|
2252
2720
|
|
2253
2721
|
test "can unscope and where the default scope of the associated model" do
|
2254
|
-
Car.has_many :other_bulbs, -> { unscope(where: [:name]).where(name: 'other') }, class_name: "Bulb"
|
2255
2722
|
car = Car.create!
|
2256
2723
|
bulb1 = Bulb.create! name: "defaulty", car: car
|
2257
2724
|
bulb2 = Bulb.create! name: "other", car: car
|
@@ -2261,7 +2728,6 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2261
2728
|
end
|
2262
2729
|
|
2263
2730
|
test "can rewhere the default scope of the associated model" do
|
2264
|
-
Car.has_many :old_bulbs, -> { rewhere(name: 'old') }, class_name: "Bulb"
|
2265
2731
|
car = Car.create!
|
2266
2732
|
bulb1 = Bulb.create! name: "defaulty", car: car
|
2267
2733
|
bulb2 = Bulb.create! name: "old", car: car
|
@@ -2270,13 +2736,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2270
2736
|
assert_equal [bulb2], car.old_bulbs
|
2271
2737
|
end
|
2272
2738
|
|
2273
|
-
test
|
2739
|
+
test "unscopes the default scope of associated model when used with include" do
|
2274
2740
|
car = Car.create!
|
2275
|
-
|
2741
|
+
bulb1 = Bulb.create! name: "defaulty", car: car
|
2742
|
+
bulb2 = Bulb.create! name: "other", car: car
|
2276
2743
|
|
2277
|
-
assert_equal [
|
2278
|
-
assert_equal [
|
2279
|
-
assert_equal [bulb], Car.eager_load(:all_bulbs).find(car.id).all_bulbs
|
2744
|
+
assert_equal [bulb1, bulb2], Car.includes(:all_bulbs2).find(car.id).all_bulbs2.sort_by(&:id)
|
2745
|
+
assert_equal [bulb1, bulb2], Car.eager_load(:all_bulbs2).find(car.id).all_bulbs2.sort_by(&:id)
|
2280
2746
|
end
|
2281
2747
|
|
2282
2748
|
test "raises RecordNotDestroyed when replaced child can't be destroyed" do
|
@@ -2291,7 +2757,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2291
2757
|
assert_equal "Failed to destroy the record", error.message
|
2292
2758
|
end
|
2293
2759
|
|
2294
|
-
test
|
2760
|
+
test "updates counter cache when default scope is given" do
|
2295
2761
|
topic = DefaultRejectedTopic.create approved: true
|
2296
2762
|
|
2297
2763
|
assert_difference "topic.reload.replies_count", 1 do
|
@@ -2299,8 +2765,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2299
2765
|
end
|
2300
2766
|
end
|
2301
2767
|
|
2302
|
-
test
|
2303
|
-
[:errors,
|
2768
|
+
test "dangerous association name raises ArgumentError" do
|
2769
|
+
[:errors, "errors", :save, "save"].each do |name|
|
2304
2770
|
assert_raises(ArgumentError, "Association #{name} should not be allowed") do
|
2305
2771
|
Class.new(ActiveRecord::Base) do
|
2306
2772
|
has_many name
|
@@ -2309,16 +2775,16 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2309
2775
|
end
|
2310
2776
|
end
|
2311
2777
|
|
2312
|
-
test
|
2778
|
+
test "passes custom context validation to validate children" do
|
2313
2779
|
pirate = FamousPirate.new
|
2314
2780
|
pirate.famous_ships << ship = FamousShip.new
|
2315
2781
|
|
2316
|
-
|
2782
|
+
assert_predicate pirate, :valid?
|
2317
2783
|
assert_not pirate.valid?(:conference)
|
2318
2784
|
assert_equal "can't be blank", ship.errors[:name].first
|
2319
2785
|
end
|
2320
2786
|
|
2321
|
-
test
|
2787
|
+
test "association with instance dependent scope" do
|
2322
2788
|
bob = authors(:bob)
|
2323
2789
|
Post.create!(title: "signed post by bob", body: "stuff", author: authors(:bob))
|
2324
2790
|
Post.create!(title: "anonymous post", body: "more stuff", author: authors(:bob))
|
@@ -2328,22 +2794,26 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2328
2794
|
assert_equal [], authors(:david).posts_with_signature.map(&:title)
|
2329
2795
|
end
|
2330
2796
|
|
2331
|
-
test
|
2797
|
+
test "associations autosaves when object is already persisted" do
|
2332
2798
|
bulb = Bulb.create!
|
2333
2799
|
tyre = Tyre.create!
|
2334
2800
|
|
2335
|
-
car = Car.create! do |c|
|
2801
|
+
car = Car.create!(name: "honda") do |c|
|
2336
2802
|
c.bulbs << bulb
|
2337
2803
|
c.tyres << tyre
|
2338
2804
|
end
|
2339
2805
|
|
2806
|
+
assert_equal [nil, "honda"], car.saved_change_to_name
|
2807
|
+
|
2340
2808
|
assert_equal 1, car.bulbs.count
|
2341
2809
|
assert_equal 1, car.tyres.count
|
2342
2810
|
end
|
2343
2811
|
|
2344
|
-
test
|
2812
|
+
test "associations replace in memory when records have the same id" do
|
2345
2813
|
bulb = Bulb.create!
|
2346
|
-
car = Car.create!(bulbs: [bulb])
|
2814
|
+
car = Car.create!(name: "honda", bulbs: [bulb])
|
2815
|
+
|
2816
|
+
assert_equal [nil, "honda"], car.saved_change_to_name
|
2347
2817
|
|
2348
2818
|
new_bulb = Bulb.find(bulb.id)
|
2349
2819
|
new_bulb.name = "foo"
|
@@ -2352,9 +2822,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2352
2822
|
assert_equal "foo", car.bulbs.first.name
|
2353
2823
|
end
|
2354
2824
|
|
2355
|
-
test
|
2825
|
+
test "in memory replacement executes no queries" do
|
2356
2826
|
bulb = Bulb.create!
|
2357
|
-
car = Car.create!(bulbs: [bulb])
|
2827
|
+
car = Car.create!(name: "honda", bulbs: [bulb])
|
2828
|
+
|
2829
|
+
assert_equal [nil, "honda"], car.saved_change_to_name
|
2358
2830
|
|
2359
2831
|
new_bulb = Bulb.find(bulb.id)
|
2360
2832
|
|
@@ -2363,7 +2835,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2363
2835
|
end
|
2364
2836
|
end
|
2365
2837
|
|
2366
|
-
test
|
2838
|
+
test "in memory replacements do not execute callbacks" do
|
2367
2839
|
raise_after_add = false
|
2368
2840
|
klass = Class.new(ActiveRecord::Base) do
|
2369
2841
|
self.table_name = :cars
|
@@ -2384,9 +2856,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2384
2856
|
end
|
2385
2857
|
end
|
2386
2858
|
|
2387
|
-
test
|
2859
|
+
test "in memory replacements sets inverse instance" do
|
2388
2860
|
bulb = Bulb.create!
|
2389
|
-
car = Car.create!(bulbs: [bulb])
|
2861
|
+
car = Car.create!(name: "honda", bulbs: [bulb])
|
2862
|
+
|
2863
|
+
assert_equal [nil, "honda"], car.saved_change_to_name
|
2390
2864
|
|
2391
2865
|
new_bulb = Bulb.find(bulb.id)
|
2392
2866
|
car.bulbs = [new_bulb]
|
@@ -2394,10 +2868,21 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2394
2868
|
assert_same car, new_bulb.car
|
2395
2869
|
end
|
2396
2870
|
|
2397
|
-
test
|
2871
|
+
test "reattach to new objects replaces inverse association and foreign key" do
|
2872
|
+
bulb = Bulb.create!(car: Car.create!)
|
2873
|
+
assert bulb.car_id
|
2874
|
+
car = Car.new
|
2875
|
+
car.bulbs << bulb
|
2876
|
+
assert_equal car, bulb.car
|
2877
|
+
assert_nil bulb.car_id
|
2878
|
+
end
|
2879
|
+
|
2880
|
+
test "in memory replacement maintains order" do
|
2398
2881
|
first_bulb = Bulb.create!
|
2399
2882
|
second_bulb = Bulb.create!
|
2400
|
-
car = Car.create!(bulbs: [first_bulb, second_bulb])
|
2883
|
+
car = Car.create!(name: "honda", bulbs: [first_bulb, second_bulb])
|
2884
|
+
|
2885
|
+
assert_equal [nil, "honda"], car.saved_change_to_name
|
2401
2886
|
|
2402
2887
|
same_bulb = Bulb.find(first_bulb.id)
|
2403
2888
|
car.bulbs = [second_bulb, same_bulb]
|
@@ -2405,8 +2890,16 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2405
2890
|
assert_equal [first_bulb, second_bulb], car.bulbs
|
2406
2891
|
end
|
2407
2892
|
|
2893
|
+
test "association size calculation works with default scoped selects when not previously fetched" do
|
2894
|
+
firm = Firm.create!(name: "Firm")
|
2895
|
+
5.times { firm.developers_with_select << Developer.create!(name: "Developer") }
|
2896
|
+
|
2897
|
+
same_firm = Firm.find(firm.id)
|
2898
|
+
assert_equal 5, same_firm.developers_with_select.size
|
2899
|
+
end
|
2900
|
+
|
2408
2901
|
test "prevent double insertion of new object when the parent association loaded in the after save callback" do
|
2409
|
-
reset_callbacks(:save
|
2902
|
+
reset_callbacks(Bulb, :save) do
|
2410
2903
|
Bulb.after_save { |record| record.car.bulbs.load }
|
2411
2904
|
|
2412
2905
|
car = Car.create!
|
@@ -2417,7 +2910,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2417
2910
|
end
|
2418
2911
|
|
2419
2912
|
test "prevent double firing the before save callback of new object when the parent association saved in the callback" do
|
2420
|
-
reset_callbacks(:save
|
2913
|
+
reset_callbacks(Bulb, :save) do
|
2421
2914
|
count = 0
|
2422
2915
|
Bulb.before_save { |record| record.car.save && count += 1 }
|
2423
2916
|
|
@@ -2428,10 +2921,68 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2428
2921
|
end
|
2429
2922
|
end
|
2430
2923
|
|
2431
|
-
|
2432
|
-
|
2924
|
+
test "calling size on an association that has not been loaded performs a query" do
|
2925
|
+
car = Car.create!
|
2926
|
+
Bulb.create(car_id: car.id)
|
2927
|
+
|
2928
|
+
car_two = Car.create!
|
2929
|
+
|
2930
|
+
assert_queries(1) do
|
2931
|
+
assert_equal 1, car.bulbs.size
|
2932
|
+
end
|
2433
2933
|
|
2434
|
-
|
2934
|
+
assert_queries(1) do
|
2935
|
+
assert_equal 0, car_two.bulbs.size
|
2936
|
+
end
|
2937
|
+
end
|
2938
|
+
|
2939
|
+
test "calling size on an association that has been loaded does not perform query" do
|
2940
|
+
car = Car.create!
|
2941
|
+
Bulb.create(car_id: car.id)
|
2942
|
+
car.bulb_ids
|
2943
|
+
|
2944
|
+
car_two = Car.create!
|
2945
|
+
car_two.bulb_ids
|
2946
|
+
|
2947
|
+
assert_no_queries do
|
2948
|
+
assert_equal 1, car.bulbs.size
|
2949
|
+
end
|
2950
|
+
|
2951
|
+
assert_no_queries do
|
2952
|
+
assert_equal 0, car_two.bulbs.size
|
2953
|
+
end
|
2954
|
+
end
|
2955
|
+
|
2956
|
+
test "calling empty on an association that has not been loaded performs a query" do
|
2957
|
+
car = Car.create!
|
2958
|
+
Bulb.create(car_id: car.id)
|
2959
|
+
|
2960
|
+
car_two = Car.create!
|
2961
|
+
|
2962
|
+
assert_queries(1) do
|
2963
|
+
assert_not_empty car.bulbs
|
2964
|
+
end
|
2965
|
+
|
2966
|
+
assert_queries(1) do
|
2967
|
+
assert_empty car_two.bulbs
|
2968
|
+
end
|
2969
|
+
end
|
2970
|
+
|
2971
|
+
test "calling empty on an association that has been loaded does not performs query" do
|
2972
|
+
car = Car.create!
|
2973
|
+
Bulb.create(car_id: car.id)
|
2974
|
+
car.bulb_ids
|
2975
|
+
|
2976
|
+
car_two = Car.create!
|
2977
|
+
car_two.bulb_ids
|
2978
|
+
|
2979
|
+
assert_no_queries do
|
2980
|
+
assert_not_empty car.bulbs
|
2981
|
+
end
|
2982
|
+
|
2983
|
+
assert_no_queries do
|
2984
|
+
assert_empty car_two.bulbs
|
2985
|
+
end
|
2435
2986
|
end
|
2436
2987
|
|
2437
2988
|
class AuthorWithErrorDestroyingAssociation < ActiveRecord::Base
|
@@ -2465,15 +3016,20 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2465
3016
|
end
|
2466
3017
|
|
2467
3018
|
def test_ids_reader_memoization
|
2468
|
-
car = Car.create!(name:
|
3019
|
+
car = Car.create!(name: "Tofaş")
|
2469
3020
|
bulb = Bulb.create!(car: car)
|
2470
3021
|
|
2471
3022
|
assert_equal [bulb.id], car.bulb_ids
|
2472
3023
|
assert_no_queries { car.bulb_ids }
|
3024
|
+
|
3025
|
+
bulb2 = car.bulbs.create!
|
3026
|
+
|
3027
|
+
assert_equal [bulb.id, bulb2.id], car.bulb_ids
|
3028
|
+
assert_no_queries { car.bulb_ids }
|
2473
3029
|
end
|
2474
3030
|
|
2475
3031
|
def test_loading_association_in_validate_callback_doesnt_affect_persistence
|
2476
|
-
reset_callbacks(:validation
|
3032
|
+
reset_callbacks(Bulb, :validation) do
|
2477
3033
|
Bulb.after_validation { |record| record.car.bulbs.load }
|
2478
3034
|
|
2479
3035
|
car = Car.create!(name: "Car")
|
@@ -2483,19 +3039,36 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
2483
3039
|
end
|
2484
3040
|
end
|
2485
3041
|
|
2486
|
-
|
2487
|
-
|
2488
|
-
|
2489
|
-
|
2490
|
-
|
2491
|
-
|
2492
|
-
old_callbacks[subclass] = subclass.send("_#{kind}_callbacks").dup
|
2493
|
-
end
|
2494
|
-
yield
|
2495
|
-
ensure
|
2496
|
-
klass.send("_#{kind}_callbacks=", old_callbacks[klass])
|
2497
|
-
klass.subclasses.each do |subclass|
|
2498
|
-
subclass.send("_#{kind}_callbacks=", old_callbacks[subclass])
|
3042
|
+
def test_create_children_could_be_rolled_back_by_after_save
|
3043
|
+
firm = Firm.create!(name: "A New Firm, Inc")
|
3044
|
+
assert_no_difference "Client.count" do
|
3045
|
+
client = firm.clients.create(name: "New Client") do |cli|
|
3046
|
+
cli.rollback_on_save = true
|
3047
|
+
assert_not cli.rollback_on_create_called
|
2499
3048
|
end
|
3049
|
+
assert client.rollback_on_create_called
|
3050
|
+
end
|
3051
|
+
end
|
3052
|
+
|
3053
|
+
def test_has_many_with_out_of_range_value
|
3054
|
+
reference = Reference.create!(id: 2147483648) # out of range in the integer
|
3055
|
+
assert_equal [], reference.ideal_jobs
|
3056
|
+
end
|
3057
|
+
|
3058
|
+
def test_has_many_preloading_with_duplicate_records
|
3059
|
+
posts = Post.joins(:comments).preload(:comments).order(:id).to_a
|
3060
|
+
assert_equal [1, 2], posts.first.comments.map(&:id).sort
|
3061
|
+
end
|
3062
|
+
|
3063
|
+
def test_has_many_association_with_same_foreign_key_name
|
3064
|
+
assert_nothing_raised do
|
3065
|
+
firm = Firm.find(15)
|
3066
|
+
assert_not_nil(firm.comments.first)
|
3067
|
+
end
|
3068
|
+
end
|
3069
|
+
|
3070
|
+
private
|
3071
|
+
def force_signal37_to_load_all_clients_of_firm
|
3072
|
+
companies(:first_firm).clients_of_firm.load_target
|
2500
3073
|
end
|
2501
3074
|
end
|