ibm_db 5.6.1-arm64-darwin-24
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 +7 -0
- data/CHANGES +299 -0
- data/LICENSE +55 -0
- data/MANIFEST +14 -0
- data/ParameterizedQueries README +39 -0
- data/README +210 -0
- data/ext/Makefile +270 -0
- data/ext/Makefile.nt32 +181 -0
- data/ext/Makefile.nt32.191 +212 -0
- data/ext/extconf.rb +320 -0
- data/ext/gil_release_version.h +3 -0
- data/ext/ibm_db.bundle +0 -0
- data/ext/ibm_db.c +11865 -0
- data/ext/ibm_db.o +0 -0
- data/ext/mkmf.log +98 -0
- data/ext/ruby_ibm_db.h +241 -0
- data/ext/ruby_ibm_db_cli.c +867 -0
- data/ext/ruby_ibm_db_cli.h +508 -0
- data/ext/ruby_ibm_db_cli.o +0 -0
- data/ext/unicode_support_version.h +3 -0
- data/init.rb +42 -0
- data/lib/IBM_DB.rb +27 -0
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +4407 -0
- data/lib/active_record/connection_adapters/ibm_db_pstmt.rb +1965 -0
- data/lib/active_record/connection_adapters/ibmdb_adapter.rb +5 -0
- data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -0
- data/lib/ibm_db.bundle +0 -0
- data/test/active_record/connection_adapters/fake_adapter.rb +52 -0
- 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/example.log +1 -0
- data/test/assets/flowers.jpg +0 -0
- data/test/assets/schema_dump_5_1.yml +345 -0
- data/test/assets/test.txt +1 -0
- data/test/cases/adapter_prevent_writes_test.rb +334 -0
- data/test/cases/adapter_test.rb +565 -0
- data/test/cases/adapters/mysql2/active_schema_test.rb +203 -0
- data/test/cases/adapters/mysql2/auto_increment_test.rb +34 -0
- data/test/cases/adapters/mysql2/bind_parameter_test.rb +52 -0
- data/test/cases/adapters/mysql2/boolean_test.rb +102 -0
- data/test/cases/adapters/mysql2/case_sensitivity_test.rb +65 -0
- data/test/cases/adapters/mysql2/charset_collation_test.rb +57 -0
- data/test/cases/adapters/mysql2/connection_test.rb +208 -0
- data/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb +28 -0
- data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +49 -0
- data/test/cases/adapters/mysql2/enum_test.rb +47 -0
- data/test/cases/adapters/mysql2/explain_test.rb +23 -0
- data/test/cases/adapters/mysql2/json_test.rb +24 -0
- data/test/cases/adapters/mysql2/mysql2_adapter_prevent_writes_test.rb +208 -0
- data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +238 -0
- 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/reserved_word_test.rb +152 -0
- data/test/cases/adapters/mysql2/schema_migrations_test.rb +64 -0
- data/test/cases/adapters/mysql2/schema_test.rb +128 -0
- data/test/cases/adapters/mysql2/set_test.rb +32 -0
- data/test/cases/adapters/mysql2/sp_test.rb +38 -0
- data/test/cases/adapters/mysql2/sql_types_test.rb +16 -0
- data/test/cases/adapters/mysql2/table_options_test.rb +125 -0
- data/test/cases/adapters/mysql2/transaction_test.rb +151 -0
- data/test/cases/adapters/mysql2/unsigned_type_test.rb +68 -0
- data/test/cases/adapters/mysql2/virtual_column_test.rb +66 -0
- data/test/cases/adapters/postgresql/active_schema_test.rb +113 -0
- data/test/cases/adapters/postgresql/array_test.rb +394 -0
- data/test/cases/adapters/postgresql/bit_string_test.rb +84 -0
- data/test/cases/adapters/postgresql/bytea_test.rb +135 -0
- data/test/cases/adapters/postgresql/case_insensitive_test.rb +27 -0
- data/test/cases/adapters/postgresql/change_schema_test.rb +40 -0
- data/test/cases/adapters/postgresql/cidr_test.rb +27 -0
- data/test/cases/adapters/postgresql/citext_test.rb +78 -0
- data/test/cases/adapters/postgresql/collation_test.rb +55 -0
- data/test/cases/adapters/postgresql/composite_test.rb +134 -0
- data/test/cases/adapters/postgresql/connection_test.rb +245 -0
- data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +74 -0
- data/test/cases/adapters/postgresql/datatype_test.rb +89 -0
- data/test/cases/adapters/postgresql/date_test.rb +42 -0
- data/test/cases/adapters/postgresql/domain_test.rb +49 -0
- data/test/cases/adapters/postgresql/enum_test.rb +93 -0
- data/test/cases/adapters/postgresql/explain_test.rb +22 -0
- data/test/cases/adapters/postgresql/extension_migration_test.rb +64 -0
- data/test/cases/adapters/postgresql/foreign_table_test.rb +109 -0
- data/test/cases/adapters/postgresql/full_text_test.rb +46 -0
- data/test/cases/adapters/postgresql/geometric_test.rb +372 -0
- data/test/cases/adapters/postgresql/hstore_test.rb +390 -0
- data/test/cases/adapters/postgresql/infinity_test.rb +108 -0
- data/test/cases/adapters/postgresql/integer_test.rb +27 -0
- data/test/cases/adapters/postgresql/interval_test.rb +99 -0
- data/test/cases/adapters/postgresql/json_test.rb +52 -0
- data/test/cases/adapters/postgresql/ltree_test.rb +51 -0
- data/test/cases/adapters/postgresql/money_test.rb +127 -0
- data/test/cases/adapters/postgresql/network_test.rb +102 -0
- data/test/cases/adapters/postgresql/numbers_test.rb +51 -0
- 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 +447 -0
- data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +27 -0
- data/test/cases/adapters/postgresql/prepared_statements_test.rb +22 -0
- data/test/cases/adapters/postgresql/quoting_test.rb +50 -0
- data/test/cases/adapters/postgresql/range_test.rb +457 -0
- data/test/cases/adapters/postgresql/referential_integrity_test.rb +112 -0
- data/test/cases/adapters/postgresql/rename_table_test.rb +35 -0
- data/test/cases/adapters/postgresql/schema_authorization_test.rb +110 -0
- data/test/cases/adapters/postgresql/schema_test.rb +713 -0
- data/test/cases/adapters/postgresql/serial_test.rb +156 -0
- data/test/cases/adapters/postgresql/statement_pool_test.rb +61 -0
- data/test/cases/adapters/postgresql/timestamp_test.rb +92 -0
- 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 +35 -0
- data/test/cases/adapters/postgresql/utils_test.rb +64 -0
- data/test/cases/adapters/postgresql/uuid_test.rb +411 -0
- data/test/cases/adapters/postgresql/xml_test.rb +50 -0
- data/test/cases/adapters/sqlite3/collation_test.rb +64 -0
- data/test/cases/adapters/sqlite3/copy_table_test.rb +101 -0
- data/test/cases/adapters/sqlite3/explain_test.rb +23 -0
- data/test/cases/adapters/sqlite3/json_test.rb +29 -0
- data/test/cases/adapters/sqlite3/quoting_test.rb +79 -0
- data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +186 -0
- data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +628 -0
- data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +24 -0
- data/test/cases/adapters/sqlite3/statement_pool_test.rb +21 -0
- data/test/cases/adapters/sqlite3/transaction_test.rb +123 -0
- data/test/cases/aggregations_test.rb +170 -0
- data/test/cases/annotate_test.rb +46 -0
- data/test/cases/ar_schema_test.rb +213 -0
- 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/association_scope_test.rb +16 -0
- data/test/cases/associations/belongs_to_associations_test.rb +1493 -0
- data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +43 -0
- data/test/cases/associations/callbacks_test.rb +208 -0
- data/test/cases/associations/cascaded_eager_loading_test.rb +245 -0
- data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +156 -0
- data/test/cases/associations/eager_load_nested_include_test.rb +127 -0
- data/test/cases/associations/eager_singularization_test.rb +148 -0
- data/test/cases/associations/eager_test.rb +1658 -0
- data/test/cases/associations/extension_test.rb +93 -0
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +1025 -0
- data/test/cases/associations/has_many_associations_test.rb +3074 -0
- data/test/cases/associations/has_many_through_associations_test.rb +1580 -0
- data/test/cases/associations/has_one_associations_test.rb +872 -0
- data/test/cases/associations/has_one_through_associations_test.rb +429 -0
- data/test/cases/associations/inner_join_association_test.rb +215 -0
- data/test/cases/associations/inverse_associations_test.rb +941 -0
- data/test/cases/associations/join_model_test.rb +787 -0
- data/test/cases/associations/left_outer_join_association_test.rb +123 -0
- data/test/cases/associations/nested_through_associations_test.rb +636 -0
- data/test/cases/associations/required_test.rb +127 -0
- data/test/cases/associations_test.rb +516 -0
- data/test/cases/attribute_decorators_test.rb +126 -0
- data/test/cases/attribute_methods/read_test.rb +60 -0
- data/test/cases/attribute_methods_test.rb +1124 -0
- data/test/cases/attribute_set_test.rb +270 -0
- data/test/cases/attribute_test.rb +246 -0
- data/test/cases/attributes_test.rb +371 -0
- data/test/cases/autosave_association_test.rb +1953 -0
- data/test/cases/base_prevent_writes_test.rb +229 -0
- data/test/cases/base_test.rb +1770 -0
- data/test/cases/batches_test.rb +695 -0
- data/test/cases/binary_test.rb +39 -0
- data/test/cases/bind_parameter_test.rb +283 -0
- data/test/cases/boolean_test.rb +52 -0
- data/test/cases/cache_key_test.rb +131 -0
- data/test/cases/calculations_test.rb +1361 -0
- data/test/cases/callbacks_test.rb +503 -0
- data/test/cases/clone_test.rb +45 -0
- data/test/cases/coders/json_test.rb +17 -0
- data/test/cases/coders/yaml_column_test.rb +66 -0
- data/test/cases/collection_cache_key_test.rb +272 -0
- data/test/cases/column_alias_test.rb +19 -0
- data/test/cases/column_definition_test.rb +34 -0
- data/test/cases/comment_test.rb +204 -0
- data/test/cases/connection_adapters/adapter_leasing_test.rb +60 -0
- data/test/cases/connection_adapters/connection_handler_test.rb +467 -0
- 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_specification_test.rb +12 -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 +436 -0
- data/test/cases/connection_adapters/mysql_type_lookup_test.rb +81 -0
- data/test/cases/connection_adapters/quoting_test.rb +13 -0
- data/test/cases/connection_adapters/schema_cache_test.rb +294 -0
- data/test/cases/connection_adapters/type_lookup_test.rb +119 -0
- data/test/cases/connection_management_test.rb +114 -0
- data/test/cases/connection_pool_test.rb +754 -0
- data/test/cases/connection_specification/resolver_test.rb +131 -0
- data/test/cases/core_test.rb +136 -0
- data/test/cases/counter_cache_test.rb +368 -0
- data/test/cases/custom_locking_test.rb +19 -0
- 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 +36 -0
- data/test/cases/date_test.rb +36 -0
- data/test/cases/date_time_precision_test.rb +129 -0
- data/test/cases/date_time_test.rb +76 -0
- data/test/cases/defaults_test.rb +254 -0
- data/test/cases/delegated_type_test.rb +57 -0
- data/test/cases/dirty_test.rb +959 -0
- data/test/cases/disconnected_test.rb +30 -0
- data/test/cases/dup_test.rb +184 -0
- data/test/cases/enum_test.rb +823 -0
- data/test/cases/errors_test.rb +16 -0
- data/test/cases/explain_subscriber_test.rb +66 -0
- data/test/cases/explain_test.rb +79 -0
- data/test/cases/filter_attributes_test.rb +153 -0
- data/test/cases/finder_respond_to_test.rb +60 -0
- data/test/cases/finder_test.rb +1676 -0
- data/test/cases/fixture_set/file_test.rb +152 -0
- data/test/cases/fixtures_test.rb +1645 -0
- data/test/cases/forbidden_attributes_protection_test.rb +130 -0
- data/test/cases/habtm_destroy_order_test.rb +61 -0
- data/test/cases/helper.rb +233 -0
- data/test/cases/hot_compatibility_test.rb +143 -0
- data/test/cases/i18n_test.rb +46 -0
- data/test/cases/inheritance_test.rb +671 -0
- data/test/cases/insert_all_test.rb +489 -0
- data/test/cases/instrumentation_test.rb +101 -0
- data/test/cases/integration_test.rb +243 -0
- data/test/cases/invalid_connection_test.rb +26 -0
- data/test/cases/invertible_migration_test.rb +527 -0
- data/test/cases/json_attribute_test.rb +35 -0
- data/test/cases/json_serialization_test.rb +310 -0
- data/test/cases/json_shared_test_cases.rb +290 -0
- data/test/cases/locking_test.rb +787 -0
- data/test/cases/log_subscriber_test.rb +267 -0
- data/test/cases/marshal_serialization_test.rb +39 -0
- data/test/cases/migration/change_schema_test.rb +504 -0
- data/test/cases/migration/change_table_test.rb +364 -0
- data/test/cases/migration/check_constraint_test.rb +162 -0
- data/test/cases/migration/column_attributes_test.rb +186 -0
- data/test/cases/migration/column_positioning_test.rb +68 -0
- data/test/cases/migration/columns_test.rb +326 -0
- data/test/cases/migration/command_recorder_test.rb +437 -0
- data/test/cases/migration/compatibility_test.rb +673 -0
- data/test/cases/migration/create_join_table_test.rb +167 -0
- data/test/cases/migration/foreign_key_test.rb +581 -0
- data/test/cases/migration/helper.rb +40 -0
- data/test/cases/migration/index_test.rb +267 -0
- data/test/cases/migration/logger_test.rb +39 -0
- data/test/cases/migration/pending_migrations_test.rb +106 -0
- data/test/cases/migration/references_foreign_key_test.rb +235 -0
- data/test/cases/migration/references_index_test.rb +120 -0
- data/test/cases/migration/references_statements_test.rb +137 -0
- data/test/cases/migration/rename_table_test.rb +116 -0
- data/test/cases/migration_test.rb +1525 -0
- data/test/cases/migrator_test.rb +527 -0
- data/test/cases/mixin_test.rb +64 -0
- data/test/cases/modules_test.rb +174 -0
- data/test/cases/multi_db_migrator_test.rb +223 -0
- data/test/cases/multiparameter_attributes_test.rb +399 -0
- data/test/cases/multiple_db_test.rb +116 -0
- data/test/cases/nested_attributes_test.rb +1119 -0
- data/test/cases/nested_attributes_with_callbacks_test.rb +146 -0
- data/test/cases/null_relation_test.rb +84 -0
- data/test/cases/numeric_data_test.rb +93 -0
- data/test/cases/persistence_test.rb +1093 -0
- data/test/cases/pooled_connections_test.rb +73 -0
- data/test/cases/prepared_statement_status_test.rb +48 -0
- data/test/cases/primary_keys_test.rb +482 -0
- data/test/cases/query_cache_test.rb +915 -0
- data/test/cases/quoting_test.rb +303 -0
- data/test/cases/readonly_test.rb +120 -0
- data/test/cases/reaper_test.rb +199 -0
- data/test/cases/reflection_test.rb +520 -0
- data/test/cases/relation/delegation_test.rb +76 -0
- data/test/cases/relation/delete_all_test.rb +117 -0
- data/test/cases/relation/merging_test.rb +434 -0
- data/test/cases/relation/mutation_test.rb +145 -0
- data/test/cases/relation/or_test.rb +192 -0
- data/test/cases/relation/predicate_builder_test.rb +31 -0
- data/test/cases/relation/record_fetch_warning_test.rb +42 -0
- 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 +141 -0
- data/test/cases/relation/where_clause_test.rb +257 -0
- data/test/cases/relation/where_test.rb +429 -0
- data/test/cases/relation_test.rb +482 -0
- data/test/cases/relations_test.rb +2251 -0
- data/test/cases/reload_models_test.rb +26 -0
- data/test/cases/reserved_word_test.rb +141 -0
- data/test/cases/result_test.rb +141 -0
- data/test/cases/sanitize_test.rb +192 -0
- data/test/cases/schema_dumper_test.rb +550 -0
- data/test/cases/schema_loading_test.rb +53 -0
- data/test/cases/scoping/default_scoping_test.rb +569 -0
- data/test/cases/scoping/named_scoping_test.rb +649 -0
- data/test/cases/scoping/relation_scoping_test.rb +522 -0
- data/test/cases/secure_token_test.rb +47 -0
- data/test/cases/serialization_test.rb +106 -0
- data/test/cases/serialized_attribute_test.rb +455 -0
- data/test/cases/signed_id_test.rb +168 -0
- data/test/cases/statement_cache_test.rb +153 -0
- data/test/cases/statement_invalid_test.rb +42 -0
- data/test/cases/store_test.rb +320 -0
- data/test/cases/strict_loading_test.rb +473 -0
- data/test/cases/suppressor_test.rb +77 -0
- data/test/cases/tasks/database_tasks_test.rb +1526 -0
- data/test/cases/tasks/mysql_rake_test.rb +417 -0
- data/test/cases/tasks/postgresql_rake_test.rb +534 -0
- data/test/cases/tasks/sqlite_rake_test.rb +267 -0
- data/test/cases/test_case.rb +142 -0
- data/test/cases/test_databases_test.rb +79 -0
- data/test/cases/test_fixtures_test.rb +96 -0
- data/test/cases/time_precision_test.rb +125 -0
- data/test/cases/timestamp_test.rb +504 -0
- data/test/cases/touch_later_test.rb +123 -0
- data/test/cases/transaction_callbacks_test.rb +772 -0
- data/test/cases/transaction_isolation_test.rb +106 -0
- data/test/cases/transactions_test.rb +1285 -0
- data/test/cases/type/adapter_specific_registry_test.rb +145 -0
- data/test/cases/type/date_time_test.rb +16 -0
- data/test/cases/type/integer_test.rb +29 -0
- data/test/cases/type/string_test.rb +24 -0
- data/test/cases/type/time_test.rb +28 -0
- data/test/cases/type/type_map_test.rb +178 -0
- data/test/cases/type/unsigned_integer_test.rb +19 -0
- data/test/cases/type_test.rb +41 -0
- data/test/cases/types_test.rb +26 -0
- data/test/cases/unconnected_test.rb +46 -0
- data/test/cases/unsafe_raw_sql_test.rb +274 -0
- data/test/cases/validations/absence_validation_test.rb +75 -0
- data/test/cases/validations/association_validation_test.rb +99 -0
- data/test/cases/validations/i18n_generate_message_validation_test.rb +102 -0
- data/test/cases/validations/i18n_validation_test.rb +87 -0
- data/test/cases/validations/length_validation_test.rb +80 -0
- data/test/cases/validations/numericality_validation_test.rb +181 -0
- data/test/cases/validations/presence_validation_test.rb +105 -0
- data/test/cases/validations/uniqueness_validation_test.rb +618 -0
- data/test/cases/validations_repair_helper.rb +21 -0
- data/test/cases/validations_test.rb +229 -0
- data/test/cases/view_test.rb +222 -0
- data/test/cases/yaml_serialization_test.rb +166 -0
- data/test/config.example.yml +97 -0
- data/test/config.rb +7 -0
- data/test/config.yml +220 -0
- data/test/connections/native_ibm_db/connection.rb +44 -0
- data/test/fixtures/accounts.yml +29 -0
- data/test/fixtures/admin/accounts.yml +2 -0
- data/test/fixtures/admin/randomly_named_a9.yml +7 -0
- data/test/fixtures/admin/randomly_named_b0.yml +7 -0
- data/test/fixtures/admin/users.yml +10 -0
- data/test/fixtures/all/admin +1 -0
- data/test/fixtures/all/developers.yml +0 -0
- data/test/fixtures/all/namespaced/accounts.yml +2 -0
- data/test/fixtures/all/people.yml +0 -0
- data/test/fixtures/all/tasks.yml +0 -0
- data/test/fixtures/author_addresses.yml +11 -0
- data/test/fixtures/author_favorites.yml +4 -0
- data/test/fixtures/authors.yml +17 -0
- data/test/fixtures/bad_posts.yml +9 -0
- data/test/fixtures/binaries.yml +137 -0
- data/test/fixtures/books.yml +38 -0
- data/test/fixtures/bulbs.yml +5 -0
- data/test/fixtures/cars.yml +9 -0
- data/test/fixtures/categories/special_categories.yml +9 -0
- data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -0
- data/test/fixtures/categories.yml +19 -0
- data/test/fixtures/categories_ordered.yml +7 -0
- data/test/fixtures/categories_posts.yml +34 -0
- data/test/fixtures/categorizations.yml +23 -0
- data/test/fixtures/citations.yml +5 -0
- data/test/fixtures/clubs.yml +8 -0
- data/test/fixtures/collections.yml +3 -0
- data/test/fixtures/colleges.yml +3 -0
- data/test/fixtures/comments.yml +72 -0
- data/test/fixtures/companies.yml +72 -0
- data/test/fixtures/computers.yml +12 -0
- data/test/fixtures/content.yml +3 -0
- data/test/fixtures/content_positions.yml +3 -0
- data/test/fixtures/courses.yml +8 -0
- data/test/fixtures/customers.yml +35 -0
- data/test/fixtures/dashboards.yml +6 -0
- data/test/fixtures/dead_parrots.yml +5 -0
- data/test/fixtures/developers.yml +22 -0
- data/test/fixtures/developers_projects.yml +17 -0
- data/test/fixtures/dog_lovers.yml +7 -0
- data/test/fixtures/dogs.yml +4 -0
- data/test/fixtures/doubloons.yml +3 -0
- data/test/fixtures/edges.yml +5 -0
- data/test/fixtures/entrants.yml +14 -0
- data/test/fixtures/essays.yml +16 -0
- data/test/fixtures/faces.yml +11 -0
- data/test/fixtures/fk_test_has_fk.yml +3 -0
- data/test/fixtures/fk_test_has_pk.yml +2 -0
- data/test/fixtures/friendships.yml +4 -0
- data/test/fixtures/funny_jokes.yml +10 -0
- data/test/fixtures/humans.yml +5 -0
- data/test/fixtures/interests.yml +33 -0
- data/test/fixtures/items.yml +3 -0
- data/test/fixtures/jobs.yml +7 -0
- data/test/fixtures/legacy_things.yml +3 -0
- data/test/fixtures/live_parrots.yml +4 -0
- data/test/fixtures/mateys.yml +4 -0
- data/test/fixtures/member_details.yml +8 -0
- data/test/fixtures/member_types.yml +6 -0
- data/test/fixtures/members.yml +11 -0
- data/test/fixtures/memberships.yml +41 -0
- data/test/fixtures/men.yml +5 -0
- data/test/fixtures/minimalistics.yml +5 -0
- data/test/fixtures/minivans.yml +5 -0
- data/test/fixtures/mixed_case_monkeys.yml +6 -0
- data/test/fixtures/mixins.yml +29 -0
- data/test/fixtures/movies.yml +7 -0
- data/test/fixtures/naked/yml/accounts.yml +1 -0
- data/test/fixtures/naked/yml/companies.yml +1 -0
- data/test/fixtures/naked/yml/courses.yml +1 -0
- data/test/fixtures/naked/yml/courses_with_invalid_key.yml +3 -0
- data/test/fixtures/naked/yml/parrots.yml +3 -0
- data/test/fixtures/naked/yml/trees.yml +3 -0
- data/test/fixtures/nodes.yml +29 -0
- data/test/fixtures/organizations.yml +5 -0
- data/test/fixtures/other_books.yml +26 -0
- data/test/fixtures/other_comments.yml +6 -0
- data/test/fixtures/other_dogs.yml +2 -0
- data/test/fixtures/other_posts.yml +8 -0
- data/test/fixtures/other_topics.yml +42 -0
- data/test/fixtures/owners.yml +9 -0
- data/test/fixtures/parrots.yml +33 -0
- data/test/fixtures/parrots_pirates.yml +7 -0
- data/test/fixtures/people.yml +24 -0
- data/test/fixtures/peoples_treasures.yml +3 -0
- data/test/fixtures/pets.yml +19 -0
- data/test/fixtures/pirates.yml +15 -0
- data/test/fixtures/posts.yml +88 -0
- data/test/fixtures/price_estimates.yml +16 -0
- data/test/fixtures/products.yml +4 -0
- data/test/fixtures/projects.yml +7 -0
- data/test/fixtures/randomly_named_a9.yml +7 -0
- data/test/fixtures/ratings.yml +14 -0
- data/test/fixtures/readers.yml +17 -0
- data/test/fixtures/references.yml +17 -0
- data/test/fixtures/reserved_words/distinct.yml +5 -0
- data/test/fixtures/reserved_words/distinct_select.yml +11 -0
- data/test/fixtures/reserved_words/group.yml +14 -0
- data/test/fixtures/reserved_words/select.yml +8 -0
- data/test/fixtures/reserved_words/values.yml +7 -0
- data/test/fixtures/ships.yml +6 -0
- data/test/fixtures/speedometers.yml +8 -0
- data/test/fixtures/sponsors.yml +15 -0
- data/test/fixtures/strict_zines.yml +2 -0
- data/test/fixtures/string_key_objects.yml +7 -0
- data/test/fixtures/subscribers.yml +11 -0
- data/test/fixtures/subscriptions.yml +12 -0
- data/test/fixtures/taggings.yml +78 -0
- data/test/fixtures/tags.yml +11 -0
- data/test/fixtures/tasks.yml +7 -0
- data/test/fixtures/teapots.yml +3 -0
- data/test/fixtures/to_be_linked/accounts.yml +2 -0
- data/test/fixtures/to_be_linked/users.yml +10 -0
- data/test/fixtures/topics.yml +49 -0
- data/test/fixtures/toys.yml +14 -0
- data/test/fixtures/traffic_lights.yml +10 -0
- data/test/fixtures/treasures.yml +10 -0
- data/test/fixtures/trees.yml +3 -0
- data/test/fixtures/uuid_children.yml +3 -0
- data/test/fixtures/uuid_parents.yml +2 -0
- data/test/fixtures/variants.yml +4 -0
- data/test/fixtures/vegetables.yml +20 -0
- data/test/fixtures/vertices.yml +4 -0
- data/test/fixtures/warehouse-things.yml +3 -0
- data/test/fixtures/warehouse_things.yml +3 -0
- data/test/fixtures/zines.yml +5 -0
- data/test/ibm_db_test.rb +25 -0
- data/test/migrations/10_urban/9_add_expressions.rb +13 -0
- data/test/migrations/decimal/1_give_me_big_numbers.rb +17 -0
- data/test/migrations/magic/1_currencies_have_symbols.rb +13 -0
- data/test/migrations/missing/1000_people_have_middle_names.rb +11 -0
- data/test/migrations/missing/1_people_have_last_names.rb +11 -0
- data/test/migrations/missing/3_we_need_reminders.rb +14 -0
- data/test/migrations/missing/4_innocent_jointable.rb +14 -0
- data/test/migrations/rename/1_we_need_things.rb +13 -0
- data/test/migrations/rename/2_rename_things.rb +11 -0
- data/test/migrations/to_copy/1_people_have_hobbies.rb +11 -0
- data/test/migrations/to_copy/2_people_have_descriptions.rb +11 -0
- data/test/migrations/to_copy2/1_create_articles.rb +9 -0
- data/test/migrations/to_copy2/2_create_comments.rb +9 -0
- data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +11 -0
- data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +11 -0
- data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +11 -0
- data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +9 -0
- data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +9 -0
- data/test/migrations/valid/1_valid_people_have_last_names.rb +11 -0
- data/test/migrations/valid/2_we_need_reminders.rb +14 -0
- data/test/migrations/valid/3_innocent_jointable.rb +14 -0
- data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +11 -0
- data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +14 -0
- data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +14 -0
- data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +11 -0
- data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +14 -0
- data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +14 -0
- data/test/migrations/version_check/20131219224947_migration_version_check.rb +10 -0
- data/test/models/account.rb +46 -0
- data/test/models/admin/account.rb +5 -0
- data/test/models/admin/randomly_named_c1.rb +9 -0
- data/test/models/admin/user.rb +48 -0
- data/test/models/admin.rb +7 -0
- data/test/models/aircraft.rb +7 -0
- data/test/models/arunit2_model.rb +5 -0
- data/test/models/author.rb +260 -0
- data/test/models/auto_id.rb +6 -0
- data/test/models/autoloadable/extra_firm.rb +4 -0
- data/test/models/binary.rb +4 -0
- data/test/models/binary_field.rb +6 -0
- data/test/models/bird.rb +24 -0
- data/test/models/book.rb +33 -0
- data/test/models/book_destroy_async.rb +24 -0
- data/test/models/boolean.rb +7 -0
- data/test/models/bulb.rb +61 -0
- data/test/models/cake_designer.rb +5 -0
- data/test/models/car.rb +36 -0
- data/test/models/carrier.rb +4 -0
- data/test/models/cart.rb +5 -0
- data/test/models/cat.rb +12 -0
- data/test/models/categorization.rb +21 -0
- data/test/models/category.rb +47 -0
- data/test/models/chef.rb +10 -0
- data/test/models/citation.rb +7 -0
- data/test/models/club.rb +28 -0
- data/test/models/college.rb +12 -0
- data/test/models/column.rb +5 -0
- data/test/models/column_name.rb +5 -0
- data/test/models/comment.rb +98 -0
- data/test/models/company.rb +226 -0
- data/test/models/company_in_module.rb +99 -0
- data/test/models/computer.rb +5 -0
- data/test/models/contact.rb +43 -0
- data/test/models/content.rb +42 -0
- data/test/models/contract.rb +38 -0
- data/test/models/country.rb +5 -0
- data/test/models/course.rb +8 -0
- data/test/models/customer.rb +85 -0
- data/test/models/customer_carrier.rb +16 -0
- data/test/models/dashboard.rb +5 -0
- data/test/models/default.rb +4 -0
- data/test/models/department.rb +6 -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 +341 -0
- 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 +7 -0
- data/test/models/dog_lover.rb +7 -0
- data/test/models/doubloon.rb +14 -0
- data/test/models/drink_designer.rb +20 -0
- data/test/models/edge.rb +7 -0
- data/test/models/electron.rb +7 -0
- data/test/models/engine.rb +5 -0
- data/test/models/entrant.rb +5 -0
- data/test/models/entry.rb +5 -0
- data/test/models/essay.rb +8 -0
- data/test/models/essay_destroy_async.rb +12 -0
- data/test/models/event.rb +5 -0
- data/test/models/eye.rb +39 -0
- data/test/models/face.rb +17 -0
- data/test/models/family.rb +6 -0
- data/test/models/family_tree.rb +6 -0
- data/test/models/friendship.rb +8 -0
- data/test/models/frog.rb +8 -0
- data/test/models/guid.rb +4 -0
- data/test/models/guitar.rb +6 -0
- data/test/models/hotel.rb +13 -0
- data/test/models/human.rb +39 -0
- data/test/models/image.rb +5 -0
- data/test/models/interest.rb +16 -0
- data/test/models/invoice.rb +6 -0
- data/test/models/item.rb +9 -0
- data/test/models/job.rb +9 -0
- data/test/models/joke.rb +9 -0
- data/test/models/keyboard.rb +5 -0
- data/test/models/legacy_thing.rb +5 -0
- data/test/models/lesson.rb +13 -0
- data/test/models/line_item.rb +5 -0
- data/test/models/liquid.rb +6 -0
- data/test/models/man.rb +11 -0
- data/test/models/matey.rb +6 -0
- data/test/models/measurement.rb +4 -0
- data/test/models/member.rb +45 -0
- data/test/models/member_detail.rb +11 -0
- data/test/models/member_type.rb +5 -0
- data/test/models/membership.rb +38 -0
- data/test/models/mentor.rb +5 -0
- data/test/models/message.rb +5 -0
- data/test/models/minimalistic.rb +4 -0
- data/test/models/minivan.rb +10 -0
- data/test/models/mixed_case_monkey.rb +5 -0
- data/test/models/mocktail_designer.rb +2 -0
- data/test/models/molecule.rb +8 -0
- data/test/models/mouse.rb +6 -0
- data/test/models/movie.rb +7 -0
- data/test/models/node.rb +7 -0
- data/test/models/non_primary_key.rb +4 -0
- data/test/models/notification.rb +5 -0
- data/test/models/numeric_data.rb +12 -0
- data/test/models/order.rb +6 -0
- data/test/models/organization.rb +16 -0
- data/test/models/other_dog.rb +7 -0
- data/test/models/owner.rb +39 -0
- data/test/models/parrot.rb +36 -0
- data/test/models/person.rb +147 -0
- data/test/models/personal_legacy_thing.rb +6 -0
- data/test/models/pet.rb +20 -0
- data/test/models/pet_treasure.rb +8 -0
- data/test/models/pirate.rb +116 -0
- data/test/models/possession.rb +5 -0
- data/test/models/post.rb +371 -0
- data/test/models/price_estimate.rb +14 -0
- data/test/models/professor.rb +7 -0
- data/test/models/project.rb +42 -0
- data/test/models/publisher/article.rb +6 -0
- data/test/models/publisher/magazine.rb +5 -0
- data/test/models/publisher.rb +4 -0
- data/test/models/randomly_named_c1.rb +5 -0
- data/test/models/rating.rb +8 -0
- data/test/models/reader.rb +25 -0
- data/test/models/recipe.rb +5 -0
- data/test/models/record.rb +4 -0
- data/test/models/reference.rb +25 -0
- data/test/models/reply.rb +79 -0
- 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 +42 -0
- data/test/models/ship_part.rb +10 -0
- data/test/models/shop.rb +19 -0
- data/test/models/shop_account.rb +8 -0
- data/test/models/speedometer.rb +8 -0
- data/test/models/sponsor.rb +10 -0
- data/test/models/squeak.rb +6 -0
- data/test/models/strict_zine.rb +7 -0
- data/test/models/string_key_object.rb +5 -0
- data/test/models/student.rb +6 -0
- data/test/models/subject.rb +16 -0
- data/test/models/subscriber.rb +10 -0
- data/test/models/subscription.rb +8 -0
- data/test/models/tag.rb +16 -0
- data/test/models/tagging.rb +20 -0
- data/test/models/task.rb +7 -0
- data/test/models/topic.rb +153 -0
- data/test/models/toy.rb +10 -0
- data/test/models/traffic_light.rb +6 -0
- data/test/models/treasure.rb +16 -0
- data/test/models/treaty.rb +5 -0
- data/test/models/tree.rb +5 -0
- data/test/models/tuning_peg.rb +6 -0
- data/test/models/tyre.rb +13 -0
- data/test/models/user.rb +22 -0
- data/test/models/uuid_child.rb +5 -0
- data/test/models/uuid_item.rb +8 -0
- data/test/models/uuid_parent.rb +5 -0
- data/test/models/vegetables.rb +33 -0
- data/test/models/vehicle.rb +7 -0
- data/test/models/vertex.rb +11 -0
- data/test/models/warehouse_thing.rb +7 -0
- data/test/models/wheel.rb +5 -0
- data/test/models/without_table.rb +5 -0
- data/test/models/zine.rb +5 -0
- data/test/schema/i5/ibm_db_specific_schema.rb +137 -0
- data/test/schema/ids/ibm_db_specific_schema.rb +140 -0
- data/test/schema/luw/ibm_db_specific_schema.rb +137 -0
- data/test/schema/mysql2_specific_schema.rb +82 -0
- data/test/schema/oracle_specific_schema.rb +38 -0
- data/test/schema/postgresql_specific_schema.rb +125 -0
- data/test/schema/schema.rb +1237 -0
- data/test/schema/schema.rb.original +1057 -0
- data/test/schema/sqlite_specific_schema.rb +11 -0
- data/test/schema/zOS/ibm_db_specific_schema.rb +208 -0
- data/test/support/config.rb +43 -0
- data/test/support/connection.rb +29 -0
- data/test/support/connection_helper.rb +16 -0
- data/test/support/ddl_helper.rb +10 -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 +22 -0
- data/test/support/stubs/strong_parameters.rb +40 -0
- data/test/support/yaml_compatibility_fixtures/rails_4_1.yml +22 -0
- data/test/support/yaml_compatibility_fixtures/rails_4_2_0.yml +182 -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 +876 -0
@@ -0,0 +1,1493 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cases/helper"
|
4
|
+
require "models/developer"
|
5
|
+
require "models/project"
|
6
|
+
require "models/company"
|
7
|
+
require "models/topic"
|
8
|
+
require "models/reply"
|
9
|
+
require "models/computer"
|
10
|
+
require "models/post"
|
11
|
+
require "models/author"
|
12
|
+
require "models/tag"
|
13
|
+
require "models/tagging"
|
14
|
+
require "models/comment"
|
15
|
+
require "models/sponsor"
|
16
|
+
require "models/member"
|
17
|
+
require "models/essay"
|
18
|
+
require "models/toy"
|
19
|
+
require "models/invoice"
|
20
|
+
require "models/line_item"
|
21
|
+
require "models/column"
|
22
|
+
require "models/record"
|
23
|
+
require "models/admin"
|
24
|
+
require "models/admin/user"
|
25
|
+
require "models/ship"
|
26
|
+
require "models/treasure"
|
27
|
+
require "models/parrot"
|
28
|
+
require "models/book"
|
29
|
+
require "models/citation"
|
30
|
+
|
31
|
+
class BelongsToAssociationsTest < ActiveRecord::TestCase
|
32
|
+
fixtures :accounts, :companies, :developers, :projects, :topics,
|
33
|
+
:developers_projects, :computers, :authors, :author_addresses,
|
34
|
+
:essays, :posts, :tags, :taggings, :comments, :sponsors, :members
|
35
|
+
|
36
|
+
def test_belongs_to
|
37
|
+
client = Client.find(3)
|
38
|
+
first_firm = companies(:first_firm)
|
39
|
+
assert_sql(/LIMIT|ROWNUM <=|FETCH FIRST/) do
|
40
|
+
assert_equal first_firm, client.firm
|
41
|
+
assert_equal first_firm.name, client.firm.name
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_where_with_custom_primary_key
|
46
|
+
assert_equal [authors(:david)], Author.where(owned_essay: essays(:david_modest_proposal))
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_find_by_with_custom_primary_key
|
50
|
+
assert_equal authors(:david), Author.find_by(owned_essay: essays(:david_modest_proposal))
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_where_on_polymorphic_association_with_nil
|
54
|
+
assert_equal comments(:greetings), Comment.where(author: nil).first
|
55
|
+
assert_equal comments(:greetings), Comment.where(author: [nil]).first
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_where_on_polymorphic_association_with_empty_array
|
59
|
+
assert_empty Comment.where(author: [])
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_assigning_belongs_to_on_destroyed_object
|
63
|
+
client = Client.create!(name: "Client")
|
64
|
+
client.destroy!
|
65
|
+
assert_raise(FrozenError) { client.firm = nil }
|
66
|
+
assert_raise(FrozenError) { client.firm = Firm.new(name: "Firm") }
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_eager_loading_wont_mutate_owner_record
|
70
|
+
client = Client.eager_load(:firm_with_basic_id).first
|
71
|
+
assert_not_predicate client, :firm_id_came_from_user?
|
72
|
+
|
73
|
+
client = Client.preload(:firm_with_basic_id).first
|
74
|
+
assert_not_predicate client, :firm_id_came_from_user?
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_missing_attribute_error_is_raised_when_no_foreign_key_attribute
|
78
|
+
assert_raises(ActiveModel::MissingAttributeError) { Client.select(:id).first.firm }
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_belongs_to_does_not_use_order_by
|
82
|
+
sql_log = capture_sql { Client.find(3).firm }
|
83
|
+
assert sql_log.all? { |sql| !/order by/i.match?(sql) }, "ORDER BY was used in the query: #{sql_log}"
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_belongs_to_with_primary_key
|
87
|
+
client = Client.create(name: "Primary key client", firm_name: companies(:first_firm).name)
|
88
|
+
assert_equal companies(:first_firm).name, client.firm_with_primary_key.name
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_belongs_to_with_primary_key_joins_on_correct_column
|
92
|
+
sql = Client.joins(:firm_with_primary_key).to_sql
|
93
|
+
if current_adapter?(:Mysql2Adapter)
|
94
|
+
assert_no_match(/`firm_with_primary_keys_companies`\.`id`/, sql)
|
95
|
+
assert_match(/`firm_with_primary_keys_companies`\.`name`/, sql)
|
96
|
+
elsif current_adapter?(:OracleAdapter)
|
97
|
+
# on Oracle aliases are truncated to 30 characters and are quoted in uppercase
|
98
|
+
assert_no_match(/"firm_with_primary_keys_compani"\."id"/i, sql)
|
99
|
+
assert_match(/"firm_with_primary_keys_compani"\."name"/i, sql)
|
100
|
+
else
|
101
|
+
assert_no_match(/firm_with_primary_keys_companies\.id/, sql)
|
102
|
+
assert_match(/firm_with_primary_keys_companies\.name/, sql)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_optional_relation_can_be_set_per_model
|
107
|
+
model1 = Class.new(ActiveRecord::Base) do
|
108
|
+
self.table_name = "accounts"
|
109
|
+
self.belongs_to_required_by_default = false
|
110
|
+
|
111
|
+
belongs_to :company
|
112
|
+
|
113
|
+
def self.name
|
114
|
+
"FirstModel"
|
115
|
+
end
|
116
|
+
end.new
|
117
|
+
|
118
|
+
model2 = Class.new(ActiveRecord::Base) do
|
119
|
+
self.table_name = "accounts"
|
120
|
+
self.belongs_to_required_by_default = true
|
121
|
+
|
122
|
+
belongs_to :company
|
123
|
+
|
124
|
+
def self.name
|
125
|
+
"SecondModel"
|
126
|
+
end
|
127
|
+
end.new
|
128
|
+
|
129
|
+
assert_predicate model1, :valid?
|
130
|
+
assert_not_predicate model2, :valid?
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_optional_relation
|
134
|
+
original_value = ActiveRecord::Base.belongs_to_required_by_default
|
135
|
+
ActiveRecord::Base.belongs_to_required_by_default = true
|
136
|
+
|
137
|
+
model = Class.new(ActiveRecord::Base) do
|
138
|
+
self.table_name = "accounts"
|
139
|
+
def self.name; "Temp"; end
|
140
|
+
belongs_to :company, optional: true
|
141
|
+
end
|
142
|
+
|
143
|
+
account = model.new
|
144
|
+
assert_predicate account, :valid?
|
145
|
+
ensure
|
146
|
+
ActiveRecord::Base.belongs_to_required_by_default = original_value
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_not_optional_relation
|
150
|
+
original_value = ActiveRecord::Base.belongs_to_required_by_default
|
151
|
+
ActiveRecord::Base.belongs_to_required_by_default = true
|
152
|
+
|
153
|
+
model = Class.new(ActiveRecord::Base) do
|
154
|
+
self.table_name = "accounts"
|
155
|
+
def self.name; "Temp"; end
|
156
|
+
belongs_to :company, optional: false
|
157
|
+
end
|
158
|
+
|
159
|
+
account = model.new
|
160
|
+
assert_not_predicate account, :valid?
|
161
|
+
assert_equal [{ error: :blank }], account.errors.details[:company]
|
162
|
+
ensure
|
163
|
+
ActiveRecord::Base.belongs_to_required_by_default = original_value
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_required_belongs_to_config
|
167
|
+
original_value = ActiveRecord::Base.belongs_to_required_by_default
|
168
|
+
ActiveRecord::Base.belongs_to_required_by_default = true
|
169
|
+
|
170
|
+
model = Class.new(ActiveRecord::Base) do
|
171
|
+
self.table_name = "accounts"
|
172
|
+
def self.name; "Temp"; end
|
173
|
+
belongs_to :company
|
174
|
+
end
|
175
|
+
|
176
|
+
account = model.new
|
177
|
+
assert_not_predicate account, :valid?
|
178
|
+
assert_equal [{ error: :blank }], account.errors.details[:company]
|
179
|
+
ensure
|
180
|
+
ActiveRecord::Base.belongs_to_required_by_default = original_value
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_default
|
184
|
+
david = developers(:david)
|
185
|
+
jamis = developers(:jamis)
|
186
|
+
|
187
|
+
model = Class.new(ActiveRecord::Base) do
|
188
|
+
self.table_name = "ships"
|
189
|
+
def self.name; "Temp"; end
|
190
|
+
belongs_to :developer, default: -> { david }
|
191
|
+
end
|
192
|
+
|
193
|
+
ship = model.create!
|
194
|
+
assert_equal david, ship.developer
|
195
|
+
|
196
|
+
ship = model.create!(developer: jamis)
|
197
|
+
assert_equal jamis, ship.developer
|
198
|
+
|
199
|
+
ship.update!(developer: nil)
|
200
|
+
assert_equal david, ship.developer
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_default_with_lambda
|
204
|
+
model = Class.new(ActiveRecord::Base) do
|
205
|
+
self.table_name = "ships"
|
206
|
+
def self.name; "Temp"; end
|
207
|
+
belongs_to :developer, default: -> { default_developer }
|
208
|
+
|
209
|
+
def default_developer
|
210
|
+
Developer.first
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
ship = model.create!
|
215
|
+
assert_equal developers(:david), ship.developer
|
216
|
+
|
217
|
+
ship = model.create!(developer: developers(:jamis))
|
218
|
+
assert_equal developers(:jamis), ship.developer
|
219
|
+
end
|
220
|
+
|
221
|
+
def test_default_scope_on_relations_is_not_cached
|
222
|
+
counter = 0
|
223
|
+
|
224
|
+
comments = Class.new(ActiveRecord::Base) {
|
225
|
+
self.table_name = "comments"
|
226
|
+
self.inheritance_column = "not_there"
|
227
|
+
|
228
|
+
posts = Class.new(ActiveRecord::Base) {
|
229
|
+
self.table_name = "posts"
|
230
|
+
self.inheritance_column = "not_there"
|
231
|
+
|
232
|
+
default_scope -> {
|
233
|
+
counter += 1
|
234
|
+
where("id = :inc", inc: counter)
|
235
|
+
}
|
236
|
+
|
237
|
+
has_many :comments, anonymous_class: comments
|
238
|
+
}
|
239
|
+
belongs_to :post, anonymous_class: posts, inverse_of: false
|
240
|
+
}
|
241
|
+
|
242
|
+
assert_equal 0, counter
|
243
|
+
comment = comments.first
|
244
|
+
assert_equal 0, counter
|
245
|
+
sql = capture_sql { comment.post }
|
246
|
+
comment.reload
|
247
|
+
assert_not_equal sql, capture_sql { comment.post }
|
248
|
+
end
|
249
|
+
|
250
|
+
def test_proxy_assignment
|
251
|
+
account = Account.find(1)
|
252
|
+
assert_nothing_raised { account.firm = account.firm }
|
253
|
+
end
|
254
|
+
|
255
|
+
def test_type_mismatch
|
256
|
+
assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = 1 }
|
257
|
+
assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = Project.find(1) }
|
258
|
+
end
|
259
|
+
|
260
|
+
def test_raises_type_mismatch_with_namespaced_class
|
261
|
+
assert_nil defined?(Region), "This test requires that there is no top-level Region class"
|
262
|
+
|
263
|
+
ActiveRecord::Base.connection.instance_eval do
|
264
|
+
create_table(:admin_regions, force: true) { |t| t.string :name }
|
265
|
+
add_column :admin_users, :region_id, :integer
|
266
|
+
end
|
267
|
+
Admin.const_set "RegionalUser", Class.new(Admin::User) { belongs_to(:region) }
|
268
|
+
Admin.const_set "Region", Class.new(ActiveRecord::Base)
|
269
|
+
|
270
|
+
e = assert_raise(ActiveRecord::AssociationTypeMismatch) {
|
271
|
+
Admin::RegionalUser.new(region: "wrong value")
|
272
|
+
}
|
273
|
+
assert_match(/^Region\([^)]+\) expected, got "wrong value" which is an instance of String\([^)]+\)$/, e.message)
|
274
|
+
ensure
|
275
|
+
Admin.send :remove_const, "Region" if Admin.const_defined?("Region")
|
276
|
+
Admin.send :remove_const, "RegionalUser" if Admin.const_defined?("RegionalUser")
|
277
|
+
|
278
|
+
ActiveRecord::Base.connection.instance_eval do
|
279
|
+
remove_column :admin_users, :region_id if column_exists?(:admin_users, :region_id)
|
280
|
+
drop_table :admin_regions, if_exists: true
|
281
|
+
end
|
282
|
+
|
283
|
+
Admin::User.reset_column_information
|
284
|
+
end
|
285
|
+
|
286
|
+
def test_natural_assignment
|
287
|
+
apple = Firm.create("name" => "Apple")
|
288
|
+
citibank = Account.create("credit_limit" => 10)
|
289
|
+
citibank.firm = apple
|
290
|
+
assert_equal apple.id, citibank.firm_id
|
291
|
+
end
|
292
|
+
|
293
|
+
def test_id_assignment
|
294
|
+
apple = Firm.create("name" => "Apple")
|
295
|
+
citibank = Account.create("credit_limit" => 10)
|
296
|
+
citibank.firm_id = apple
|
297
|
+
assert_nil citibank.firm_id
|
298
|
+
end
|
299
|
+
|
300
|
+
def test_natural_assignment_with_primary_key
|
301
|
+
apple = Firm.create("name" => "Apple")
|
302
|
+
citibank = Client.create("name" => "Primary key client")
|
303
|
+
citibank.firm_with_primary_key = apple
|
304
|
+
assert_equal apple.name, citibank.firm_name
|
305
|
+
end
|
306
|
+
|
307
|
+
def test_eager_loading_with_primary_key
|
308
|
+
Firm.create("name" => "Apple")
|
309
|
+
Client.create("name" => "Citibank", :firm_name => "Apple")
|
310
|
+
citibank_result = Client.all.merge!(where: { name: "Citibank" }, includes: :firm_with_primary_key).first
|
311
|
+
assert_predicate citibank_result.association(:firm_with_primary_key), :loaded?
|
312
|
+
end
|
313
|
+
|
314
|
+
def test_eager_loading_with_primary_key_as_symbol
|
315
|
+
Firm.create("name" => "Apple")
|
316
|
+
Client.create("name" => "Citibank", :firm_name => "Apple")
|
317
|
+
citibank_result = Client.all.merge!(where: { name: "Citibank" }, includes: :firm_with_primary_key_symbols).first
|
318
|
+
assert_predicate citibank_result.association(:firm_with_primary_key_symbols), :loaded?
|
319
|
+
end
|
320
|
+
|
321
|
+
def test_creating_the_belonging_object
|
322
|
+
citibank = Account.create("credit_limit" => 10)
|
323
|
+
apple = citibank.create_firm("name" => "Apple")
|
324
|
+
assert_equal apple, citibank.firm
|
325
|
+
citibank.save
|
326
|
+
citibank.reload
|
327
|
+
assert_equal apple, citibank.firm
|
328
|
+
end
|
329
|
+
|
330
|
+
def test_creating_the_belonging_object_from_new_record
|
331
|
+
citibank = Account.new("credit_limit" => 10)
|
332
|
+
apple = citibank.create_firm("name" => "Apple")
|
333
|
+
assert_equal apple, citibank.firm
|
334
|
+
citibank.save
|
335
|
+
citibank.reload
|
336
|
+
assert_equal apple, citibank.firm
|
337
|
+
end
|
338
|
+
|
339
|
+
def test_creating_the_belonging_object_with_primary_key
|
340
|
+
client = Client.create(name: "Primary key client")
|
341
|
+
apple = client.create_firm_with_primary_key("name" => "Apple")
|
342
|
+
assert_equal apple, client.firm_with_primary_key
|
343
|
+
client.save
|
344
|
+
client.reload
|
345
|
+
assert_equal apple, client.firm_with_primary_key
|
346
|
+
end
|
347
|
+
|
348
|
+
def test_building_the_belonging_object
|
349
|
+
citibank = Account.create("credit_limit" => 10)
|
350
|
+
apple = citibank.build_firm("name" => "Apple")
|
351
|
+
citibank.save
|
352
|
+
assert_equal apple.id, citibank.firm_id
|
353
|
+
end
|
354
|
+
|
355
|
+
def test_building_the_belonging_object_with_implicit_sti_base_class
|
356
|
+
account = Account.new
|
357
|
+
company = account.build_firm
|
358
|
+
assert_kind_of Company, company, "Expected #{company.class} to be a Company"
|
359
|
+
end
|
360
|
+
|
361
|
+
def test_building_the_belonging_object_with_explicit_sti_base_class
|
362
|
+
account = Account.new
|
363
|
+
company = account.build_firm(type: "Company")
|
364
|
+
assert_kind_of Company, company, "Expected #{company.class} to be a Company"
|
365
|
+
end
|
366
|
+
|
367
|
+
def test_building_the_belonging_object_with_sti_subclass
|
368
|
+
account = Account.new
|
369
|
+
company = account.build_firm(type: "Firm")
|
370
|
+
assert_kind_of Firm, company, "Expected #{company.class} to be a Firm"
|
371
|
+
end
|
372
|
+
|
373
|
+
def test_building_the_belonging_object_with_an_invalid_type
|
374
|
+
account = Account.new
|
375
|
+
assert_raise(ActiveRecord::SubclassNotFound) { account.build_firm(type: "InvalidType") }
|
376
|
+
end
|
377
|
+
|
378
|
+
def test_building_the_belonging_object_with_an_unrelated_type
|
379
|
+
account = Account.new
|
380
|
+
assert_raise(ActiveRecord::SubclassNotFound) { account.build_firm(type: "Account") }
|
381
|
+
end
|
382
|
+
|
383
|
+
def test_building_the_belonging_object_with_primary_key
|
384
|
+
client = Client.create(name: "Primary key client")
|
385
|
+
apple = client.build_firm_with_primary_key("name" => "Apple")
|
386
|
+
client.save
|
387
|
+
assert_equal apple.name, client.firm_name
|
388
|
+
end
|
389
|
+
|
390
|
+
def test_create!
|
391
|
+
client = Client.create!(name: "Jimmy")
|
392
|
+
account = client.create_account!(credit_limit: 10)
|
393
|
+
assert_equal account, client.account
|
394
|
+
assert_predicate account, :persisted?
|
395
|
+
client.save
|
396
|
+
client.reload
|
397
|
+
assert_equal account, client.account
|
398
|
+
end
|
399
|
+
|
400
|
+
def test_failing_create!
|
401
|
+
client = Client.create!(name: "Jimmy")
|
402
|
+
assert_raise(ActiveRecord::RecordInvalid) { client.create_account! }
|
403
|
+
assert_not_nil client.account
|
404
|
+
assert_predicate client.account, :new_record?
|
405
|
+
end
|
406
|
+
|
407
|
+
def test_reloading_the_belonging_object
|
408
|
+
odegy_account = accounts(:odegy_account)
|
409
|
+
|
410
|
+
assert_equal "Odegy", odegy_account.firm.name
|
411
|
+
Company.where(id: odegy_account.firm_id).update_all(name: "ODEGY")
|
412
|
+
assert_equal "Odegy", odegy_account.firm.name
|
413
|
+
|
414
|
+
assert_equal "ODEGY", odegy_account.reload_firm.name
|
415
|
+
end
|
416
|
+
|
417
|
+
def test_reload_the_belonging_object_with_query_cache
|
418
|
+
odegy_account_id = accounts(:odegy_account).id
|
419
|
+
|
420
|
+
connection = ActiveRecord::Base.connection
|
421
|
+
connection.enable_query_cache!
|
422
|
+
connection.clear_query_cache
|
423
|
+
|
424
|
+
# Populate the cache with a query
|
425
|
+
odegy_account = Account.find(odegy_account_id)
|
426
|
+
|
427
|
+
# Populate the cache with a second query
|
428
|
+
odegy_account.firm
|
429
|
+
|
430
|
+
assert_equal 2, connection.query_cache.size
|
431
|
+
|
432
|
+
# Clear the cache and fetch the firm again, populating the cache with a query
|
433
|
+
assert_queries(1) { odegy_account.reload_firm }
|
434
|
+
|
435
|
+
# This query is not cached anymore, so it should make a real SQL query
|
436
|
+
assert_queries(1) { Account.find(odegy_account_id) }
|
437
|
+
ensure
|
438
|
+
ActiveRecord::Base.connection.disable_query_cache!
|
439
|
+
end
|
440
|
+
|
441
|
+
def test_natural_assignment_to_nil
|
442
|
+
client = Client.find(3)
|
443
|
+
client.firm = nil
|
444
|
+
client.save
|
445
|
+
client.association(:firm).reload
|
446
|
+
assert_nil client.firm
|
447
|
+
assert_nil client.client_of
|
448
|
+
end
|
449
|
+
|
450
|
+
def test_natural_assignment_to_nil_with_primary_key
|
451
|
+
client = Client.create(name: "Primary key client", firm_name: companies(:first_firm).name)
|
452
|
+
client.firm_with_primary_key = nil
|
453
|
+
client.save
|
454
|
+
client.association(:firm_with_primary_key).reload
|
455
|
+
assert_nil client.firm_with_primary_key
|
456
|
+
assert_nil client.client_of
|
457
|
+
end
|
458
|
+
|
459
|
+
def test_with_different_class_name
|
460
|
+
assert_equal Company.find(1).name, Company.find(3).firm_with_other_name.name
|
461
|
+
assert_not_nil Company.find(3).firm_with_other_name, "Microsoft should have a firm"
|
462
|
+
end
|
463
|
+
|
464
|
+
def test_with_condition
|
465
|
+
assert_equal Company.find(1).name, Company.find(3).firm_with_condition.name
|
466
|
+
assert_not_nil Company.find(3).firm_with_condition, "Microsoft should have a firm"
|
467
|
+
end
|
468
|
+
|
469
|
+
def test_polymorphic_association_class
|
470
|
+
sponsor = Sponsor.new
|
471
|
+
assert_nil sponsor.association(:sponsorable).klass
|
472
|
+
sponsor.association(:sponsorable).reload
|
473
|
+
assert_nil sponsor.sponsorable
|
474
|
+
|
475
|
+
sponsor.sponsorable_type = "" # the column doesn't have to be declared NOT NULL
|
476
|
+
assert_nil sponsor.association(:sponsorable).klass
|
477
|
+
sponsor.association(:sponsorable).reload
|
478
|
+
assert_nil sponsor.sponsorable
|
479
|
+
|
480
|
+
sponsor.sponsorable = Member.new name: "Bert"
|
481
|
+
assert_equal Member, sponsor.association(:sponsorable).klass
|
482
|
+
end
|
483
|
+
|
484
|
+
def test_with_polymorphic_and_condition
|
485
|
+
sponsor = Sponsor.create
|
486
|
+
member = Member.create name: "Bert"
|
487
|
+
|
488
|
+
sponsor.sponsorable = member
|
489
|
+
sponsor.save!
|
490
|
+
|
491
|
+
assert_equal member, sponsor.sponsorable
|
492
|
+
assert_nil sponsor.sponsorable_with_conditions
|
493
|
+
|
494
|
+
sponsor = Sponsor.preload(:sponsorable, :sponsorable_with_conditions).last
|
495
|
+
|
496
|
+
assert_equal member, sponsor.sponsorable
|
497
|
+
assert_nil sponsor.sponsorable_with_conditions
|
498
|
+
end
|
499
|
+
|
500
|
+
def test_with_select
|
501
|
+
assert_equal 1, Post.find(2).author_with_select.attributes.size
|
502
|
+
assert_equal 1, Post.includes(:author_with_select).find(2).author_with_select.attributes.size
|
503
|
+
end
|
504
|
+
|
505
|
+
def test_custom_attribute_with_select
|
506
|
+
assert_equal 2, Company.find(2).firm_with_select.attributes.size
|
507
|
+
assert_equal 2, Company.includes(:firm_with_select).find(2).firm_with_select.attributes.size
|
508
|
+
end
|
509
|
+
|
510
|
+
def test_belongs_to_without_counter_cache_option
|
511
|
+
# Ship has a conventionally named `treasures_count` column, but the counter_cache
|
512
|
+
# option is not given on the association.
|
513
|
+
ship = Ship.create(name: "Countless")
|
514
|
+
|
515
|
+
assert_no_difference lambda { ship.reload.treasures_count }, "treasures_count should not be changed unless counter_cache is given on the relation" do
|
516
|
+
treasure = Treasure.new(name: "Gold", ship: ship)
|
517
|
+
treasure.save
|
518
|
+
end
|
519
|
+
|
520
|
+
assert_no_difference lambda { ship.reload.treasures_count }, "treasures_count should not be changed unless counter_cache is given on the relation" do
|
521
|
+
treasure = ship.treasures.first
|
522
|
+
treasure.destroy
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
def test_belongs_to_counter
|
527
|
+
debate = Topic.create("title" => "debate")
|
528
|
+
assert_equal 0, debate.read_attribute("replies_count"), "No replies yet"
|
529
|
+
|
530
|
+
trash = debate.replies.create("title" => "blah!", "content" => "world around!")
|
531
|
+
assert_equal 1, Topic.find(debate.id).read_attribute("replies_count"), "First reply created"
|
532
|
+
|
533
|
+
trash.destroy
|
534
|
+
assert_equal 0, Topic.find(debate.id).read_attribute("replies_count"), "First reply deleted"
|
535
|
+
end
|
536
|
+
|
537
|
+
def test_belongs_to_counter_with_assigning_nil
|
538
|
+
topic = Topic.create!(title: "debate")
|
539
|
+
reply = Reply.create!(title: "blah!", content: "world around!", topic: topic)
|
540
|
+
|
541
|
+
assert_equal topic.id, reply.parent_id
|
542
|
+
assert_equal 1, topic.reload.replies.size
|
543
|
+
|
544
|
+
reply.topic = nil
|
545
|
+
reply.reload
|
546
|
+
|
547
|
+
assert_equal topic.id, reply.parent_id
|
548
|
+
assert_equal 1, topic.reload.replies.size
|
549
|
+
|
550
|
+
reply.topic = nil
|
551
|
+
reply.save!
|
552
|
+
|
553
|
+
assert_equal 0, topic.reload.replies.size
|
554
|
+
end
|
555
|
+
|
556
|
+
def test_belongs_to_counter_with_assigning_new_object
|
557
|
+
topic = Topic.create!(title: "debate")
|
558
|
+
reply = Reply.create!(title: "blah!", content: "world around!", topic: topic)
|
559
|
+
|
560
|
+
assert_equal topic.id, reply.parent_id
|
561
|
+
assert_equal 1, topic.reload.replies_count
|
562
|
+
|
563
|
+
topic2 = reply.build_topic(title: "debate2")
|
564
|
+
reply.save!
|
565
|
+
|
566
|
+
assert_not_equal topic.id, reply.parent_id
|
567
|
+
assert_equal topic2.id, reply.parent_id
|
568
|
+
|
569
|
+
assert_equal 0, topic.reload.replies_count
|
570
|
+
assert_equal 1, topic2.reload.replies_count
|
571
|
+
end
|
572
|
+
|
573
|
+
def test_belongs_to_with_primary_key_counter
|
574
|
+
debate = Topic.create("title" => "debate")
|
575
|
+
debate2 = Topic.create("title" => "debate2")
|
576
|
+
reply = Reply.create("title" => "blah!", "content" => "world around!", "parent_title" => "debate2")
|
577
|
+
|
578
|
+
assert_equal 0, debate.reload.replies_count
|
579
|
+
assert_equal 1, debate2.reload.replies_count
|
580
|
+
|
581
|
+
reply.parent_title = "debate"
|
582
|
+
reply.save!
|
583
|
+
|
584
|
+
assert_equal 1, debate.reload.replies_count
|
585
|
+
assert_equal 0, debate2.reload.replies_count
|
586
|
+
|
587
|
+
assert_no_queries do
|
588
|
+
reply.topic_with_primary_key = debate
|
589
|
+
end
|
590
|
+
|
591
|
+
assert_equal 1, debate.reload.replies_count
|
592
|
+
assert_equal 0, debate2.reload.replies_count
|
593
|
+
|
594
|
+
reply.topic_with_primary_key = debate2
|
595
|
+
reply.save!
|
596
|
+
|
597
|
+
assert_equal 0, debate.reload.replies_count
|
598
|
+
assert_equal 1, debate2.reload.replies_count
|
599
|
+
|
600
|
+
reply.topic_with_primary_key = nil
|
601
|
+
reply.save!
|
602
|
+
|
603
|
+
assert_equal 0, debate.reload.replies_count
|
604
|
+
assert_equal 0, debate2.reload.replies_count
|
605
|
+
end
|
606
|
+
|
607
|
+
def test_belongs_to_counter_with_reassigning
|
608
|
+
topic1 = Topic.create("title" => "t1")
|
609
|
+
topic2 = Topic.create("title" => "t2")
|
610
|
+
reply1 = Reply.new("title" => "r1", "content" => "r1")
|
611
|
+
reply1.topic = topic1
|
612
|
+
|
613
|
+
assert reply1.save
|
614
|
+
assert_equal 1, Topic.find(topic1.id).replies.size
|
615
|
+
assert_equal 0, Topic.find(topic2.id).replies.size
|
616
|
+
|
617
|
+
reply1.topic = Topic.find(topic2.id)
|
618
|
+
|
619
|
+
assert_no_queries do
|
620
|
+
reply1.topic = topic2
|
621
|
+
end
|
622
|
+
|
623
|
+
assert reply1.save
|
624
|
+
assert_equal 0, Topic.find(topic1.id).replies.size
|
625
|
+
assert_equal 1, Topic.find(topic2.id).replies.size
|
626
|
+
|
627
|
+
reply1.topic = nil
|
628
|
+
reply1.save!
|
629
|
+
|
630
|
+
assert_equal 0, Topic.find(topic1.id).replies.size
|
631
|
+
assert_equal 0, Topic.find(topic2.id).replies.size
|
632
|
+
|
633
|
+
reply1.topic = topic1
|
634
|
+
reply1.save!
|
635
|
+
|
636
|
+
assert_equal 1, Topic.find(topic1.id).replies.size
|
637
|
+
assert_equal 0, Topic.find(topic2.id).replies.size
|
638
|
+
|
639
|
+
reply1.destroy
|
640
|
+
|
641
|
+
assert_equal 0, Topic.find(topic1.id).replies.size
|
642
|
+
assert_equal 0, Topic.find(topic2.id).replies.size
|
643
|
+
end
|
644
|
+
|
645
|
+
def test_belongs_to_reassign_with_namespaced_models_and_counters
|
646
|
+
topic1 = Web::Topic.create("title" => "t1")
|
647
|
+
topic2 = Web::Topic.create("title" => "t2")
|
648
|
+
reply1 = Web::Reply.new("title" => "r1", "content" => "r1")
|
649
|
+
reply1.topic = topic1
|
650
|
+
|
651
|
+
assert reply1.save
|
652
|
+
assert_equal 1, Web::Topic.find(topic1.id).replies.size
|
653
|
+
assert_equal 0, Web::Topic.find(topic2.id).replies.size
|
654
|
+
|
655
|
+
reply1.topic = Web::Topic.find(topic2.id)
|
656
|
+
|
657
|
+
assert reply1.save
|
658
|
+
assert_equal 0, Web::Topic.find(topic1.id).replies.size
|
659
|
+
assert_equal 1, Web::Topic.find(topic2.id).replies.size
|
660
|
+
end
|
661
|
+
|
662
|
+
def test_belongs_to_counter_after_save
|
663
|
+
topic = Topic.create!(title: "monday night")
|
664
|
+
|
665
|
+
assert_queries(2) do
|
666
|
+
topic.replies.create!(title: "re: monday night", content: "football")
|
667
|
+
end
|
668
|
+
|
669
|
+
assert_equal 1, Topic.find(topic.id)[:replies_count]
|
670
|
+
|
671
|
+
topic.save!
|
672
|
+
assert_equal 1, Topic.find(topic.id)[:replies_count]
|
673
|
+
end
|
674
|
+
|
675
|
+
def test_belongs_to_counter_after_touch
|
676
|
+
topic = Topic.create!(title: "topic")
|
677
|
+
|
678
|
+
assert_equal 0, topic.replies_count
|
679
|
+
assert_equal 0, topic.after_touch_called
|
680
|
+
|
681
|
+
reply = Reply.create!(title: "blah!", content: "world around!", topic_with_primary_key: topic)
|
682
|
+
|
683
|
+
assert_equal 1, topic.replies_count
|
684
|
+
assert_equal 1, topic.after_touch_called
|
685
|
+
|
686
|
+
reply.destroy!
|
687
|
+
|
688
|
+
assert_equal 0, topic.replies_count
|
689
|
+
assert_equal 2, topic.after_touch_called
|
690
|
+
end
|
691
|
+
|
692
|
+
def test_belongs_to_touch_with_reassigning
|
693
|
+
debate = Topic.create!(title: "debate")
|
694
|
+
debate2 = Topic.create!(title: "debate2")
|
695
|
+
reply = Reply.create!(title: "blah!", content: "world around!", parent_title: "debate2")
|
696
|
+
|
697
|
+
time = 1.day.ago
|
698
|
+
|
699
|
+
debate.touch(time: time)
|
700
|
+
debate2.touch(time: time)
|
701
|
+
|
702
|
+
assert_queries(3) do
|
703
|
+
reply.parent_title = "debate"
|
704
|
+
reply.save!
|
705
|
+
end
|
706
|
+
|
707
|
+
assert_operator debate.reload.updated_at, :>, time
|
708
|
+
assert_operator debate2.reload.updated_at, :>, time
|
709
|
+
|
710
|
+
debate.touch(time: time)
|
711
|
+
debate2.touch(time: time)
|
712
|
+
|
713
|
+
assert_queries(3) do
|
714
|
+
reply.topic_with_primary_key = debate2
|
715
|
+
reply.save!
|
716
|
+
end
|
717
|
+
|
718
|
+
assert_operator debate.reload.updated_at, :>, time
|
719
|
+
assert_operator debate2.reload.updated_at, :>, time
|
720
|
+
end
|
721
|
+
|
722
|
+
def test_belongs_to_with_touch_option_on_touch
|
723
|
+
line_item = LineItem.create!
|
724
|
+
Invoice.create!(line_items: [line_item])
|
725
|
+
|
726
|
+
assert_queries(1) { line_item.touch }
|
727
|
+
end
|
728
|
+
|
729
|
+
def test_belongs_to_with_touch_on_multiple_records
|
730
|
+
line_item = LineItem.create!(amount: 1)
|
731
|
+
line_item2 = LineItem.create!(amount: 2)
|
732
|
+
Invoice.create!(line_items: [line_item, line_item2])
|
733
|
+
|
734
|
+
assert_queries(1) do
|
735
|
+
LineItem.transaction do
|
736
|
+
line_item.touch
|
737
|
+
line_item2.touch
|
738
|
+
end
|
739
|
+
end
|
740
|
+
|
741
|
+
assert_queries(2) do
|
742
|
+
line_item.touch
|
743
|
+
line_item2.touch
|
744
|
+
end
|
745
|
+
end
|
746
|
+
|
747
|
+
def test_belongs_to_with_touch_option_on_touch_without_updated_at_attributes
|
748
|
+
assert_not LineItem.column_names.include?("updated_at")
|
749
|
+
|
750
|
+
line_item = LineItem.create!
|
751
|
+
invoice = Invoice.create!(line_items: [line_item])
|
752
|
+
initial = invoice.updated_at
|
753
|
+
travel(1.second) do
|
754
|
+
line_item.touch
|
755
|
+
end
|
756
|
+
|
757
|
+
assert_not_equal initial, invoice.reload.updated_at
|
758
|
+
end
|
759
|
+
|
760
|
+
def test_belongs_to_with_touch_option_on_touch_and_removed_parent
|
761
|
+
line_item = LineItem.create!
|
762
|
+
Invoice.create!(line_items: [line_item])
|
763
|
+
|
764
|
+
line_item.invoice = nil
|
765
|
+
|
766
|
+
assert_queries(2) { line_item.touch }
|
767
|
+
end
|
768
|
+
|
769
|
+
def test_belongs_to_with_touch_option_on_update
|
770
|
+
line_item = LineItem.create!
|
771
|
+
Invoice.create!(line_items: [line_item])
|
772
|
+
|
773
|
+
assert_queries(2) { line_item.update amount: 10 }
|
774
|
+
end
|
775
|
+
|
776
|
+
def test_belongs_to_with_touch_option_on_empty_update
|
777
|
+
line_item = LineItem.create!
|
778
|
+
Invoice.create!(line_items: [line_item])
|
779
|
+
|
780
|
+
assert_no_queries { line_item.save }
|
781
|
+
end
|
782
|
+
|
783
|
+
def test_belongs_to_with_touch_option_on_destroy
|
784
|
+
line_item = LineItem.create!
|
785
|
+
Invoice.create!(line_items: [line_item])
|
786
|
+
|
787
|
+
assert_queries(2) { line_item.destroy }
|
788
|
+
end
|
789
|
+
|
790
|
+
def test_belongs_to_with_touch_option_on_destroy_with_destroyed_parent
|
791
|
+
line_item = LineItem.create!
|
792
|
+
invoice = Invoice.create!(line_items: [line_item])
|
793
|
+
invoice.destroy
|
794
|
+
|
795
|
+
assert_queries(1) { line_item.destroy }
|
796
|
+
end
|
797
|
+
|
798
|
+
def test_belongs_to_with_touch_option_on_touch_and_reassigned_parent
|
799
|
+
line_item = LineItem.create!
|
800
|
+
Invoice.create!(line_items: [line_item])
|
801
|
+
|
802
|
+
line_item.invoice = Invoice.create!
|
803
|
+
|
804
|
+
assert_queries(3) { line_item.touch }
|
805
|
+
end
|
806
|
+
|
807
|
+
def test_belongs_to_counter_after_update
|
808
|
+
topic = Topic.create!(title: "37s")
|
809
|
+
topic.replies.create!(title: "re: 37s", content: "rails")
|
810
|
+
assert_equal 1, Topic.find(topic.id)[:replies_count]
|
811
|
+
|
812
|
+
topic.update(title: "37signals")
|
813
|
+
assert_equal 1, Topic.find(topic.id)[:replies_count]
|
814
|
+
end
|
815
|
+
|
816
|
+
def test_belongs_to_counter_when_update_columns
|
817
|
+
topic = Topic.create!(title: "37s")
|
818
|
+
topic.replies.create!(title: "re: 37s", content: "rails")
|
819
|
+
assert_equal 1, Topic.find(topic.id)[:replies_count]
|
820
|
+
|
821
|
+
topic.update_columns(content: "rails is wonderful")
|
822
|
+
assert_equal 1, Topic.find(topic.id)[:replies_count]
|
823
|
+
end
|
824
|
+
|
825
|
+
def test_assignment_before_child_saved
|
826
|
+
final_cut = Client.new("name" => "Final Cut")
|
827
|
+
firm = Firm.find(1)
|
828
|
+
final_cut.firm = firm
|
829
|
+
assert_not_predicate final_cut, :persisted?
|
830
|
+
assert final_cut.save
|
831
|
+
assert_predicate final_cut, :persisted?
|
832
|
+
assert_predicate firm, :persisted?
|
833
|
+
assert_equal firm, final_cut.firm
|
834
|
+
final_cut.association(:firm).reload
|
835
|
+
assert_equal firm, final_cut.firm
|
836
|
+
end
|
837
|
+
|
838
|
+
def test_assignment_before_child_saved_with_primary_key
|
839
|
+
final_cut = Client.new("name" => "Final Cut")
|
840
|
+
firm = Firm.find(1)
|
841
|
+
final_cut.firm_with_primary_key = firm
|
842
|
+
assert_not_predicate final_cut, :persisted?
|
843
|
+
assert final_cut.save
|
844
|
+
assert_predicate final_cut, :persisted?
|
845
|
+
assert_predicate firm, :persisted?
|
846
|
+
assert_equal firm, final_cut.firm_with_primary_key
|
847
|
+
final_cut.association(:firm_with_primary_key).reload
|
848
|
+
assert_equal firm, final_cut.firm_with_primary_key
|
849
|
+
end
|
850
|
+
|
851
|
+
def test_new_record_with_foreign_key_but_no_object
|
852
|
+
client = Client.new("firm_id" => 1)
|
853
|
+
assert_equal Firm.first, client.firm_with_basic_id
|
854
|
+
end
|
855
|
+
|
856
|
+
def test_setting_foreign_key_after_nil_target_loaded
|
857
|
+
client = Client.new
|
858
|
+
client.firm_with_basic_id
|
859
|
+
client.firm_id = 1
|
860
|
+
|
861
|
+
assert_equal companies(:first_firm), client.firm_with_basic_id
|
862
|
+
end
|
863
|
+
|
864
|
+
def test_polymorphic_setting_foreign_key_after_nil_target_loaded
|
865
|
+
sponsor = Sponsor.new
|
866
|
+
sponsor.sponsorable
|
867
|
+
sponsor.sponsorable_id = 1
|
868
|
+
sponsor.sponsorable_type = "Member"
|
869
|
+
|
870
|
+
assert_equal members(:groucho), sponsor.sponsorable
|
871
|
+
end
|
872
|
+
|
873
|
+
def test_dont_find_target_when_foreign_key_is_null
|
874
|
+
tagging = taggings(:thinking_general)
|
875
|
+
assert_no_queries { tagging.super_tag }
|
876
|
+
end
|
877
|
+
|
878
|
+
def test_dont_find_target_when_saving_foreign_key_after_stale_association_loaded
|
879
|
+
client = Client.create!(name: "Test client", firm_with_basic_id: Firm.find(1))
|
880
|
+
client.firm_id = Firm.create!(name: "Test firm").id
|
881
|
+
assert_queries(1) { client.save! }
|
882
|
+
end
|
883
|
+
|
884
|
+
def test_field_name_same_as_foreign_key
|
885
|
+
computer = Computer.find(1)
|
886
|
+
assert_not_nil computer.developer, ":foreign key == attribute didn't lock up" # '
|
887
|
+
end
|
888
|
+
|
889
|
+
def test_counter_cache
|
890
|
+
topic = Topic.create title: "Zoom-zoom-zoom"
|
891
|
+
assert_equal 0, topic[:replies_count]
|
892
|
+
|
893
|
+
reply = Reply.create(title: "re: zoom", content: "speedy quick!")
|
894
|
+
reply.topic = topic
|
895
|
+
reply.save!
|
896
|
+
|
897
|
+
assert_equal 1, topic.reload[:replies_count]
|
898
|
+
assert_equal 1, topic.replies.size
|
899
|
+
|
900
|
+
topic[:replies_count] = 15
|
901
|
+
assert_equal 15, topic.replies.size
|
902
|
+
end
|
903
|
+
|
904
|
+
def test_counter_cache_double_destroy
|
905
|
+
topic = Topic.create title: "Zoom-zoom-zoom"
|
906
|
+
|
907
|
+
5.times do
|
908
|
+
topic.replies.create(title: "re: zoom", content: "speedy quick!")
|
909
|
+
end
|
910
|
+
|
911
|
+
assert_equal 5, topic.reload[:replies_count]
|
912
|
+
assert_equal 5, topic.replies.size
|
913
|
+
|
914
|
+
reply = topic.replies.first
|
915
|
+
|
916
|
+
reply.destroy
|
917
|
+
assert_equal 4, topic.reload[:replies_count]
|
918
|
+
|
919
|
+
reply.destroy
|
920
|
+
assert_equal 4, topic.reload[:replies_count]
|
921
|
+
assert_equal 4, topic.replies.size
|
922
|
+
end
|
923
|
+
|
924
|
+
def test_concurrent_counter_cache_double_destroy
|
925
|
+
topic = Topic.create title: "Zoom-zoom-zoom"
|
926
|
+
|
927
|
+
5.times do
|
928
|
+
topic.replies.create(title: "re: zoom", content: "speedy quick!")
|
929
|
+
end
|
930
|
+
|
931
|
+
assert_equal 5, topic.reload[:replies_count]
|
932
|
+
assert_equal 5, topic.replies.size
|
933
|
+
|
934
|
+
reply = topic.replies.first
|
935
|
+
reply_clone = Reply.find(reply.id)
|
936
|
+
|
937
|
+
reply.destroy
|
938
|
+
assert_equal 4, topic.reload[:replies_count]
|
939
|
+
|
940
|
+
reply_clone.destroy
|
941
|
+
assert_equal 4, topic.reload[:replies_count]
|
942
|
+
assert_equal 4, topic.replies.size
|
943
|
+
end
|
944
|
+
|
945
|
+
def test_custom_counter_cache
|
946
|
+
reply = Reply.create(title: "re: zoom", content: "speedy quick!")
|
947
|
+
assert_equal 0, reply[:replies_count]
|
948
|
+
|
949
|
+
silly = SillyReply.create(title: "gaga", content: "boo-boo")
|
950
|
+
silly.reply = reply
|
951
|
+
silly.save!
|
952
|
+
|
953
|
+
assert_equal 1, reply.reload[:replies_count]
|
954
|
+
assert_equal 1, reply.replies.size
|
955
|
+
|
956
|
+
reply[:replies_count] = 17
|
957
|
+
assert_equal 17, reply.replies.size
|
958
|
+
end
|
959
|
+
|
960
|
+
def test_replace_counter_cache
|
961
|
+
topic = Topic.create(title: "Zoom-zoom-zoom")
|
962
|
+
reply = Reply.create(title: "re: zoom", content: "speedy quick!")
|
963
|
+
|
964
|
+
reply.topic = topic
|
965
|
+
reply.save
|
966
|
+
topic.reload
|
967
|
+
|
968
|
+
assert_equal 1, topic.replies_count
|
969
|
+
end
|
970
|
+
|
971
|
+
def test_association_assignment_sticks
|
972
|
+
post = Post.first
|
973
|
+
|
974
|
+
author1, author2 = Author.all.merge!(limit: 2).to_a
|
975
|
+
assert_not_nil author1
|
976
|
+
assert_not_nil author2
|
977
|
+
|
978
|
+
# make sure the association is loaded
|
979
|
+
post.author
|
980
|
+
|
981
|
+
# set the association by id, directly
|
982
|
+
post.author_id = author2.id
|
983
|
+
|
984
|
+
# save and reload
|
985
|
+
post.save!
|
986
|
+
post.reload
|
987
|
+
|
988
|
+
# the author id of the post should be the id we set
|
989
|
+
assert_equal post.author_id, author2.id
|
990
|
+
end
|
991
|
+
|
992
|
+
def test_cant_save_readonly_association
|
993
|
+
assert_raise(ActiveRecord::ReadOnlyRecord) { companies(:first_client).readonly_firm.save! }
|
994
|
+
assert_predicate companies(:first_client).readonly_firm, :readonly?
|
995
|
+
end
|
996
|
+
|
997
|
+
def test_polymorphic_assignment_foreign_key_type_string
|
998
|
+
comment = Comment.first
|
999
|
+
comment.author = Author.first
|
1000
|
+
comment.resource = Member.first
|
1001
|
+
comment.save
|
1002
|
+
|
1003
|
+
assert_equal Comment.all.to_a,
|
1004
|
+
Comment.includes(:author).to_a
|
1005
|
+
|
1006
|
+
assert_equal Comment.all.to_a,
|
1007
|
+
Comment.includes(:resource).to_a
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
def test_polymorphic_assignment_foreign_type_field_updating
|
1011
|
+
# should update when assigning a saved record
|
1012
|
+
sponsor = Sponsor.new
|
1013
|
+
member = Member.create
|
1014
|
+
sponsor.sponsorable = member
|
1015
|
+
assert_equal "Member", sponsor.sponsorable_type
|
1016
|
+
|
1017
|
+
# should update when assigning a new record
|
1018
|
+
sponsor = Sponsor.new
|
1019
|
+
member = Member.new
|
1020
|
+
sponsor.sponsorable = member
|
1021
|
+
assert_equal "Member", sponsor.sponsorable_type
|
1022
|
+
end
|
1023
|
+
|
1024
|
+
def test_polymorphic_assignment_with_primary_key_foreign_type_field_updating
|
1025
|
+
# should update when assigning a saved record
|
1026
|
+
essay = Essay.new
|
1027
|
+
writer = Author.create(name: "David")
|
1028
|
+
essay.writer = writer
|
1029
|
+
assert_equal "Author", essay.writer_type
|
1030
|
+
|
1031
|
+
# should update when assigning a new record
|
1032
|
+
essay = Essay.new
|
1033
|
+
writer = Author.new
|
1034
|
+
essay.writer = writer
|
1035
|
+
assert_equal "Author", essay.writer_type
|
1036
|
+
end
|
1037
|
+
|
1038
|
+
def test_polymorphic_assignment_updates_foreign_id_field_for_new_and_saved_records
|
1039
|
+
sponsor = Sponsor.new
|
1040
|
+
saved_member = Member.create
|
1041
|
+
new_member = Member.new
|
1042
|
+
|
1043
|
+
sponsor.sponsorable = saved_member
|
1044
|
+
assert_equal saved_member.id, sponsor.sponsorable_id
|
1045
|
+
|
1046
|
+
sponsor.sponsorable = new_member
|
1047
|
+
assert_nil sponsor.sponsorable_id
|
1048
|
+
end
|
1049
|
+
|
1050
|
+
def test_assignment_updates_foreign_id_field_for_new_and_saved_records
|
1051
|
+
client = Client.new
|
1052
|
+
saved_firm = Firm.create name: "Saved"
|
1053
|
+
new_firm = Firm.new
|
1054
|
+
|
1055
|
+
client.firm = saved_firm
|
1056
|
+
assert_equal saved_firm.id, client.client_of
|
1057
|
+
|
1058
|
+
client.firm = new_firm
|
1059
|
+
assert_nil client.client_of
|
1060
|
+
end
|
1061
|
+
|
1062
|
+
def test_polymorphic_assignment_with_primary_key_updates_foreign_id_field_for_new_and_saved_records
|
1063
|
+
essay = Essay.new
|
1064
|
+
saved_writer = Author.create(name: "David")
|
1065
|
+
new_writer = Author.new
|
1066
|
+
|
1067
|
+
essay.writer = saved_writer
|
1068
|
+
assert_equal saved_writer.name, essay.writer_id
|
1069
|
+
|
1070
|
+
essay.writer = new_writer
|
1071
|
+
assert_nil essay.writer_id
|
1072
|
+
end
|
1073
|
+
|
1074
|
+
def test_polymorphic_assignment_with_nil
|
1075
|
+
essay = Essay.new
|
1076
|
+
assert_nil essay.writer_id
|
1077
|
+
assert_nil essay.writer_type
|
1078
|
+
|
1079
|
+
essay.writer_id = 1
|
1080
|
+
essay.writer_type = "Author"
|
1081
|
+
|
1082
|
+
essay.writer = nil
|
1083
|
+
assert_nil essay.writer_id
|
1084
|
+
assert_nil essay.writer_type
|
1085
|
+
end
|
1086
|
+
|
1087
|
+
def test_belongs_to_proxy_should_not_respond_to_private_methods
|
1088
|
+
assert_raise(NoMethodError) { companies(:first_firm).private_method }
|
1089
|
+
assert_raise(NoMethodError) { companies(:second_client).firm.private_method }
|
1090
|
+
end
|
1091
|
+
|
1092
|
+
def test_belongs_to_proxy_should_respond_to_private_methods_via_send
|
1093
|
+
companies(:first_firm).send(:private_method)
|
1094
|
+
companies(:second_client).firm.send(:private_method)
|
1095
|
+
end
|
1096
|
+
|
1097
|
+
def test_save_of_record_with_loaded_belongs_to
|
1098
|
+
@account = companies(:first_firm).account
|
1099
|
+
|
1100
|
+
assert_nothing_raised do
|
1101
|
+
Account.find(@account.id).save!
|
1102
|
+
Account.all.merge!(includes: :firm).find(@account.id).save!
|
1103
|
+
end
|
1104
|
+
|
1105
|
+
@account.firm.delete
|
1106
|
+
|
1107
|
+
assert_nothing_raised do
|
1108
|
+
Account.find(@account.id).save!
|
1109
|
+
Account.all.merge!(includes: :firm).find(@account.id).save!
|
1110
|
+
end
|
1111
|
+
end
|
1112
|
+
|
1113
|
+
def test_dependent_delete_and_destroy_with_belongs_to
|
1114
|
+
AuthorAddress.destroyed_author_address_ids.clear
|
1115
|
+
|
1116
|
+
author_address = author_addresses(:david_address)
|
1117
|
+
author_address_extra = author_addresses(:david_address_extra)
|
1118
|
+
assert_equal [], AuthorAddress.destroyed_author_address_ids
|
1119
|
+
|
1120
|
+
assert_difference "AuthorAddress.count", -2 do
|
1121
|
+
authors(:david).destroy
|
1122
|
+
end
|
1123
|
+
|
1124
|
+
assert_equal [], AuthorAddress.where(id: [author_address.id, author_address_extra.id])
|
1125
|
+
assert_equal [author_address.id], AuthorAddress.destroyed_author_address_ids
|
1126
|
+
end
|
1127
|
+
|
1128
|
+
def test_belongs_to_invalid_dependent_option_raises_exception
|
1129
|
+
error = assert_raise ArgumentError do
|
1130
|
+
Class.new(Author).belongs_to :special_author_address, dependent: :nullify
|
1131
|
+
end
|
1132
|
+
assert_equal error.message, "The :dependent option must be one of [:destroy, :delete, :destroy_async], but is :nullify"
|
1133
|
+
end
|
1134
|
+
|
1135
|
+
class EssayDestroy < ActiveRecord::Base
|
1136
|
+
self.table_name = "essays"
|
1137
|
+
belongs_to :book, dependent: :destroy, class_name: "DestroyableBook"
|
1138
|
+
end
|
1139
|
+
|
1140
|
+
class DestroyableBook < ActiveRecord::Base
|
1141
|
+
self.table_name = "books"
|
1142
|
+
belongs_to :author, class_name: "UndestroyableAuthor", dependent: :destroy
|
1143
|
+
end
|
1144
|
+
|
1145
|
+
class UndestroyableAuthor < ActiveRecord::Base
|
1146
|
+
self.table_name = "authors"
|
1147
|
+
has_one :book, class_name: "DestroyableBook", foreign_key: "author_id"
|
1148
|
+
before_destroy :dont
|
1149
|
+
|
1150
|
+
def dont
|
1151
|
+
throw(:abort)
|
1152
|
+
end
|
1153
|
+
end
|
1154
|
+
|
1155
|
+
def test_dependency_should_halt_parent_destruction
|
1156
|
+
author = UndestroyableAuthor.create!(name: "Test")
|
1157
|
+
book = DestroyableBook.create!(author: author)
|
1158
|
+
|
1159
|
+
assert_no_difference ["UndestroyableAuthor.count", "DestroyableBook.count"] do
|
1160
|
+
assert_not book.destroy
|
1161
|
+
end
|
1162
|
+
end
|
1163
|
+
|
1164
|
+
def test_dependency_should_halt_parent_destruction_with_cascaded_three_levels
|
1165
|
+
author = UndestroyableAuthor.create!(name: "Test")
|
1166
|
+
book = DestroyableBook.create!(author: author)
|
1167
|
+
essay = EssayDestroy.create!(book: book)
|
1168
|
+
|
1169
|
+
assert_no_difference ["UndestroyableAuthor.count", "DestroyableBook.count", "EssayDestroy.count"] do
|
1170
|
+
assert_not essay.destroy
|
1171
|
+
assert_not essay.destroyed?
|
1172
|
+
end
|
1173
|
+
end
|
1174
|
+
|
1175
|
+
def test_attributes_are_being_set_when_initialized_from_belongs_to_association_with_where_clause
|
1176
|
+
new_firm = accounts(:signals37).build_firm(name: "Apple")
|
1177
|
+
assert_equal new_firm.name, "Apple"
|
1178
|
+
end
|
1179
|
+
|
1180
|
+
def test_attributes_are_set_without_error_when_initialized_from_belongs_to_association_with_array_in_where_clause
|
1181
|
+
new_account = Account.where(credit_limit: [ 50, 60 ]).new
|
1182
|
+
assert_nil new_account.credit_limit
|
1183
|
+
end
|
1184
|
+
|
1185
|
+
def test_reassigning_the_parent_id_updates_the_object
|
1186
|
+
client = companies(:second_client)
|
1187
|
+
|
1188
|
+
client.firm
|
1189
|
+
client.firm_with_condition
|
1190
|
+
firm_proxy = client.send(:association_instance_get, :firm)
|
1191
|
+
firm_with_condition_proxy = client.send(:association_instance_get, :firm_with_condition)
|
1192
|
+
|
1193
|
+
assert_not_predicate firm_proxy, :stale_target?
|
1194
|
+
assert_not_predicate firm_with_condition_proxy, :stale_target?
|
1195
|
+
assert_equal companies(:first_firm), client.firm
|
1196
|
+
assert_equal companies(:first_firm), client.firm_with_condition
|
1197
|
+
|
1198
|
+
client.client_of = companies(:another_firm).id
|
1199
|
+
|
1200
|
+
assert_predicate firm_proxy, :stale_target?
|
1201
|
+
assert_predicate firm_with_condition_proxy, :stale_target?
|
1202
|
+
assert_equal companies(:another_firm), client.firm
|
1203
|
+
assert_equal companies(:another_firm), client.firm_with_condition
|
1204
|
+
end
|
1205
|
+
|
1206
|
+
def test_destroying_child_with_unloaded_parent_and_foreign_key_and_touch_is_possible_with_has_many_inversing
|
1207
|
+
with_has_many_inversing do
|
1208
|
+
book = Book.create!
|
1209
|
+
citation = book.citations.create!
|
1210
|
+
|
1211
|
+
assert_difference "Citation.count", -1 do
|
1212
|
+
Citation.find(citation.id).destroy
|
1213
|
+
end
|
1214
|
+
end
|
1215
|
+
end
|
1216
|
+
|
1217
|
+
def test_polymorphic_reassignment_of_associated_id_updates_the_object
|
1218
|
+
sponsor = sponsors(:moustache_club_sponsor_for_groucho)
|
1219
|
+
|
1220
|
+
sponsor.sponsorable
|
1221
|
+
proxy = sponsor.send(:association_instance_get, :sponsorable)
|
1222
|
+
|
1223
|
+
assert_not_predicate proxy, :stale_target?
|
1224
|
+
assert_equal members(:groucho), sponsor.sponsorable
|
1225
|
+
|
1226
|
+
sponsor.sponsorable_id = members(:some_other_guy).id
|
1227
|
+
|
1228
|
+
assert_predicate proxy, :stale_target?
|
1229
|
+
assert_equal members(:some_other_guy), sponsor.sponsorable
|
1230
|
+
end
|
1231
|
+
|
1232
|
+
def test_polymorphic_reassignment_of_associated_type_updates_the_object
|
1233
|
+
sponsor = sponsors(:moustache_club_sponsor_for_groucho)
|
1234
|
+
|
1235
|
+
sponsor.sponsorable
|
1236
|
+
proxy = sponsor.send(:association_instance_get, :sponsorable)
|
1237
|
+
|
1238
|
+
assert_not_predicate proxy, :stale_target?
|
1239
|
+
assert_equal members(:groucho), sponsor.sponsorable
|
1240
|
+
|
1241
|
+
sponsor.sponsorable_type = "Firm"
|
1242
|
+
|
1243
|
+
assert_predicate proxy, :stale_target?
|
1244
|
+
assert_equal companies(:first_firm), sponsor.sponsorable
|
1245
|
+
end
|
1246
|
+
|
1247
|
+
def test_reloading_association_with_key_change
|
1248
|
+
client = companies(:second_client)
|
1249
|
+
firm = client.association(:firm)
|
1250
|
+
|
1251
|
+
client.firm = companies(:another_firm)
|
1252
|
+
firm.reload
|
1253
|
+
assert_equal companies(:another_firm), firm.target
|
1254
|
+
|
1255
|
+
client.client_of = companies(:first_firm).id
|
1256
|
+
firm.reload
|
1257
|
+
assert_equal companies(:first_firm), firm.target
|
1258
|
+
end
|
1259
|
+
|
1260
|
+
def test_polymorphic_counter_cache
|
1261
|
+
tagging = taggings(:welcome_general)
|
1262
|
+
post = posts(:welcome)
|
1263
|
+
comment = comments(:greetings)
|
1264
|
+
|
1265
|
+
assert_equal post.id, comment.id
|
1266
|
+
|
1267
|
+
assert_difference "post.reload.tags_count", -1 do
|
1268
|
+
assert_difference "comment.reload.tags_count", +1 do
|
1269
|
+
tagging.taggable = comment
|
1270
|
+
tagging.save!
|
1271
|
+
end
|
1272
|
+
end
|
1273
|
+
|
1274
|
+
assert_difference "comment.reload.tags_count", -1 do
|
1275
|
+
assert_difference "post.reload.tags_count", +1 do
|
1276
|
+
tagging.taggable_type = post.class.polymorphic_name
|
1277
|
+
tagging.taggable_id = post.id
|
1278
|
+
tagging.save!
|
1279
|
+
end
|
1280
|
+
end
|
1281
|
+
end
|
1282
|
+
|
1283
|
+
def test_polymorphic_with_custom_foreign_type
|
1284
|
+
sponsor = sponsors(:moustache_club_sponsor_for_groucho)
|
1285
|
+
groucho = members(:groucho)
|
1286
|
+
other = members(:some_other_guy)
|
1287
|
+
|
1288
|
+
assert_equal groucho, sponsor.sponsorable
|
1289
|
+
assert_equal groucho, sponsor.thing
|
1290
|
+
|
1291
|
+
sponsor.thing = other
|
1292
|
+
|
1293
|
+
assert_equal other, sponsor.sponsorable
|
1294
|
+
assert_equal other, sponsor.thing
|
1295
|
+
|
1296
|
+
sponsor.sponsorable = groucho
|
1297
|
+
|
1298
|
+
assert_equal groucho, sponsor.sponsorable
|
1299
|
+
assert_equal groucho, sponsor.thing
|
1300
|
+
end
|
1301
|
+
|
1302
|
+
def test_build_with_conditions
|
1303
|
+
client = companies(:second_client)
|
1304
|
+
firm = client.build_bob_firm
|
1305
|
+
|
1306
|
+
assert_equal "Bob", firm.name
|
1307
|
+
end
|
1308
|
+
|
1309
|
+
def test_create_with_conditions
|
1310
|
+
client = companies(:second_client)
|
1311
|
+
firm = client.create_bob_firm
|
1312
|
+
|
1313
|
+
assert_equal "Bob", firm.name
|
1314
|
+
end
|
1315
|
+
|
1316
|
+
def test_create_bang_with_conditions
|
1317
|
+
client = companies(:second_client)
|
1318
|
+
firm = client.create_bob_firm!
|
1319
|
+
|
1320
|
+
assert_equal "Bob", firm.name
|
1321
|
+
end
|
1322
|
+
|
1323
|
+
def test_build_with_block
|
1324
|
+
client = Client.create(name: "Client Company")
|
1325
|
+
|
1326
|
+
firm = client.build_firm { |f| f.name = "Agency Company" }
|
1327
|
+
assert_equal "Agency Company", firm.name
|
1328
|
+
end
|
1329
|
+
|
1330
|
+
def test_create_with_block
|
1331
|
+
client = Client.create(name: "Client Company")
|
1332
|
+
|
1333
|
+
firm = client.create_firm { |f| f.name = "Agency Company" }
|
1334
|
+
assert_equal "Agency Company", firm.name
|
1335
|
+
end
|
1336
|
+
|
1337
|
+
def test_create_bang_with_block
|
1338
|
+
client = Client.create(name: "Client Company")
|
1339
|
+
|
1340
|
+
firm = client.create_firm! { |f| f.name = "Agency Company" }
|
1341
|
+
assert_equal "Agency Company", firm.name
|
1342
|
+
end
|
1343
|
+
|
1344
|
+
def test_should_set_foreign_key_on_create_association
|
1345
|
+
client = Client.create! name: "fuu"
|
1346
|
+
|
1347
|
+
firm = client.create_firm name: "baa"
|
1348
|
+
assert_equal firm.id, client.client_of
|
1349
|
+
end
|
1350
|
+
|
1351
|
+
def test_should_set_foreign_key_on_create_association!
|
1352
|
+
client = Client.create! name: "fuu"
|
1353
|
+
|
1354
|
+
firm = client.create_firm! name: "baa"
|
1355
|
+
assert_equal firm.id, client.client_of
|
1356
|
+
end
|
1357
|
+
|
1358
|
+
def test_self_referential_belongs_to_with_counter_cache_assigning_nil
|
1359
|
+
comment = Comment.create! post: posts(:thinking), body: "fuu"
|
1360
|
+
comment.parent = nil
|
1361
|
+
comment.save!
|
1362
|
+
|
1363
|
+
assert_nil comment.reload.parent
|
1364
|
+
assert_equal 0, comments(:greetings).reload.children_count
|
1365
|
+
end
|
1366
|
+
|
1367
|
+
def test_belongs_to_with_id_assigning
|
1368
|
+
post = posts(:welcome)
|
1369
|
+
comment = Comment.create! body: "foo", post: post
|
1370
|
+
parent = comments(:greetings)
|
1371
|
+
assert_equal 0, parent.reload.children_count
|
1372
|
+
comment.parent_id = parent.id
|
1373
|
+
|
1374
|
+
comment.save!
|
1375
|
+
assert_equal 1, parent.reload.children_count
|
1376
|
+
end
|
1377
|
+
|
1378
|
+
def test_belongs_to_with_out_of_range_value_assigning
|
1379
|
+
model = Class.new(Author) do
|
1380
|
+
def self.name; "Temp"; end
|
1381
|
+
validates :author_address, presence: true
|
1382
|
+
end
|
1383
|
+
|
1384
|
+
author = model.new
|
1385
|
+
author.author_address_id = 9223372036854775808 # out of range in the bigint
|
1386
|
+
|
1387
|
+
assert_nil author.author_address
|
1388
|
+
assert_not_predicate author, :valid?
|
1389
|
+
assert_equal [{ error: :blank }], author.errors.details[:author_address]
|
1390
|
+
end
|
1391
|
+
|
1392
|
+
def test_polymorphic_with_custom_primary_key
|
1393
|
+
toy = Toy.create!
|
1394
|
+
sponsor = Sponsor.create!(sponsorable: toy)
|
1395
|
+
|
1396
|
+
assert_equal toy, sponsor.reload.sponsorable
|
1397
|
+
end
|
1398
|
+
|
1399
|
+
class SponsorWithTouchInverse < Sponsor
|
1400
|
+
belongs_to :sponsorable, polymorphic: true, inverse_of: :sponsors, touch: true
|
1401
|
+
end
|
1402
|
+
|
1403
|
+
def test_destroying_polymorphic_child_with_unloaded_parent_and_touch_is_possible_with_has_many_inversing
|
1404
|
+
with_has_many_inversing do
|
1405
|
+
toy = Toy.create!
|
1406
|
+
sponsor = toy.sponsors.create!
|
1407
|
+
|
1408
|
+
assert_difference "Sponsor.count", -1 do
|
1409
|
+
SponsorWithTouchInverse.find(sponsor.id).destroy
|
1410
|
+
end
|
1411
|
+
end
|
1412
|
+
end
|
1413
|
+
|
1414
|
+
def test_polymorphic_with_false
|
1415
|
+
assert_nothing_raised do
|
1416
|
+
Class.new(ActiveRecord::Base) do
|
1417
|
+
def self.name; "Post"; end
|
1418
|
+
belongs_to :category, polymorphic: false
|
1419
|
+
end
|
1420
|
+
end
|
1421
|
+
end
|
1422
|
+
|
1423
|
+
test "stale tracking doesn't care about the type" do
|
1424
|
+
apple = Firm.create("name" => "Apple")
|
1425
|
+
citibank = Account.create("credit_limit" => 10)
|
1426
|
+
|
1427
|
+
citibank.firm_id = apple.id
|
1428
|
+
citibank.firm # load it
|
1429
|
+
|
1430
|
+
citibank.firm_id = apple.id.to_s
|
1431
|
+
|
1432
|
+
assert_not_predicate citibank.association(:firm), :stale_target?
|
1433
|
+
end
|
1434
|
+
|
1435
|
+
def test_reflect_the_most_recent_change
|
1436
|
+
author1, author2 = Author.limit(2)
|
1437
|
+
post = Post.new(title: "foo", body: "bar")
|
1438
|
+
|
1439
|
+
post.author = author1
|
1440
|
+
post.author_id = author2.id
|
1441
|
+
|
1442
|
+
assert post.save
|
1443
|
+
assert_equal post.author_id, author2.id
|
1444
|
+
end
|
1445
|
+
|
1446
|
+
test "dangerous association name raises ArgumentError" do
|
1447
|
+
[:errors, "errors", :save, "save"].each do |name|
|
1448
|
+
assert_raises(ArgumentError, "Association #{name} should not be allowed") do
|
1449
|
+
Class.new(ActiveRecord::Base) do
|
1450
|
+
belongs_to name
|
1451
|
+
end
|
1452
|
+
end
|
1453
|
+
end
|
1454
|
+
end
|
1455
|
+
|
1456
|
+
test "belongs_to works with model called Record" do
|
1457
|
+
record = Record.create!
|
1458
|
+
Column.create! record: record
|
1459
|
+
assert_equal 1, Column.count
|
1460
|
+
end
|
1461
|
+
|
1462
|
+
def test_multiple_counter_cache_with_after_create_update
|
1463
|
+
post = posts(:welcome)
|
1464
|
+
parent = comments(:greetings)
|
1465
|
+
|
1466
|
+
assert_difference "parent.reload.children_count", +1 do
|
1467
|
+
assert_difference "post.reload.comments_count", +1 do
|
1468
|
+
CommentWithAfterCreateUpdate.create(body: "foo", post: post, parent: parent)
|
1469
|
+
end
|
1470
|
+
end
|
1471
|
+
end
|
1472
|
+
|
1473
|
+
test "assigning an association doesn't result in duplicate objects" do
|
1474
|
+
post = Post.create!(title: "title", body: "body")
|
1475
|
+
post.comments = [post.comments.build(body: "body")]
|
1476
|
+
post.save!
|
1477
|
+
|
1478
|
+
assert_equal 1, post.comments.size
|
1479
|
+
assert_equal 1, Comment.where(post_id: post.id).count
|
1480
|
+
assert_equal post.id, Comment.last.post.id
|
1481
|
+
end
|
1482
|
+
end
|
1483
|
+
|
1484
|
+
class BelongsToWithForeignKeyTest < ActiveRecord::TestCase
|
1485
|
+
fixtures :authors, :author_addresses
|
1486
|
+
|
1487
|
+
def test_destroy_linked_models
|
1488
|
+
address = AuthorAddress.create!
|
1489
|
+
author = Author.create! name: "Author", author_address_id: address.id
|
1490
|
+
|
1491
|
+
author.destroy!
|
1492
|
+
end
|
1493
|
+
end
|