ibm_db 3.0.0-x86-mingw32 → 3.0.1-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES +4 -0
- data/MANIFEST +14 -14
- data/README +225 -225
- data/ext/Makefile.nt32 +181 -181
- data/ext/Makefile.nt32.191 +212 -212
- data/ext/OLD/extconf.rb +264 -0
- data/ext/{extconf_MacOS.rb → OLD/extconf_MacOS.rb} +269 -269
- data/ext/extconf.rb +291 -264
- data/ext/ibm_db.c +2 -2
- data/ext/ruby_ibm_db.h +241 -241
- data/ext/ruby_ibm_db_cli.h +500 -500
- data/init.rb +41 -41
- data/lib/IBM_DB.rb +27 -27
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +4 -4
- data/lib/active_record/connection_adapters/ibmdb_adapter.rb +1 -1
- data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -328
- data/lib/mswin32/ibm_db.rb +115 -115
- data/test/active_record/connection_adapters/fake_adapter.rb +46 -0
- data/test/assets/example.log +1 -0
- data/test/assets/flowers.jpg +0 -0
- data/test/assets/test.txt +1 -0
- data/test/cases/adapter_test.rb +261 -207
- data/test/cases/aggregations_test.rb +158 -0
- data/test/cases/ar_schema_test.rb +161 -0
- data/test/cases/associations/association_scope_test.rb +21 -0
- data/test/cases/associations/belongs_to_associations_test.rb +1029 -711
- data/test/cases/associations/callbacks_test.rb +192 -0
- data/test/cases/associations/cascaded_eager_loading_test.rb +188 -181
- data/test/cases/associations/deprecated_counter_cache_on_has_many_through_test.rb +26 -0
- data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +36 -0
- data/test/cases/associations/eager_load_nested_include_test.rb +128 -0
- data/test/cases/associations/eager_singularization_test.rb +148 -0
- data/test/cases/associations/eager_test.rb +1411 -0
- data/test/cases/associations/extension_test.rb +82 -0
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +932 -851
- data/test/cases/associations/has_many_associations_test.rb +2162 -0
- data/test/cases/associations/has_many_through_associations_test.rb +1204 -0
- data/test/cases/associations/has_one_associations_test.rb +610 -0
- data/test/cases/associations/has_one_through_associations_test.rb +380 -0
- data/test/cases/associations/inner_join_association_test.rb +139 -0
- data/test/cases/associations/inverse_associations_test.rb +693 -0
- data/test/cases/associations/join_model_test.rb +754 -743
- data/test/cases/associations/nested_through_associations_test.rb +579 -0
- data/test/cases/associations/required_test.rb +82 -0
- data/test/cases/associations_test.rb +380 -0
- data/test/cases/attribute_decorators_test.rb +125 -0
- data/test/cases/attribute_methods/read_test.rb +60 -0
- data/test/cases/attribute_methods/serialization_test.rb +29 -0
- data/test/cases/attribute_methods_test.rb +952 -822
- data/test/cases/attribute_set_test.rb +200 -0
- data/test/cases/attribute_test.rb +180 -0
- data/test/cases/attributes_test.rb +136 -0
- data/test/cases/autosave_association_test.rb +1595 -0
- data/test/cases/base_test.rb +1638 -2133
- data/test/cases/batches_test.rb +212 -0
- data/test/cases/binary_test.rb +52 -0
- data/test/cases/bind_parameter_test.rb +100 -0
- data/test/cases/calculations_test.rb +646 -482
- data/test/cases/callbacks_test.rb +543 -0
- data/test/cases/clone_test.rb +40 -0
- data/test/cases/coders/yaml_column_test.rb +63 -0
- data/test/cases/column_alias_test.rb +17 -0
- data/test/cases/column_definition_test.rb +123 -0
- data/test/cases/connection_adapters/adapter_leasing_test.rb +54 -0
- data/test/cases/connection_adapters/connection_handler_test.rb +53 -0
- data/test/cases/connection_adapters/connection_specification_test.rb +12 -0
- data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +293 -0
- data/test/cases/connection_adapters/mysql_type_lookup_test.rb +65 -0
- data/test/cases/connection_adapters/quoting_test.rb +13 -0
- data/test/cases/connection_adapters/schema_cache_test.rb +56 -0
- data/test/cases/connection_adapters/type_lookup_test.rb +110 -0
- data/test/cases/connection_management_test.rb +122 -0
- data/test/cases/connection_pool_test.rb +346 -0
- data/test/cases/connection_specification/resolver_test.rb +116 -0
- data/test/cases/core_test.rb +112 -0
- data/test/cases/counter_cache_test.rb +209 -0
- data/test/cases/custom_locking_test.rb +17 -0
- data/test/cases/database_statements_test.rb +19 -0
- data/test/cases/date_time_test.rb +61 -0
- data/test/cases/defaults_test.rb +223 -0
- data/test/cases/dirty_test.rb +775 -0
- data/test/cases/disconnected_test.rb +28 -0
- data/test/cases/dup_test.rb +157 -0
- data/test/cases/enum_test.rb +290 -0
- data/test/cases/explain_subscriber_test.rb +64 -0
- data/test/cases/explain_test.rb +76 -0
- data/test/cases/finder_respond_to_test.rb +60 -0
- data/test/cases/finder_test.rb +1166 -0
- data/test/cases/fixture_set/file_test.rb +138 -0
- data/test/cases/fixtures_test.rb +897 -0
- data/test/cases/forbidden_attributes_protection_test.rb +99 -0
- data/test/cases/habtm_destroy_order_test.rb +61 -0
- data/test/cases/helper.rb +210 -0
- data/test/cases/hot_compatibility_test.rb +54 -0
- data/test/cases/i18n_test.rb +45 -0
- data/test/cases/inheritance_test.rb +375 -0
- data/test/cases/integration_test.rb +139 -0
- data/test/cases/invalid_connection_test.rb +22 -0
- data/test/cases/invalid_date_test.rb +32 -0
- data/test/cases/invertible_migration_test.rb +295 -0
- data/test/cases/json_serialization_test.rb +302 -0
- data/test/cases/locking_test.rb +477 -0
- data/test/cases/log_subscriber_test.rb +136 -0
- data/test/cases/migration/change_schema_test - Copy.rb +448 -0
- data/test/cases/migration/change_schema_test.rb +472 -0
- data/test/cases/migration/change_table_test.rb +224 -0
- data/test/cases/migration/column_attributes_test.rb +192 -0
- data/test/cases/migration/column_positioning_test.rb +56 -0
- data/test/cases/migration/columns_test.rb +304 -0
- data/test/cases/migration/command_recorder_test.rb +305 -0
- data/test/cases/migration/create_join_table_test.rb +148 -0
- data/test/cases/migration/foreign_key_test - Changed.rb +325 -0
- data/test/cases/migration/foreign_key_test.rb +360 -0
- data/test/cases/migration/helper.rb +39 -0
- data/test/cases/migration/index_test.rb +216 -0
- data/test/cases/migration/logger_test.rb +36 -0
- data/test/cases/migration/pending_migrations_test.rb +53 -0
- data/test/cases/migration/references_foreign_key_test.rb +214 -0
- data/test/cases/migration/references_index_test.rb +101 -0
- data/test/cases/migration/references_statements_test.rb +116 -0
- data/test/cases/migration/rename_table_test.rb +93 -0
- data/test/cases/migration/table_and_index_test.rb +24 -0
- data/test/cases/migration_test.rb +959 -2408
- data/test/cases/migrator_test.rb +388 -0
- data/test/cases/mixin_test.rb +70 -0
- data/test/cases/modules_test.rb +173 -0
- data/test/cases/multiparameter_attributes_test.rb +350 -0
- data/test/cases/multiple_db_test.rb +115 -0
- data/test/cases/nested_attributes_test.rb +1057 -0
- data/test/cases/nested_attributes_with_callbacks_test.rb +144 -0
- data/test/cases/persistence_test.rb +909 -642
- data/test/cases/pooled_connections_test.rb +81 -0
- data/test/cases/primary_keys_test.rb +237 -0
- data/test/cases/query_cache_test.rb +326 -257
- data/test/cases/quoting_test.rb +156 -0
- data/test/cases/readonly_test.rb +118 -0
- data/test/cases/reaper_test.rb +85 -0
- data/test/cases/reflection_test.rb +454 -0
- data/test/cases/relation/delegation_test.rb +68 -0
- data/test/cases/relation/merging_test.rb +161 -0
- data/test/cases/relation/mutation_test.rb +165 -0
- data/test/cases/relation/predicate_builder_test.rb +14 -0
- data/test/cases/relation/where_chain_test.rb +181 -0
- data/test/cases/relation/where_test.rb +300 -0
- data/test/cases/relation/where_test2.rb +36 -0
- data/test/cases/relation_test.rb +297 -0
- data/test/cases/relations_test.rb +1815 -1182
- data/test/cases/reload_models_test.rb +22 -0
- data/test/cases/result_test.rb +80 -0
- data/test/cases/sanitize_test.rb +83 -0
- data/test/cases/schema_dumper_test.rb +463 -256
- data/test/cases/scoping/default_scoping_test.rb +454 -0
- data/test/cases/scoping/named_scoping_test.rb +524 -0
- data/test/cases/scoping/relation_scoping_test.rb +357 -0
- data/test/cases/serialization_test.rb +104 -0
- data/test/cases/serialized_attribute_test.rb +277 -0
- data/test/cases/statement_cache_test.rb +98 -0
- data/test/cases/store_test.rb +194 -0
- data/test/cases/tasks/database_tasks_test.rb +396 -0
- data/test/cases/tasks/mysql_rake_test.rb +311 -0
- data/test/cases/tasks/postgresql_rake_test.rb +245 -0
- data/test/cases/tasks/sqlite_rake_test.rb +193 -0
- data/test/cases/test_case.rb +123 -0
- data/test/cases/timestamp_test.rb +468 -0
- data/test/cases/transaction_callbacks_test.rb +452 -300
- data/test/cases/transaction_isolation_test.rb +106 -0
- data/test/cases/transactions_test.rb +817 -0
- data/test/cases/type/decimal_test.rb +51 -0
- data/test/cases/type/integer_test.rb +121 -0
- data/test/cases/type/string_test.rb +36 -0
- data/test/cases/type/type_map_test.rb +177 -0
- data/test/cases/type/unsigned_integer_test.rb +18 -0
- data/test/cases/types_test.rb +141 -0
- data/test/cases/unconnected_test.rb +33 -0
- data/test/cases/validations/association_validation_test.rb +86 -0
- data/test/cases/validations/i18n_generate_message_validation_test.rb +84 -0
- data/test/cases/validations/i18n_validation_test.rb +90 -0
- data/test/cases/validations/length_validation_test.rb +47 -0
- data/test/cases/validations/presence_validation_test.rb +68 -0
- data/test/cases/validations/uniqueness_validation_test.rb +434 -299
- data/test/cases/validations_repair_helper.rb +23 -0
- data/test/cases/validations_test.rb +165 -0
- data/test/cases/view_test.rb +113 -0
- data/test/cases/xml_serialization_test.rb +457 -408
- data/test/cases/yaml_serialization_test.rb +86 -0
- data/test/config.rb +5 -0
- data/test/config.yml +154 -154
- data/test/connections/native_ibm_db/connection.rb +43 -43
- 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/people.yml +0 -0
- data/test/fixtures/all/tasks.yml +0 -0
- data/test/fixtures/author_addresses.yml +18 -0
- data/test/fixtures/author_favorites.yml +4 -0
- data/test/fixtures/authors.yml +23 -0
- data/test/fixtures/binaries.yml +133 -0
- data/test/fixtures/books.yml +11 -0
- data/test/fixtures/bulbs.yml +5 -0
- data/test/fixtures/cars.yml +9 -0
- data/test/fixtures/categories.yml +19 -0
- data/test/fixtures/categories/special_categories.yml +9 -0
- data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -0
- data/test/fixtures/categories_ordered.yml +7 -0
- data/test/fixtures/categories_posts.yml +31 -0
- data/test/fixtures/categorizations.yml +23 -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 +65 -0
- data/test/fixtures/companies.yml +67 -0
- data/test/fixtures/computers.yml +10 -0
- data/test/fixtures/courses.yml +8 -0
- data/test/fixtures/customers.yml +26 -0
- data/test/fixtures/dashboards.yml +6 -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 +6 -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/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/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 +34 -0
- data/test/fixtures/men.yml +5 -0
- data/test/fixtures/minimalistics.yml +2 -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/csv/accounts.csv +1 -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/organizations.yml +5 -0
- data/test/fixtures/other_topics.yml +42 -0
- data/test/fixtures/owners.yml +9 -0
- data/test/fixtures/parrots.yml +27 -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 +12 -0
- data/test/fixtures/posts.yml +80 -0
- data/test/fixtures/price_estimates.yml +7 -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 +11 -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 +12 -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/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/zines.yml +5 -0
- data/test/ibm_db_test.rb +24 -24
- data/test/migrations/10_urban/9_add_expressions.rb +11 -0
- data/test/migrations/decimal/1_give_me_big_numbers.rb +15 -0
- data/test/migrations/magic/1_currencies_have_symbols.rb +12 -0
- data/test/migrations/missing/1000_people_have_middle_names.rb +9 -0
- data/test/migrations/missing/1_people_have_last_names.rb +9 -0
- data/test/migrations/missing/3_we_need_reminders.rb +12 -0
- data/test/migrations/missing/4_innocent_jointable.rb +12 -0
- data/test/migrations/rename/1_we_need_things.rb +11 -0
- data/test/migrations/rename/2_rename_things.rb +9 -0
- data/test/migrations/to_copy/1_people_have_hobbies.rb +9 -0
- data/test/migrations/to_copy/2_people_have_descriptions.rb +9 -0
- data/test/migrations/to_copy2/1_create_articles.rb +7 -0
- data/test/migrations/to_copy2/2_create_comments.rb +7 -0
- data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +9 -0
- data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +9 -0
- data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +9 -0
- data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +7 -0
- data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +7 -0
- data/test/migrations/valid/1_valid_people_have_last_names.rb +9 -0
- data/test/migrations/valid/2_we_need_reminders.rb +12 -0
- data/test/migrations/valid/3_innocent_jointable.rb +12 -0
- data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +9 -0
- data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +12 -0
- data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +12 -0
- data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +9 -0
- data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +12 -0
- data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +12 -0
- data/test/migrations/version_check/20131219224947_migration_version_check.rb +8 -0
- data/test/models/admin.rb +5 -0
- data/test/models/admin/account.rb +3 -0
- data/test/models/admin/randomly_named_c1.rb +3 -0
- data/test/models/admin/user.rb +40 -0
- data/test/models/aircraft.rb +4 -0
- data/test/models/arunit2_model.rb +3 -0
- data/test/models/author.rb +212 -0
- data/test/models/auto_id.rb +4 -0
- data/test/models/autoloadable/extra_firm.rb +2 -0
- data/test/models/binary.rb +2 -0
- data/test/models/bird.rb +12 -0
- data/test/models/book.rb +18 -0
- data/test/models/boolean.rb +2 -0
- data/test/models/bulb.rb +51 -0
- data/test/models/cake_designer.rb +3 -0
- data/test/models/car.rb +26 -0
- data/test/models/carrier.rb +2 -0
- data/test/models/categorization.rb +19 -0
- data/test/models/category.rb +35 -0
- data/test/models/chef.rb +3 -0
- data/test/models/citation.rb +3 -0
- data/test/models/club.rb +23 -0
- data/test/models/college.rb +10 -0
- data/test/models/column.rb +3 -0
- data/test/models/column_name.rb +3 -0
- data/test/models/comment.rb +64 -0
- data/test/models/company.rb +225 -0
- data/test/models/company_in_module.rb +98 -0
- data/test/models/computer.rb +3 -0
- data/test/models/contact.rb +41 -0
- data/test/models/contract.rb +20 -0
- data/test/models/country.rb +7 -0
- data/test/models/course.rb +6 -0
- data/test/models/customer.rb +77 -0
- data/test/models/customer_carrier.rb +14 -0
- data/test/models/dashboard.rb +3 -0
- data/test/models/default.rb +2 -0
- data/test/models/department.rb +4 -0
- data/test/models/developer.rb +252 -0
- data/test/models/dog.rb +5 -0
- data/test/models/dog_lover.rb +5 -0
- data/test/models/doubloon.rb +12 -0
- data/test/models/drink_designer.rb +3 -0
- data/test/models/edge.rb +5 -0
- data/test/models/electron.rb +5 -0
- data/test/models/engine.rb +4 -0
- data/test/models/entrant.rb +3 -0
- data/test/models/essay.rb +5 -0
- data/test/models/event.rb +3 -0
- data/test/models/eye.rb +37 -0
- data/test/models/face.rb +9 -0
- data/test/models/friendship.rb +6 -0
- data/test/models/guid.rb +2 -0
- data/test/models/hotel.rb +6 -0
- data/test/models/image.rb +3 -0
- data/test/models/interest.rb +5 -0
- data/test/models/invoice.rb +4 -0
- data/test/models/item.rb +7 -0
- data/test/models/job.rb +7 -0
- data/test/models/joke.rb +7 -0
- data/test/models/keyboard.rb +3 -0
- data/test/models/legacy_thing.rb +3 -0
- data/test/models/lesson.rb +11 -0
- data/test/models/line_item.rb +3 -0
- data/test/models/liquid.rb +4 -0
- data/test/models/man.rb +11 -0
- data/test/models/matey.rb +4 -0
- data/test/models/member.rb +41 -0
- data/test/models/member_detail.rb +7 -0
- data/test/models/member_type.rb +3 -0
- data/test/models/membership.rb +35 -0
- data/test/models/minimalistic.rb +2 -0
- data/test/models/minivan.rb +9 -0
- data/test/models/mixed_case_monkey.rb +3 -0
- data/test/models/molecule.rb +6 -0
- data/test/models/movie.rb +5 -0
- data/test/models/order.rb +4 -0
- data/test/models/organization.rb +14 -0
- data/test/models/owner.rb +34 -0
- data/test/models/parrot.rb +29 -0
- data/test/models/person.rb +143 -0
- data/test/models/personal_legacy_thing.rb +4 -0
- data/test/models/pet.rb +15 -0
- data/test/models/pirate.rb +92 -0
- data/test/models/possession.rb +3 -0
- data/test/models/post.rb +264 -0
- data/test/models/price_estimate.rb +4 -0
- data/test/models/professor.rb +5 -0
- data/test/models/project.rb +29 -0
- data/test/models/publisher.rb +2 -0
- data/test/models/publisher/article.rb +4 -0
- data/test/models/publisher/magazine.rb +3 -0
- data/test/models/randomly_named_c1.rb +3 -0
- data/test/models/rating.rb +4 -0
- data/test/models/reader.rb +23 -0
- data/test/models/record.rb +2 -0
- data/test/models/reference.rb +22 -0
- data/test/models/reply.rb +61 -0
- data/test/models/ship.rb +33 -0
- data/test/models/ship_part.rb +8 -0
- data/test/models/shop.rb +17 -0
- data/test/models/shop_account.rb +6 -0
- data/test/models/speedometer.rb +6 -0
- data/test/models/sponsor.rb +7 -0
- data/test/models/string_key_object.rb +3 -0
- data/test/models/student.rb +4 -0
- data/test/models/subject.rb +16 -0
- data/test/models/subscriber.rb +8 -0
- data/test/models/subscription.rb +4 -0
- data/test/models/tag.rb +7 -0
- data/test/models/tagging.rb +13 -0
- data/test/models/task.rb +5 -0
- data/test/models/topic.rb +124 -0
- data/test/models/toy.rb +6 -0
- data/test/models/traffic_light.rb +4 -0
- data/test/models/treasure.rb +14 -0
- data/test/models/treaty.rb +7 -0
- data/test/models/tyre.rb +11 -0
- data/test/models/uuid_child.rb +3 -0
- data/test/models/uuid_parent.rb +3 -0
- data/test/models/vegetables.rb +24 -0
- data/test/models/vehicle.rb +7 -0
- data/test/models/vertex.rb +9 -0
- data/test/models/warehouse_thing.rb +5 -5
- data/test/models/wheel.rb +3 -0
- data/test/models/without_table.rb +3 -0
- data/test/models/zine.rb +3 -0
- data/test/schema/mysql2_specific_schema.rb +58 -0
- data/test/schema/mysql_specific_schema.rb +70 -0
- data/test/schema/oracle_specific_schema.rb +43 -0
- data/test/schema/postgresql_specific_schema.rb +202 -0
- data/test/schema/schema.rb +938 -751
- data/test/schema/sqlite_specific_schema.rb +22 -0
- data/test/support/config.rb +43 -0
- data/test/support/connection.rb +22 -0
- data/test/support/connection_helper.rb +14 -0
- data/test/support/ddl_helper.rb +8 -0
- data/test/support/schema_dumping_helper.rb +20 -0
- metadata +444 -18
@@ -0,0 +1,26 @@
|
|
1
|
+
require "cases/helper"
|
2
|
+
|
3
|
+
class DeprecatedCounterCacheOnHasManyThroughTest < ActiveRecord::TestCase
|
4
|
+
class Post < ActiveRecord::Base
|
5
|
+
has_many :taggings, as: :taggable
|
6
|
+
has_many :tags, through: :taggings
|
7
|
+
end
|
8
|
+
|
9
|
+
class Tagging < ActiveRecord::Base
|
10
|
+
belongs_to :taggable, polymorphic: true
|
11
|
+
belongs_to :tag
|
12
|
+
end
|
13
|
+
|
14
|
+
class Tag < ActiveRecord::Base
|
15
|
+
end
|
16
|
+
|
17
|
+
test "counter caches are updated in the database if the belongs_to association doesn't specify a counter cache" do
|
18
|
+
post = Post.create!(title: 'Hello', body: 'World!')
|
19
|
+
assert_deprecated { post.tags << Tag.create!(name: 'whatever') }
|
20
|
+
|
21
|
+
assert_equal 1, post.tags.size
|
22
|
+
assert_equal 1, post.tags_count
|
23
|
+
assert_equal 1, post.reload.tags.size
|
24
|
+
assert_equal 1, post.reload.tags_count
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'cases/helper'
|
2
|
+
require 'models/post'
|
3
|
+
require 'models/tagging'
|
4
|
+
|
5
|
+
module Namespaced
|
6
|
+
class Post < ActiveRecord::Base
|
7
|
+
self.table_name = 'posts'
|
8
|
+
has_one :tagging, :as => :taggable, :class_name => 'Tagging'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class EagerLoadIncludeFullStiClassNamesTest < ActiveRecord::TestCase
|
13
|
+
|
14
|
+
def setup
|
15
|
+
generate_test_objects
|
16
|
+
end
|
17
|
+
|
18
|
+
def generate_test_objects
|
19
|
+
post = Namespaced::Post.create( :title => 'Great stuff', :body => 'This is not', :author_id => 1 )
|
20
|
+
Tagging.create( :taggable => post )
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_class_names
|
24
|
+
old = ActiveRecord::Base.store_full_sti_class
|
25
|
+
|
26
|
+
ActiveRecord::Base.store_full_sti_class = false
|
27
|
+
post = Namespaced::Post.includes(:tagging).find_by_title('Great stuff')
|
28
|
+
assert_nil post.tagging
|
29
|
+
|
30
|
+
ActiveRecord::Base.store_full_sti_class = true
|
31
|
+
post = Namespaced::Post.includes(:tagging).find_by_title('Great stuff')
|
32
|
+
assert_instance_of Tagging, post.tagging
|
33
|
+
ensure
|
34
|
+
ActiveRecord::Base.store_full_sti_class = old
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'cases/helper'
|
2
|
+
require 'models/post'
|
3
|
+
require 'models/tag'
|
4
|
+
require 'models/author'
|
5
|
+
require 'models/comment'
|
6
|
+
require 'models/category'
|
7
|
+
require 'models/categorization'
|
8
|
+
require 'models/tagging'
|
9
|
+
|
10
|
+
module Remembered
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
|
13
|
+
included do
|
14
|
+
after_create :remember
|
15
|
+
protected
|
16
|
+
def remember; self.class.remembered << self; end
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
def remembered; @@remembered ||= []; end
|
21
|
+
def sample; @@remembered.sample; end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class ShapeExpression < ActiveRecord::Base
|
26
|
+
belongs_to :shape, :polymorphic => true
|
27
|
+
belongs_to :paint, :polymorphic => true
|
28
|
+
end
|
29
|
+
|
30
|
+
class Circle < ActiveRecord::Base
|
31
|
+
has_many :shape_expressions, :as => :shape
|
32
|
+
include Remembered
|
33
|
+
end
|
34
|
+
class Square < ActiveRecord::Base
|
35
|
+
has_many :shape_expressions, :as => :shape
|
36
|
+
include Remembered
|
37
|
+
end
|
38
|
+
class Triangle < ActiveRecord::Base
|
39
|
+
has_many :shape_expressions, :as => :shape
|
40
|
+
include Remembered
|
41
|
+
end
|
42
|
+
class PaintColor < ActiveRecord::Base
|
43
|
+
has_many :shape_expressions, :as => :paint
|
44
|
+
belongs_to :non_poly, :foreign_key => "non_poly_one_id", :class_name => "NonPolyOne"
|
45
|
+
include Remembered
|
46
|
+
end
|
47
|
+
class PaintTexture < ActiveRecord::Base
|
48
|
+
has_many :shape_expressions, :as => :paint
|
49
|
+
belongs_to :non_poly, :foreign_key => "non_poly_two_id", :class_name => "NonPolyTwo"
|
50
|
+
include Remembered
|
51
|
+
end
|
52
|
+
class NonPolyOne < ActiveRecord::Base
|
53
|
+
has_many :paint_colors
|
54
|
+
include Remembered
|
55
|
+
end
|
56
|
+
class NonPolyTwo < ActiveRecord::Base
|
57
|
+
has_many :paint_textures
|
58
|
+
include Remembered
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
class EagerLoadPolyAssocsTest < ActiveRecord::TestCase
|
64
|
+
NUM_SIMPLE_OBJS = 50
|
65
|
+
NUM_SHAPE_EXPRESSIONS = 100
|
66
|
+
|
67
|
+
def setup
|
68
|
+
generate_test_object_graphs
|
69
|
+
end
|
70
|
+
|
71
|
+
teardown do
|
72
|
+
[Circle, Square, Triangle, PaintColor, PaintTexture,
|
73
|
+
ShapeExpression, NonPolyOne, NonPolyTwo].each do |c|
|
74
|
+
c.delete_all
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def generate_test_object_graphs
|
79
|
+
1.upto(NUM_SIMPLE_OBJS) do
|
80
|
+
[Circle, Square, Triangle, NonPolyOne, NonPolyTwo].map(&:create!)
|
81
|
+
end
|
82
|
+
1.upto(NUM_SIMPLE_OBJS) do
|
83
|
+
PaintColor.create!(:non_poly_one_id => NonPolyOne.sample.id)
|
84
|
+
PaintTexture.create!(:non_poly_two_id => NonPolyTwo.sample.id)
|
85
|
+
end
|
86
|
+
1.upto(NUM_SHAPE_EXPRESSIONS) do
|
87
|
+
shape_type = [Circle, Square, Triangle].sample
|
88
|
+
paint_type = [PaintColor, PaintTexture].sample
|
89
|
+
ShapeExpression.create!(:shape_type => shape_type.to_s, :shape_id => shape_type.sample.id,
|
90
|
+
:paint_type => paint_type.to_s, :paint_id => paint_type.sample.id)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_include_query
|
95
|
+
res = ShapeExpression.all.merge!(:includes => [ :shape, { :paint => :non_poly } ]).to_a
|
96
|
+
assert_equal NUM_SHAPE_EXPRESSIONS, res.size
|
97
|
+
assert_queries(0) do
|
98
|
+
res.each do |se|
|
99
|
+
assert_not_nil se.paint.non_poly, "this is the association that was loading incorrectly before the change"
|
100
|
+
assert_not_nil se.shape, "just making sure other associations still work"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
class EagerLoadNestedIncludeWithMissingDataTest < ActiveRecord::TestCase
|
107
|
+
def setup
|
108
|
+
@davey_mcdave = Author.create(:name => 'Davey McDave')
|
109
|
+
@first_post = @davey_mcdave.posts.create(:title => 'Davey Speaks', :body => 'Expressive wordage')
|
110
|
+
@first_comment = @first_post.comments.create(:body => 'Inflamatory doublespeak')
|
111
|
+
@first_categorization = @davey_mcdave.categorizations.create(:category => Category.first, :post => @first_post)
|
112
|
+
end
|
113
|
+
|
114
|
+
teardown do
|
115
|
+
@davey_mcdave.destroy
|
116
|
+
@first_post.destroy
|
117
|
+
@first_comment.destroy
|
118
|
+
@first_categorization.destroy
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_missing_data_in_a_nested_include_should_not_cause_errors_when_constructing_objects
|
122
|
+
assert_nothing_raised do
|
123
|
+
# @davey_mcdave doesn't have any author_favorites
|
124
|
+
includes = {:posts => :comments, :categorizations => :category, :author_favorites => :favorite_author }
|
125
|
+
Author.all.merge!(:includes => includes, :where => {:authors => {:name => @davey_mcdave.name}}, :order => 'categories.name').to_a
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require "cases/helper"
|
2
|
+
|
3
|
+
|
4
|
+
if ActiveRecord::Base.connection.supports_migrations?
|
5
|
+
class EagerSingularizationTest < ActiveRecord::TestCase
|
6
|
+
class Virus < ActiveRecord::Base
|
7
|
+
belongs_to :octopus
|
8
|
+
end
|
9
|
+
|
10
|
+
class Octopus < ActiveRecord::Base
|
11
|
+
has_one :virus
|
12
|
+
end
|
13
|
+
|
14
|
+
class Pass < ActiveRecord::Base
|
15
|
+
belongs_to :bus
|
16
|
+
end
|
17
|
+
|
18
|
+
class Bus < ActiveRecord::Base
|
19
|
+
has_many :passes
|
20
|
+
end
|
21
|
+
|
22
|
+
class Mess < ActiveRecord::Base
|
23
|
+
has_and_belongs_to_many :crises
|
24
|
+
end
|
25
|
+
|
26
|
+
class Crisis < ActiveRecord::Base
|
27
|
+
has_and_belongs_to_many :messes
|
28
|
+
has_many :analyses, :dependent => :destroy
|
29
|
+
has_many :successes, :through => :analyses
|
30
|
+
has_many :dresses, :dependent => :destroy
|
31
|
+
has_many :compresses, :through => :dresses
|
32
|
+
end
|
33
|
+
|
34
|
+
class Analysis < ActiveRecord::Base
|
35
|
+
belongs_to :crisis
|
36
|
+
belongs_to :success
|
37
|
+
end
|
38
|
+
|
39
|
+
class Success < ActiveRecord::Base
|
40
|
+
has_many :analyses, :dependent => :destroy
|
41
|
+
has_many :crises, :through => :analyses
|
42
|
+
end
|
43
|
+
|
44
|
+
class Dress < ActiveRecord::Base
|
45
|
+
belongs_to :crisis
|
46
|
+
has_many :compresses
|
47
|
+
end
|
48
|
+
|
49
|
+
class Compress < ActiveRecord::Base
|
50
|
+
belongs_to :dress
|
51
|
+
end
|
52
|
+
|
53
|
+
def setup
|
54
|
+
connection.create_table :viri do |t|
|
55
|
+
t.column :octopus_id, :integer
|
56
|
+
t.column :species, :string
|
57
|
+
end
|
58
|
+
connection.create_table :octopi do |t|
|
59
|
+
t.column :species, :string
|
60
|
+
end
|
61
|
+
connection.create_table :passes do |t|
|
62
|
+
t.column :bus_id, :integer
|
63
|
+
t.column :rides, :integer
|
64
|
+
end
|
65
|
+
connection.create_table :buses do |t|
|
66
|
+
t.column :name, :string
|
67
|
+
end
|
68
|
+
connection.create_table :crises_messes, :id => false do |t|
|
69
|
+
t.column :crisis_id, :integer
|
70
|
+
t.column :mess_id, :integer
|
71
|
+
end
|
72
|
+
connection.create_table :messes do |t|
|
73
|
+
t.column :name, :string
|
74
|
+
end
|
75
|
+
connection.create_table :crises do |t|
|
76
|
+
t.column :name, :string
|
77
|
+
end
|
78
|
+
connection.create_table :successes do |t|
|
79
|
+
t.column :name, :string
|
80
|
+
end
|
81
|
+
connection.create_table :analyses do |t|
|
82
|
+
t.column :crisis_id, :integer
|
83
|
+
t.column :success_id, :integer
|
84
|
+
end
|
85
|
+
connection.create_table :dresses do |t|
|
86
|
+
t.column :crisis_id, :integer
|
87
|
+
end
|
88
|
+
connection.create_table :compresses do |t|
|
89
|
+
t.column :dress_id, :integer
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
teardown do
|
94
|
+
connection.drop_table :viri
|
95
|
+
connection.drop_table :octopi
|
96
|
+
connection.drop_table :passes
|
97
|
+
connection.drop_table :buses
|
98
|
+
connection.drop_table :crises_messes
|
99
|
+
connection.drop_table :messes
|
100
|
+
connection.drop_table :crises
|
101
|
+
connection.drop_table :successes
|
102
|
+
connection.drop_table :analyses
|
103
|
+
connection.drop_table :dresses
|
104
|
+
connection.drop_table :compresses
|
105
|
+
end
|
106
|
+
|
107
|
+
def connection
|
108
|
+
ActiveRecord::Base.connection
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_eager_no_extra_singularization_belongs_to
|
112
|
+
assert_nothing_raised do
|
113
|
+
Virus.all.merge!(:includes => :octopus).to_a
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_eager_no_extra_singularization_has_one
|
118
|
+
assert_nothing_raised do
|
119
|
+
Octopus.all.merge!(:includes => :virus).to_a
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_eager_no_extra_singularization_has_many
|
124
|
+
assert_nothing_raised do
|
125
|
+
Bus.all.merge!(:includes => :passes).to_a
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_eager_no_extra_singularization_has_and_belongs_to_many
|
130
|
+
assert_nothing_raised do
|
131
|
+
Crisis.all.merge!(:includes => :messes).to_a
|
132
|
+
Mess.all.merge!(:includes => :crises).to_a
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_eager_no_extra_singularization_has_many_through_belongs_to
|
137
|
+
assert_nothing_raised do
|
138
|
+
Crisis.all.merge!(:includes => :successes).to_a
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_eager_no_extra_singularization_has_many_through_has_many
|
143
|
+
assert_nothing_raised do
|
144
|
+
Crisis.all.merge!(:includes => :compresses).to_a
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,1411 @@
|
|
1
|
+
require "cases/helper"
|
2
|
+
require 'models/post'
|
3
|
+
require 'models/tagging'
|
4
|
+
require 'models/tag'
|
5
|
+
require 'models/comment'
|
6
|
+
require 'models/author'
|
7
|
+
require 'models/essay'
|
8
|
+
require 'models/category'
|
9
|
+
require 'models/company'
|
10
|
+
require 'models/person'
|
11
|
+
require 'models/reader'
|
12
|
+
require 'models/owner'
|
13
|
+
require 'models/pet'
|
14
|
+
require 'models/reference'
|
15
|
+
require 'models/job'
|
16
|
+
require 'models/subscriber'
|
17
|
+
require 'models/subscription'
|
18
|
+
require 'models/book'
|
19
|
+
require 'models/developer'
|
20
|
+
require 'models/computer'
|
21
|
+
require 'models/project'
|
22
|
+
require 'models/member'
|
23
|
+
require 'models/membership'
|
24
|
+
require 'models/club'
|
25
|
+
require 'models/categorization'
|
26
|
+
require 'models/sponsor'
|
27
|
+
|
28
|
+
class EagerAssociationTest < ActiveRecord::TestCase
|
29
|
+
fixtures :posts, :comments, :authors, :essays, :author_addresses, :categories, :categories_posts,
|
30
|
+
:companies, :accounts, :tags, :taggings, :people, :readers, :categorizations,
|
31
|
+
:owners, :pets, :author_favorites, :jobs, :references, :subscribers, :subscriptions, :books,
|
32
|
+
:developers, :projects, :developers_projects, :members, :memberships, :clubs, :sponsors
|
33
|
+
|
34
|
+
def test_eager_with_has_one_through_join_model_with_conditions_on_the_through
|
35
|
+
member = Member.all.merge!(:includes => :favourite_club).find(members(:some_other_guy).id)
|
36
|
+
assert_nil member.favourite_club
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_loading_with_one_association
|
40
|
+
posts = Post.all.merge!(:includes => :comments).to_a
|
41
|
+
post = posts.find { |p| p.id == 1 }
|
42
|
+
assert_equal 2, post.comments.size
|
43
|
+
assert post.comments.include?(comments(:greetings))
|
44
|
+
|
45
|
+
post = Post.all.merge!(:includes => :comments, :where => "posts.title = 'Welcome to the weblog'").first
|
46
|
+
assert_equal 2, post.comments.size
|
47
|
+
assert post.comments.include?(comments(:greetings))
|
48
|
+
|
49
|
+
posts = Post.all.merge!(:includes => :last_comment).to_a
|
50
|
+
post = posts.find { |p| p.id == 1 }
|
51
|
+
assert_equal Post.find(1).last_comment, post.last_comment
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_loading_with_one_association_with_non_preload
|
55
|
+
posts = Post.all.merge!(:includes => :last_comment, :order => 'comments.id DESC').to_a
|
56
|
+
post = posts.find { |p| p.id == 1 }
|
57
|
+
assert_equal Post.find(1).last_comment, post.last_comment
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_loading_conditions_with_or
|
61
|
+
posts = authors(:david).posts.references(:comments).merge(
|
62
|
+
:includes => :comments,
|
63
|
+
:where => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE} = 'SpecialComment'"
|
64
|
+
).to_a
|
65
|
+
assert_nil posts.detect { |p| p.author_id != authors(:david).id },
|
66
|
+
"expected to find only david's posts"
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_with_ordering
|
70
|
+
list = Post.all.merge!(:includes => :comments, :order => "posts.id DESC").to_a
|
71
|
+
[:other_by_mary, :other_by_bob, :misc_by_mary, :misc_by_bob, :eager_other,
|
72
|
+
:sti_habtm, :sti_post_and_comments, :sti_comments, :authorless, :thinking, :welcome
|
73
|
+
].each_with_index do |post, index|
|
74
|
+
assert_equal posts(post), list[index]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_has_many_through_with_order
|
79
|
+
authors = Author.includes(:favorite_authors).to_a
|
80
|
+
assert authors.count > 0
|
81
|
+
assert_no_queries { authors.map(&:favorite_authors) }
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_eager_loaded_has_one_association_with_references_does_not_run_additional_queries
|
85
|
+
Post.update_all(author_id: nil)
|
86
|
+
authors = Author.includes(:post).references(:post).to_a
|
87
|
+
assert authors.count > 0
|
88
|
+
assert_no_queries { authors.map(&:post) }
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_with_two_tables_in_from_without_getting_double_quoted
|
92
|
+
posts = Post.select("posts.*").from("authors, posts").eager_load(:comments).where("posts.author_id = authors.id").order("posts.id").to_a
|
93
|
+
assert_equal 2, posts.first.comments.size
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_loading_with_multiple_associations
|
97
|
+
posts = Post.all.merge!(:includes => [ :comments, :author, :categories ], :order => "posts.id").to_a
|
98
|
+
assert_equal 2, posts.first.comments.size
|
99
|
+
assert_equal 2, posts.first.categories.size
|
100
|
+
assert posts.first.comments.include?(comments(:greetings))
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_duplicate_middle_objects
|
104
|
+
comments = Comment.all.merge!(:where => 'post_id = 1', :includes => [:post => :author]).to_a
|
105
|
+
assert_no_queries do
|
106
|
+
comments.each {|comment| comment.post.author.name}
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_preloading_has_many_in_multiple_queries_with_more_ids_than_database_can_handle
|
111
|
+
Comment.connection.expects(:in_clause_length).at_least_once.returns(5)
|
112
|
+
posts = Post.all.merge!(:includes=>:comments).to_a
|
113
|
+
assert_equal 11, posts.size
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_preloading_has_many_in_one_queries_when_database_has_no_limit_on_ids_it_can_handle
|
117
|
+
Comment.connection.expects(:in_clause_length).at_least_once.returns(nil)
|
118
|
+
posts = Post.all.merge!(:includes=>:comments).to_a
|
119
|
+
assert_equal 11, posts.size
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_preloading_habtm_in_multiple_queries_with_more_ids_than_database_can_handle
|
123
|
+
Comment.connection.expects(:in_clause_length).at_least_once.returns(5)
|
124
|
+
posts = Post.all.merge!(:includes=>:categories).to_a
|
125
|
+
assert_equal 11, posts.size
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_preloading_habtm_in_one_queries_when_database_has_no_limit_on_ids_it_can_handle
|
129
|
+
Comment.connection.expects(:in_clause_length).at_least_once.returns(nil)
|
130
|
+
posts = Post.all.merge!(:includes=>:categories).to_a
|
131
|
+
assert_equal 11, posts.size
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_load_associated_records_in_one_query_when_adapter_has_no_limit
|
135
|
+
Comment.connection.expects(:in_clause_length).at_least_once.returns(nil)
|
136
|
+
|
137
|
+
post = posts(:welcome)
|
138
|
+
assert_queries(2) do
|
139
|
+
Post.includes(:comments).where(:id => post.id).to_a
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_load_associated_records_in_several_queries_when_many_ids_passed
|
144
|
+
Comment.connection.expects(:in_clause_length).at_least_once.returns(1)
|
145
|
+
|
146
|
+
post1, post2 = posts(:welcome), posts(:thinking)
|
147
|
+
assert_queries(3) do
|
148
|
+
Post.includes(:comments).where(:id => [post1.id, post2.id]).to_a
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_load_associated_records_in_one_query_when_a_few_ids_passed
|
153
|
+
Comment.connection.expects(:in_clause_length).at_least_once.returns(3)
|
154
|
+
|
155
|
+
post = posts(:welcome)
|
156
|
+
assert_queries(2) do
|
157
|
+
Post.includes(:comments).where(:id => post.id).to_a
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_including_duplicate_objects_from_belongs_to
|
162
|
+
popular_post = Post.create!(:title => 'foo', :body => "I like cars!")
|
163
|
+
comment = popular_post.comments.create!(:body => "lol")
|
164
|
+
popular_post.readers.create!(:person => people(:michael))
|
165
|
+
popular_post.readers.create!(:person => people(:david))
|
166
|
+
|
167
|
+
readers = Reader.all.merge!(:where => ["post_id = ?", popular_post.id],
|
168
|
+
:includes => {:post => :comments}).to_a
|
169
|
+
readers.each do |reader|
|
170
|
+
assert_equal [comment], reader.post.comments
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def test_including_duplicate_objects_from_has_many
|
175
|
+
car_post = Post.create!(:title => 'foo', :body => "I like cars!")
|
176
|
+
car_post.categories << categories(:general)
|
177
|
+
car_post.categories << categories(:technology)
|
178
|
+
|
179
|
+
comment = car_post.comments.create!(:body => "hmm")
|
180
|
+
categories = Category.all.merge!(:where => { 'posts.id' => car_post.id },
|
181
|
+
:includes => {:posts => :comments}).to_a
|
182
|
+
categories.each do |category|
|
183
|
+
assert_equal [comment], category.posts[0].comments
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_associations_loaded_for_all_records
|
188
|
+
post = Post.create!(:title => 'foo', :body => "I like cars!")
|
189
|
+
SpecialComment.create!(:body => 'Come on!', :post => post)
|
190
|
+
first_category = Category.create! :name => 'First!', :posts => [post]
|
191
|
+
second_category = Category.create! :name => 'Second!', :posts => [post]
|
192
|
+
|
193
|
+
categories = Category.where(:id => [first_category.id, second_category.id]).includes(:posts => :special_comments)
|
194
|
+
assert_equal categories.map { |category| category.posts.first.special_comments.loaded? }, [true, true]
|
195
|
+
end
|
196
|
+
|
197
|
+
def test_finding_with_includes_on_has_many_association_with_same_include_includes_only_once
|
198
|
+
author_id = authors(:david).id
|
199
|
+
author = assert_queries(3) { Author.all.merge!(:includes => {:posts_with_comments => :comments}).find(author_id) } # find the author, then find the posts, then find the comments
|
200
|
+
author.posts_with_comments.each do |post_with_comments|
|
201
|
+
assert_equal post_with_comments.comments.length, post_with_comments.comments.count
|
202
|
+
assert_nil post_with_comments.comments.to_a.uniq!
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def test_finding_with_includes_on_has_one_association_with_same_include_includes_only_once
|
207
|
+
author = authors(:david)
|
208
|
+
post = author.post_about_thinking_with_last_comment
|
209
|
+
last_comment = post.last_comment
|
210
|
+
author = assert_queries(3) { Author.all.merge!(:includes => {:post_about_thinking_with_last_comment => :last_comment}).find(author.id)} # find the author, then find the posts, then find the comments
|
211
|
+
assert_no_queries do
|
212
|
+
assert_equal post, author.post_about_thinking_with_last_comment
|
213
|
+
assert_equal last_comment, author.post_about_thinking_with_last_comment.last_comment
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def test_finding_with_includes_on_belongs_to_association_with_same_include_includes_only_once
|
218
|
+
post = posts(:welcome)
|
219
|
+
author = post.author
|
220
|
+
author_address = author.author_address
|
221
|
+
post = assert_queries(3) { Post.all.merge!(:includes => {:author_with_address => :author_address}).find(post.id) } # find the post, then find the author, then find the address
|
222
|
+
assert_no_queries do
|
223
|
+
assert_equal author, post.author_with_address
|
224
|
+
assert_equal author_address, post.author_with_address.author_address
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
def test_finding_with_includes_on_null_belongs_to_association_with_same_include_includes_only_once
|
229
|
+
post = posts(:welcome)
|
230
|
+
post.update!(author: nil)
|
231
|
+
post = assert_queries(1) { Post.all.merge!(includes: {author_with_address: :author_address}).find(post.id) }
|
232
|
+
# find the post, then find the author which is null so no query for the author or address
|
233
|
+
assert_no_queries do
|
234
|
+
assert_equal nil, post.author_with_address
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
def test_finding_with_includes_on_null_belongs_to_polymorphic_association
|
239
|
+
sponsor = sponsors(:moustache_club_sponsor_for_groucho)
|
240
|
+
sponsor.update!(sponsorable: nil)
|
241
|
+
sponsor = assert_queries(1) { Sponsor.all.merge!(:includes => :sponsorable).find(sponsor.id) }
|
242
|
+
assert_no_queries do
|
243
|
+
assert_equal nil, sponsor.sponsorable
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
def test_finding_with_includes_on_empty_polymorphic_type_column
|
248
|
+
sponsor = sponsors(:moustache_club_sponsor_for_groucho)
|
249
|
+
sponsor.update!(sponsorable_type: '', sponsorable_id: nil) # sponsorable_type column might be declared NOT NULL
|
250
|
+
sponsor = assert_queries(1) do
|
251
|
+
assert_nothing_raised { Sponsor.all.merge!(:includes => :sponsorable).find(sponsor.id) }
|
252
|
+
end
|
253
|
+
assert_no_queries do
|
254
|
+
assert_equal nil, sponsor.sponsorable
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
def test_loading_from_an_association
|
259
|
+
posts = authors(:david).posts.merge(:includes => :comments, :order => "posts.id").to_a
|
260
|
+
assert_equal 2, posts.first.comments.size
|
261
|
+
end
|
262
|
+
|
263
|
+
def test_loading_from_an_association_that_has_a_hash_of_conditions
|
264
|
+
assert_nothing_raised do
|
265
|
+
Author.all.merge!(:includes => :hello_posts_with_hash_conditions).to_a
|
266
|
+
end
|
267
|
+
assert !Author.all.merge!(:includes => :hello_posts_with_hash_conditions).find(authors(:david).id).hello_posts.empty?
|
268
|
+
end
|
269
|
+
|
270
|
+
def test_loading_with_no_associations
|
271
|
+
assert_nil Post.all.merge!(:includes => :author).find(posts(:authorless).id).author
|
272
|
+
end
|
273
|
+
|
274
|
+
# Regression test for 21c75e5
|
275
|
+
def test_nested_loading_does_not_raise_exception_when_association_does_not_exist
|
276
|
+
assert_nothing_raised do
|
277
|
+
Post.all.merge!(:includes => {:author => :author_addresss}).find(posts(:authorless).id)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
def test_three_level_nested_preloading_does_not_raise_exception_when_association_does_not_exist
|
282
|
+
post_id = Comment.where(author_id: nil).where.not(post_id: nil).first.post_id
|
283
|
+
|
284
|
+
assert_nothing_raised do
|
285
|
+
Post.preload(:comments => [{:author => :essays}]).find(post_id)
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
def test_nested_loading_through_has_one_association
|
290
|
+
aa = AuthorAddress.all.merge!(:includes => {:author => :posts}).find(author_addresses(:david_address).id)
|
291
|
+
assert_equal aa.author.posts.count, aa.author.posts.length
|
292
|
+
end
|
293
|
+
|
294
|
+
def test_nested_loading_through_has_one_association_with_order
|
295
|
+
aa = AuthorAddress.all.merge!(:includes => {:author => :posts}, :order => 'author_addresses.id').find(author_addresses(:david_address).id)
|
296
|
+
assert_equal aa.author.posts.count, aa.author.posts.length
|
297
|
+
end
|
298
|
+
|
299
|
+
def test_nested_loading_through_has_one_association_with_order_on_association
|
300
|
+
aa = AuthorAddress.all.merge!(:includes => {:author => :posts}, :order => 'authors.id').find(author_addresses(:david_address).id)
|
301
|
+
assert_equal aa.author.posts.count, aa.author.posts.length
|
302
|
+
end
|
303
|
+
|
304
|
+
def test_nested_loading_through_has_one_association_with_order_on_nested_association
|
305
|
+
aa = AuthorAddress.all.merge!(:includes => {:author => :posts}, :order => 'posts.id').find(author_addresses(:david_address).id)
|
306
|
+
assert_equal aa.author.posts.count, aa.author.posts.length
|
307
|
+
end
|
308
|
+
|
309
|
+
def test_nested_loading_through_has_one_association_with_conditions
|
310
|
+
aa = AuthorAddress.references(:author_addresses).merge(
|
311
|
+
:includes => {:author => :posts},
|
312
|
+
:where => "author_addresses.id > 0"
|
313
|
+
).find author_addresses(:david_address).id
|
314
|
+
assert_equal aa.author.posts.count, aa.author.posts.length
|
315
|
+
end
|
316
|
+
|
317
|
+
def test_nested_loading_through_has_one_association_with_conditions_on_association
|
318
|
+
aa = AuthorAddress.references(:authors).merge(
|
319
|
+
:includes => {:author => :posts},
|
320
|
+
:where => "authors.id > 0"
|
321
|
+
).find author_addresses(:david_address).id
|
322
|
+
assert_equal aa.author.posts.count, aa.author.posts.length
|
323
|
+
end
|
324
|
+
|
325
|
+
def test_nested_loading_through_has_one_association_with_conditions_on_nested_association
|
326
|
+
aa = AuthorAddress.references(:posts).merge(
|
327
|
+
:includes => {:author => :posts},
|
328
|
+
:where => "posts.id > 0"
|
329
|
+
).find author_addresses(:david_address).id
|
330
|
+
assert_equal aa.author.posts.count, aa.author.posts.length
|
331
|
+
end
|
332
|
+
|
333
|
+
def test_eager_association_loading_with_belongs_to_and_foreign_keys
|
334
|
+
pets = Pet.all.merge!(:includes => :owner).to_a
|
335
|
+
assert_equal 4, pets.length
|
336
|
+
end
|
337
|
+
|
338
|
+
def test_eager_association_loading_with_belongs_to
|
339
|
+
comments = Comment.all.merge!(:includes => :post).to_a
|
340
|
+
assert_equal 11, comments.length
|
341
|
+
titles = comments.map { |c| c.post.title }
|
342
|
+
assert titles.include?(posts(:welcome).title)
|
343
|
+
assert titles.include?(posts(:sti_post_and_comments).title)
|
344
|
+
end
|
345
|
+
|
346
|
+
def test_eager_association_loading_with_belongs_to_and_limit
|
347
|
+
comments = Comment.all.merge!(:includes => :post, :limit => 5, :order => 'comments.id').to_a
|
348
|
+
assert_equal 5, comments.length
|
349
|
+
assert_equal [1,2,3,5,6], comments.collect { |c| c.id }
|
350
|
+
end
|
351
|
+
|
352
|
+
def test_eager_association_loading_with_belongs_to_and_limit_and_conditions
|
353
|
+
comments = Comment.all.merge!(:includes => :post, :where => 'post_id = 4', :limit => 3, :order => 'comments.id').to_a
|
354
|
+
assert_equal 3, comments.length
|
355
|
+
assert_equal [5,6,7], comments.collect { |c| c.id }
|
356
|
+
end
|
357
|
+
|
358
|
+
def test_eager_association_loading_with_belongs_to_and_limit_and_offset
|
359
|
+
comments = Comment.all.merge!(:includes => :post, :limit => 3, :offset => 2, :order => 'comments.id').to_a
|
360
|
+
assert_equal 3, comments.length
|
361
|
+
assert_equal [3,5,6], comments.collect { |c| c.id }
|
362
|
+
end
|
363
|
+
|
364
|
+
def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_conditions
|
365
|
+
comments = Comment.all.merge!(:includes => :post, :where => 'post_id = 4', :limit => 3, :offset => 1, :order => 'comments.id').to_a
|
366
|
+
assert_equal 3, comments.length
|
367
|
+
assert_equal [6,7,8], comments.collect { |c| c.id }
|
368
|
+
end
|
369
|
+
|
370
|
+
def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_conditions_array
|
371
|
+
comments = Comment.all.merge!(:includes => :post, :where => ['post_id = ?',4], :limit => 3, :offset => 1, :order => 'comments.id').to_a
|
372
|
+
assert_equal 3, comments.length
|
373
|
+
assert_equal [6,7,8], comments.collect { |c| c.id }
|
374
|
+
end
|
375
|
+
|
376
|
+
def test_eager_association_loading_with_belongs_to_and_conditions_string_with_unquoted_table_name
|
377
|
+
assert_nothing_raised do
|
378
|
+
Comment.includes(:post).references(:posts).where('posts.id = ?', 4)
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
def test_eager_association_loading_with_belongs_to_and_conditions_hash
|
383
|
+
comments = []
|
384
|
+
assert_nothing_raised do
|
385
|
+
comments = Comment.all.merge!(:includes => :post, :where => {:posts => {:id => 4}}, :limit => 3, :order => 'comments.id').to_a
|
386
|
+
end
|
387
|
+
assert_equal 3, comments.length
|
388
|
+
assert_equal [5,6,7], comments.collect { |c| c.id }
|
389
|
+
assert_no_queries do
|
390
|
+
comments.first.post
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
def test_eager_association_loading_with_belongs_to_and_conditions_string_with_quoted_table_name
|
395
|
+
quoted_posts_id= Comment.connection.quote_table_name('posts') + '.' + Comment.connection.quote_column_name('id')
|
396
|
+
assert_nothing_raised do
|
397
|
+
Comment.includes(:post).references(:posts).where("#{quoted_posts_id} = ?", 4)
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
def test_eager_association_loading_with_belongs_to_and_order_string_with_unquoted_table_name
|
402
|
+
assert_nothing_raised do
|
403
|
+
Comment.all.merge!(:includes => :post, :order => 'posts.id').to_a
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
def test_eager_association_loading_with_belongs_to_and_order_string_with_quoted_table_name
|
408
|
+
quoted_posts_id= Comment.connection.quote_table_name('posts') + '.' + Comment.connection.quote_column_name('id')
|
409
|
+
assert_nothing_raised do
|
410
|
+
Comment.includes(:post).references(:posts).order(quoted_posts_id)
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
414
|
+
def test_eager_association_loading_with_belongs_to_and_limit_and_multiple_associations
|
415
|
+
posts = Post.all.merge!(:includes => [:author, :very_special_comment], :limit => 1, :order => 'posts.id').to_a
|
416
|
+
assert_equal 1, posts.length
|
417
|
+
assert_equal [1], posts.collect { |p| p.id }
|
418
|
+
end
|
419
|
+
|
420
|
+
def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_multiple_associations
|
421
|
+
posts = Post.all.merge!(:includes => [:author, :very_special_comment], :limit => 1, :offset => 1, :order => 'posts.id').to_a
|
422
|
+
assert_equal 1, posts.length
|
423
|
+
assert_equal [2], posts.collect { |p| p.id }
|
424
|
+
end
|
425
|
+
|
426
|
+
def test_eager_association_loading_with_belongs_to_inferred_foreign_key_from_association_name
|
427
|
+
author_favorite = AuthorFavorite.all.merge!(:includes => :favorite_author).first
|
428
|
+
assert_equal authors(:mary), assert_no_queries { author_favorite.favorite_author }
|
429
|
+
end
|
430
|
+
|
431
|
+
def test_eager_load_belongs_to_quotes_table_and_column_names
|
432
|
+
job = Job.includes(:ideal_reference).find jobs(:unicyclist).id
|
433
|
+
references(:michael_unicyclist)
|
434
|
+
assert_no_queries{ assert_equal references(:michael_unicyclist), job.ideal_reference}
|
435
|
+
end
|
436
|
+
|
437
|
+
def test_eager_load_has_one_quotes_table_and_column_names
|
438
|
+
michael = Person.all.merge!(:includes => :favourite_reference).find(people(:michael).id)
|
439
|
+
references(:michael_unicyclist)
|
440
|
+
assert_no_queries{ assert_equal references(:michael_unicyclist), michael.favourite_reference}
|
441
|
+
end
|
442
|
+
|
443
|
+
def test_eager_load_has_many_quotes_table_and_column_names
|
444
|
+
michael = Person.all.merge!(:includes => :references).find(people(:michael).id)
|
445
|
+
references(:michael_magician,:michael_unicyclist)
|
446
|
+
assert_no_queries{ assert_equal references(:michael_magician,:michael_unicyclist), michael.references.sort_by(&:id) }
|
447
|
+
end
|
448
|
+
|
449
|
+
def test_eager_load_has_many_through_quotes_table_and_column_names
|
450
|
+
michael = Person.all.merge!(:includes => :jobs).find(people(:michael).id)
|
451
|
+
jobs(:magician, :unicyclist)
|
452
|
+
assert_no_queries{ assert_equal jobs(:unicyclist, :magician), michael.jobs.sort_by(&:id) }
|
453
|
+
end
|
454
|
+
|
455
|
+
def test_eager_load_has_many_with_string_keys
|
456
|
+
subscriptions = subscriptions(:webster_awdr, :webster_rfr)
|
457
|
+
subscriber =Subscriber.all.merge!(:includes => :subscriptions).find(subscribers(:second).id)
|
458
|
+
assert_equal subscriptions, subscriber.subscriptions.sort_by(&:id)
|
459
|
+
end
|
460
|
+
|
461
|
+
def test_string_id_column_joins
|
462
|
+
s = Subscriber.create! do |c|
|
463
|
+
c.id = "PL"
|
464
|
+
end
|
465
|
+
|
466
|
+
b = Book.create!
|
467
|
+
|
468
|
+
Subscription.create!(:subscriber_id => "PL", :book_id => b.id)
|
469
|
+
s.reload
|
470
|
+
s.book_ids = s.book_ids
|
471
|
+
end
|
472
|
+
|
473
|
+
def test_eager_load_has_many_through_with_string_keys
|
474
|
+
books = books(:awdr, :rfr)
|
475
|
+
subscriber = Subscriber.all.merge!(:includes => :books).find(subscribers(:second).id)
|
476
|
+
assert_equal books, subscriber.books.sort_by(&:id)
|
477
|
+
end
|
478
|
+
|
479
|
+
def test_eager_load_belongs_to_with_string_keys
|
480
|
+
subscriber = subscribers(:second)
|
481
|
+
subscription = Subscription.all.merge!(:includes => :subscriber).find(subscriptions(:webster_awdr).id)
|
482
|
+
assert_equal subscriber, subscription.subscriber
|
483
|
+
end
|
484
|
+
|
485
|
+
def test_eager_association_loading_with_explicit_join
|
486
|
+
posts = Post.all.merge!(:includes => :comments, :joins => "INNER JOIN authors ON posts.author_id = authors.id AND authors.name = 'Mary'", :limit => 1, :order => 'author_id').to_a
|
487
|
+
assert_equal 1, posts.length
|
488
|
+
end
|
489
|
+
|
490
|
+
def test_eager_with_has_many_through
|
491
|
+
posts_with_comments = people(:michael).posts.merge(:includes => :comments, :order => 'posts.id').to_a
|
492
|
+
posts_with_author = people(:michael).posts.merge(:includes => :author, :order => 'posts.id').to_a
|
493
|
+
posts_with_comments_and_author = people(:michael).posts.merge(:includes => [ :comments, :author ], :order => 'posts.id').to_a
|
494
|
+
assert_equal 2, posts_with_comments.inject(0) { |sum, post| sum + post.comments.size }
|
495
|
+
assert_equal authors(:david), assert_no_queries { posts_with_author.first.author }
|
496
|
+
assert_equal authors(:david), assert_no_queries { posts_with_comments_and_author.first.author }
|
497
|
+
end
|
498
|
+
|
499
|
+
def test_eager_with_has_many_through_a_belongs_to_association
|
500
|
+
author = authors(:mary)
|
501
|
+
Post.create!(:author => author, :title => "TITLE", :body => "BODY")
|
502
|
+
author.author_favorites.create(:favorite_author_id => 1)
|
503
|
+
author.author_favorites.create(:favorite_author_id => 2)
|
504
|
+
posts_with_author_favorites = author.posts.merge(:includes => :author_favorites).to_a
|
505
|
+
assert_no_queries { posts_with_author_favorites.first.author_favorites.first.author_id }
|
506
|
+
end
|
507
|
+
|
508
|
+
def test_eager_with_has_many_through_an_sti_join_model
|
509
|
+
author = Author.all.merge!(:includes => :special_post_comments, :order => 'authors.id').first
|
510
|
+
assert_equal [comments(:does_it_hurt)], assert_no_queries { author.special_post_comments }
|
511
|
+
end
|
512
|
+
|
513
|
+
def test_eager_with_has_many_through_an_sti_join_model_with_conditions_on_both
|
514
|
+
author = Author.all.merge!(:includes => :special_nonexistant_post_comments, :order => 'authors.id').first
|
515
|
+
assert_equal [], author.special_nonexistant_post_comments
|
516
|
+
end
|
517
|
+
|
518
|
+
def test_eager_with_has_many_through_join_model_with_conditions
|
519
|
+
assert_equal Author.all.merge!(:includes => :hello_post_comments,
|
520
|
+
:order => 'authors.id').first.hello_post_comments.sort_by(&:id),
|
521
|
+
Author.all.merge!(:order => 'authors.id').first.hello_post_comments.sort_by(&:id)
|
522
|
+
end
|
523
|
+
|
524
|
+
def test_eager_with_has_many_through_join_model_with_conditions_on_top_level
|
525
|
+
assert_equal comments(:more_greetings), Author.all.merge!(:includes => :comments_with_order_and_conditions).find(authors(:david).id).comments_with_order_and_conditions.first
|
526
|
+
end
|
527
|
+
|
528
|
+
def test_eager_with_has_many_through_join_model_with_include
|
529
|
+
author_comments = Author.all.merge!(:includes => :comments_with_include).find(authors(:david).id).comments_with_include.to_a
|
530
|
+
assert_no_queries do
|
531
|
+
author_comments.first.post.title
|
532
|
+
end
|
533
|
+
end
|
534
|
+
|
535
|
+
def test_eager_with_has_many_through_with_conditions_join_model_with_include
|
536
|
+
post_tags = Post.find(posts(:welcome).id).misc_tags
|
537
|
+
eager_post_tags = Post.all.merge!(:includes => :misc_tags).find(1).misc_tags
|
538
|
+
assert_equal post_tags, eager_post_tags
|
539
|
+
end
|
540
|
+
|
541
|
+
def test_eager_with_has_many_through_join_model_ignores_default_includes
|
542
|
+
assert_nothing_raised do
|
543
|
+
authors(:david).comments_on_posts_with_default_include.to_a
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
547
|
+
def test_eager_with_has_many_and_limit
|
548
|
+
posts = Post.all.merge!(:order => 'posts.id asc', :includes => [ :author, :comments ], :limit => 2).to_a
|
549
|
+
assert_equal 2, posts.size
|
550
|
+
assert_equal 3, posts.inject(0) { |sum, post| sum + post.comments.size }
|
551
|
+
end
|
552
|
+
|
553
|
+
def test_eager_with_has_many_and_limit_and_conditions
|
554
|
+
posts = Post.all.merge!(:includes => [ :author, :comments ], :limit => 2, :where => "posts.body = 'hello'", :order => "posts.id").to_a
|
555
|
+
assert_equal 2, posts.size
|
556
|
+
assert_equal [4,5], posts.collect { |p| p.id }
|
557
|
+
end
|
558
|
+
|
559
|
+
def test_eager_with_has_many_and_limit_and_conditions_array
|
560
|
+
posts = Post.all.merge!(:includes => [ :author, :comments ], :limit => 2, :where => [ "posts.body = ?", 'hello' ], :order => "posts.id").to_a
|
561
|
+
assert_equal 2, posts.size
|
562
|
+
assert_equal [4,5], posts.collect { |p| p.id }
|
563
|
+
end
|
564
|
+
|
565
|
+
def test_eager_with_has_many_and_limit_and_conditions_array_on_the_eagers
|
566
|
+
posts = Post.includes(:author, :comments).limit(2).references(:author).where("authors.name = ?", 'David')
|
567
|
+
assert_equal 2, posts.size
|
568
|
+
|
569
|
+
count = Post.includes(:author, :comments).limit(2).references(:author).where("authors.name = ?", 'David').count
|
570
|
+
assert_equal posts.size, count
|
571
|
+
end
|
572
|
+
|
573
|
+
def test_eager_with_has_many_and_limit_and_high_offset
|
574
|
+
posts = Post.all.merge!(:includes => [ :author, :comments ], :limit => 2, :offset => 10, :where => { 'authors.name' => 'David' }).to_a
|
575
|
+
assert_equal 0, posts.size
|
576
|
+
end
|
577
|
+
|
578
|
+
def test_eager_with_has_many_and_limit_and_high_offset_and_multiple_array_conditions
|
579
|
+
assert_queries(1) do
|
580
|
+
posts = Post.references(:authors, :comments).
|
581
|
+
merge(:includes => [ :author, :comments ], :limit => 2, :offset => 10,
|
582
|
+
:where => [ "authors.name = ? and comments.body = ?", 'David', 'go crazy' ]).to_a
|
583
|
+
assert_equal 0, posts.size
|
584
|
+
end
|
585
|
+
end
|
586
|
+
|
587
|
+
def test_eager_with_has_many_and_limit_and_high_offset_and_multiple_hash_conditions
|
588
|
+
assert_queries(1) do
|
589
|
+
posts = Post.all.merge!(:includes => [ :author, :comments ], :limit => 2, :offset => 10,
|
590
|
+
:where => { 'authors.name' => 'David', 'comments.body' => 'go crazy' }).to_a
|
591
|
+
assert_equal 0, posts.size
|
592
|
+
end
|
593
|
+
end
|
594
|
+
|
595
|
+
def test_count_eager_with_has_many_and_limit_and_high_offset
|
596
|
+
posts = Post.all.merge!(:includes => [ :author, :comments ], :limit => 2, :offset => 10, :where => { 'authors.name' => 'David' }).count(:all)
|
597
|
+
assert_equal 0, posts
|
598
|
+
end
|
599
|
+
|
600
|
+
def test_eager_with_has_many_and_limit_with_no_results
|
601
|
+
posts = Post.all.merge!(:includes => [ :author, :comments ], :limit => 2, :where => "posts.title = 'magic forest'").to_a
|
602
|
+
assert_equal 0, posts.size
|
603
|
+
end
|
604
|
+
|
605
|
+
def test_eager_count_performed_on_a_has_many_association_with_multi_table_conditional
|
606
|
+
author = authors(:david)
|
607
|
+
author_posts_without_comments = author.posts.select { |post| post.comments.blank? }
|
608
|
+
assert_equal author_posts_without_comments.size, author.posts.includes(:comments).where('comments.id is null').references(:comments).count
|
609
|
+
end
|
610
|
+
|
611
|
+
def test_eager_count_performed_on_a_has_many_through_association_with_multi_table_conditional
|
612
|
+
person = people(:michael)
|
613
|
+
person_posts_without_comments = person.posts.select { |post| post.comments.blank? }
|
614
|
+
assert_equal person_posts_without_comments.size, person.posts_with_no_comments.count
|
615
|
+
end
|
616
|
+
|
617
|
+
def test_eager_with_has_and_belongs_to_many_and_limit
|
618
|
+
posts = Post.all.merge!(:includes => :categories, :order => "posts.id", :limit => 3).to_a
|
619
|
+
assert_equal 3, posts.size
|
620
|
+
assert_equal 2, posts[0].categories.size
|
621
|
+
assert_equal 1, posts[1].categories.size
|
622
|
+
assert_equal 0, posts[2].categories.size
|
623
|
+
assert posts[0].categories.include?(categories(:technology))
|
624
|
+
assert posts[1].categories.include?(categories(:general))
|
625
|
+
end
|
626
|
+
|
627
|
+
# Since the preloader for habtm gets raw row hashes from the database and then
|
628
|
+
# instantiates them, this test ensures that it only instantiates one actual
|
629
|
+
# object per record from the database.
|
630
|
+
def test_has_and_belongs_to_many_should_not_instantiate_same_records_multiple_times
|
631
|
+
welcome = posts(:welcome)
|
632
|
+
categories = Category.includes(:posts)
|
633
|
+
|
634
|
+
general = categories.find { |c| c == categories(:general) }
|
635
|
+
technology = categories.find { |c| c == categories(:technology) }
|
636
|
+
|
637
|
+
post1 = general.posts.to_a.find { |p| p == welcome }
|
638
|
+
post2 = technology.posts.to_a.find { |p| p == welcome }
|
639
|
+
|
640
|
+
assert_equal post1.object_id, post2.object_id
|
641
|
+
end
|
642
|
+
|
643
|
+
def test_eager_with_has_many_and_limit_and_conditions_on_the_eagers
|
644
|
+
posts =
|
645
|
+
authors(:david).posts
|
646
|
+
.includes(:comments)
|
647
|
+
.where("comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'")
|
648
|
+
.references(:comments)
|
649
|
+
.limit(2)
|
650
|
+
.to_a
|
651
|
+
assert_equal 2, posts.size
|
652
|
+
|
653
|
+
count =
|
654
|
+
Post.includes(:comments, :author)
|
655
|
+
.where("authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')")
|
656
|
+
.references(:authors, :comments)
|
657
|
+
.limit(2)
|
658
|
+
.count
|
659
|
+
assert_equal count, posts.size
|
660
|
+
end
|
661
|
+
|
662
|
+
def test_eager_with_has_many_and_limit_and_scoped_conditions_on_the_eagers
|
663
|
+
posts = nil
|
664
|
+
Post.includes(:comments)
|
665
|
+
.where("comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'")
|
666
|
+
.references(:comments)
|
667
|
+
.scoping do
|
668
|
+
|
669
|
+
posts = authors(:david).posts.limit(2).to_a
|
670
|
+
assert_equal 2, posts.size
|
671
|
+
end
|
672
|
+
|
673
|
+
Post.includes(:comments, :author)
|
674
|
+
.where("authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')")
|
675
|
+
.references(:authors, :comments)
|
676
|
+
.scoping do
|
677
|
+
|
678
|
+
count = Post.limit(2).count
|
679
|
+
assert_equal count, posts.size
|
680
|
+
end
|
681
|
+
end
|
682
|
+
|
683
|
+
def test_eager_association_loading_with_habtm
|
684
|
+
posts = Post.all.merge!(:includes => :categories, :order => "posts.id").to_a
|
685
|
+
assert_equal 2, posts[0].categories.size
|
686
|
+
assert_equal 1, posts[1].categories.size
|
687
|
+
assert_equal 0, posts[2].categories.size
|
688
|
+
assert posts[0].categories.include?(categories(:technology))
|
689
|
+
assert posts[1].categories.include?(categories(:general))
|
690
|
+
end
|
691
|
+
|
692
|
+
def test_eager_with_inheritance
|
693
|
+
SpecialPost.all.merge!(:includes => [ :comments ]).to_a
|
694
|
+
end
|
695
|
+
|
696
|
+
def test_eager_has_one_with_association_inheritance
|
697
|
+
post = Post.all.merge!(:includes => [ :very_special_comment ]).find(4)
|
698
|
+
assert_equal "VerySpecialComment", post.very_special_comment.class.to_s
|
699
|
+
end
|
700
|
+
|
701
|
+
def test_eager_has_many_with_association_inheritance
|
702
|
+
post = Post.all.merge!(:includes => [ :special_comments ]).find(4)
|
703
|
+
post.special_comments.each do |special_comment|
|
704
|
+
assert special_comment.is_a?(SpecialComment)
|
705
|
+
end
|
706
|
+
end
|
707
|
+
|
708
|
+
def test_eager_habtm_with_association_inheritance
|
709
|
+
post = Post.all.merge!(:includes => [ :special_categories ]).find(6)
|
710
|
+
assert_equal 1, post.special_categories.size
|
711
|
+
post.special_categories.each do |special_category|
|
712
|
+
assert_equal "SpecialCategory", special_category.class.to_s
|
713
|
+
end
|
714
|
+
end
|
715
|
+
|
716
|
+
def test_eager_with_has_one_dependent_does_not_destroy_dependent
|
717
|
+
assert_not_nil companies(:first_firm).account
|
718
|
+
f = Firm.all.merge!(:includes => :account,
|
719
|
+
:where => ["companies.name = ?", "37signals"]).first
|
720
|
+
assert_not_nil f.account
|
721
|
+
assert_equal companies(:first_firm, :reload).account, f.account
|
722
|
+
end
|
723
|
+
|
724
|
+
def test_eager_with_multi_table_conditional_properly_counts_the_records_when_using_size
|
725
|
+
author = authors(:david)
|
726
|
+
posts_with_no_comments = author.posts.select { |post| post.comments.blank? }
|
727
|
+
assert_equal posts_with_no_comments.size, author.posts_with_no_comments.size
|
728
|
+
assert_equal posts_with_no_comments, author.posts_with_no_comments
|
729
|
+
end
|
730
|
+
|
731
|
+
def test_eager_with_invalid_association_reference
|
732
|
+
assert_raise(ActiveRecord::AssociationNotFoundError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
|
733
|
+
Post.all.merge!(:includes=> :monkeys ).find(6)
|
734
|
+
}
|
735
|
+
assert_raise(ActiveRecord::AssociationNotFoundError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
|
736
|
+
Post.all.merge!(:includes=>[ :monkeys ]).find(6)
|
737
|
+
}
|
738
|
+
assert_raise(ActiveRecord::AssociationNotFoundError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
|
739
|
+
Post.all.merge!(:includes=>[ 'monkeys' ]).find(6)
|
740
|
+
}
|
741
|
+
assert_raise(ActiveRecord::AssociationNotFoundError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys, :elephants") {
|
742
|
+
Post.all.merge!(:includes=>[ :monkeys, :elephants ]).find(6)
|
743
|
+
}
|
744
|
+
end
|
745
|
+
|
746
|
+
def test_eager_with_default_scope
|
747
|
+
developer = EagerDeveloperWithDefaultScope.where(:name => 'David').first
|
748
|
+
projects = Project.order(:id).to_a
|
749
|
+
assert_no_queries do
|
750
|
+
assert_equal(projects, developer.projects)
|
751
|
+
end
|
752
|
+
end
|
753
|
+
|
754
|
+
def test_eager_with_default_scope_as_class_method
|
755
|
+
developer = EagerDeveloperWithClassMethodDefaultScope.where(:name => 'David').first
|
756
|
+
projects = Project.order(:id).to_a
|
757
|
+
assert_no_queries do
|
758
|
+
assert_equal(projects, developer.projects)
|
759
|
+
end
|
760
|
+
end
|
761
|
+
|
762
|
+
def test_eager_with_default_scope_as_lambda
|
763
|
+
developer = EagerDeveloperWithLambdaDefaultScope.where(:name => 'David').first
|
764
|
+
projects = Project.order(:id).to_a
|
765
|
+
assert_no_queries do
|
766
|
+
assert_equal(projects, developer.projects)
|
767
|
+
end
|
768
|
+
end
|
769
|
+
|
770
|
+
def test_eager_with_default_scope_as_block
|
771
|
+
# warm up the habtm cache
|
772
|
+
EagerDeveloperWithBlockDefaultScope.where(:name => 'David').first.projects
|
773
|
+
developer = EagerDeveloperWithBlockDefaultScope.where(:name => 'David').first
|
774
|
+
projects = Project.order(:id).to_a
|
775
|
+
assert_no_queries do
|
776
|
+
assert_equal(projects, developer.projects)
|
777
|
+
end
|
778
|
+
end
|
779
|
+
|
780
|
+
def test_eager_with_default_scope_as_callable
|
781
|
+
developer = EagerDeveloperWithCallableDefaultScope.where(:name => 'David').first
|
782
|
+
projects = Project.order(:id).to_a
|
783
|
+
assert_no_queries do
|
784
|
+
assert_equal(projects, developer.projects)
|
785
|
+
end
|
786
|
+
end
|
787
|
+
|
788
|
+
def find_all_ordered(className, include=nil)
|
789
|
+
className.all.merge!(:order=>"#{className.table_name}.#{className.primary_key}", :includes=>include).to_a
|
790
|
+
end
|
791
|
+
|
792
|
+
def test_limited_eager_with_order
|
793
|
+
unless current_adapter?(:IBM_DBAdapter)
|
794
|
+
assert_equal(
|
795
|
+
posts(:thinking, :sti_comments),
|
796
|
+
Post.all.merge!(
|
797
|
+
:includes => [:author, :comments], :where => { 'authors.name' => 'David' },
|
798
|
+
:order => 'UPPER(posts.title)', :limit => 2, :offset => 1
|
799
|
+
).to_a
|
800
|
+
)
|
801
|
+
assert_equal(
|
802
|
+
posts(:sti_post_and_comments, :sti_comments),
|
803
|
+
Post.all.merge!(
|
804
|
+
:includes => [:author, :comments], :where => { 'authors.name' => 'David' },
|
805
|
+
:order => 'UPPER(posts.title) DESC', :limit => 2, :offset => 1
|
806
|
+
).to_a
|
807
|
+
)
|
808
|
+
else
|
809
|
+
assert_equal(
|
810
|
+
posts(:thinking, :sti_comments),
|
811
|
+
Post.all.merge!(
|
812
|
+
:includes => [:author, :comments], :where => { 'authors.name' => 'David' },
|
813
|
+
:order => 'posts.id', :limit => 2, :offset => 1
|
814
|
+
).to_a
|
815
|
+
)
|
816
|
+
assert_equal(
|
817
|
+
posts(:sti_post_and_comments, :sti_comments),
|
818
|
+
Post.all.merge!(
|
819
|
+
:includes => [:author, :comments], :where => { 'authors.name' => 'David' },
|
820
|
+
:order => 'posts.id DESC', :limit => 2, :offset => 1
|
821
|
+
).to_a
|
822
|
+
)
|
823
|
+
end
|
824
|
+
end
|
825
|
+
|
826
|
+
def test_limited_eager_with_multiple_order_columns
|
827
|
+
unless current_adapter?(:IBM_DBAdapter)
|
828
|
+
assert_equal(
|
829
|
+
posts(:thinking, :sti_comments),
|
830
|
+
Post.all.merge!(
|
831
|
+
:includes => [:author, :comments], :where => { 'authors.name' => 'David' },
|
832
|
+
:order => ['UPPER(posts.title)', 'posts.id'], :limit => 2, :offset => 1
|
833
|
+
).to_a
|
834
|
+
)
|
835
|
+
assert_equal(
|
836
|
+
posts(:sti_post_and_comments, :sti_comments),
|
837
|
+
Post.all.merge!(
|
838
|
+
:includes => [:author, :comments], :where => { 'authors.name' => 'David' },
|
839
|
+
:order => ['UPPER(posts.title) DESC', 'posts.id'], :limit => 2, :offset => 1
|
840
|
+
).to_a
|
841
|
+
)
|
842
|
+
else
|
843
|
+
assert_equal(
|
844
|
+
posts(:thinking, :sti_comments),
|
845
|
+
Post.all.merge!(
|
846
|
+
:includes => [:author, :comments], :where => { 'authors.name' => 'David' },
|
847
|
+
:order => ['posts.id'], :limit => 2, :offset => 1
|
848
|
+
).to_a
|
849
|
+
)
|
850
|
+
assert_equal(
|
851
|
+
posts(:sti_post_and_comments, :sti_comments),
|
852
|
+
Post.all.merge!(
|
853
|
+
:includes => [:author, :comments], :where => { 'authors.name' => 'David' },
|
854
|
+
:order => ['posts.id DESC'], :limit => 2, :offset => 1
|
855
|
+
).to_a
|
856
|
+
)
|
857
|
+
end
|
858
|
+
end
|
859
|
+
|
860
|
+
def test_limited_eager_with_numeric_in_association
|
861
|
+
assert_equal(
|
862
|
+
people(:david, :susan),
|
863
|
+
Person.references(:number1_fans_people).merge(
|
864
|
+
:includes => [:readers, :primary_contact, :number1_fan],
|
865
|
+
:where => "number1_fans_people.first_name like 'M%'",
|
866
|
+
:order => 'people.id', :limit => 2, :offset => 0
|
867
|
+
).to_a
|
868
|
+
)
|
869
|
+
end
|
870
|
+
|
871
|
+
def test_preload_with_interpolation
|
872
|
+
assert_deprecated do
|
873
|
+
post = Post.includes(:comments_with_interpolated_conditions).find(posts(:welcome).id)
|
874
|
+
assert_equal [comments(:greetings)], post.comments_with_interpolated_conditions
|
875
|
+
end
|
876
|
+
|
877
|
+
assert_deprecated do
|
878
|
+
post = Post.joins(:comments_with_interpolated_conditions).find(posts(:welcome).id)
|
879
|
+
assert_equal [comments(:greetings)], post.comments_with_interpolated_conditions
|
880
|
+
end
|
881
|
+
end
|
882
|
+
|
883
|
+
def test_polymorphic_type_condition
|
884
|
+
post = Post.all.merge!(:includes => :taggings).find(posts(:thinking).id)
|
885
|
+
assert post.taggings.include?(taggings(:thinking_general))
|
886
|
+
post = SpecialPost.all.merge!(:includes => :taggings).find(posts(:thinking).id)
|
887
|
+
assert post.taggings.include?(taggings(:thinking_general))
|
888
|
+
end
|
889
|
+
|
890
|
+
def test_eager_with_multiple_associations_with_same_table_has_many_and_habtm
|
891
|
+
# Eager includes of has many and habtm associations aren't necessarily sorted in the same way
|
892
|
+
def assert_equal_after_sort(item1, item2, item3 = nil)
|
893
|
+
assert_equal(item1.sort{|a,b| a.id <=> b.id}, item2.sort{|a,b| a.id <=> b.id})
|
894
|
+
assert_equal(item3.sort{|a,b| a.id <=> b.id}, item2.sort{|a,b| a.id <=> b.id}) if item3
|
895
|
+
end
|
896
|
+
# Test regular association, association with conditions, association with
|
897
|
+
# STI, and association with conditions assured not to be true
|
898
|
+
post_types = [:posts, :other_posts, :special_posts]
|
899
|
+
# test both has_many and has_and_belongs_to_many
|
900
|
+
[Author, Category].each do |className|
|
901
|
+
d1 = find_all_ordered(className)
|
902
|
+
# test including all post types at once
|
903
|
+
d2 = find_all_ordered(className, post_types)
|
904
|
+
d1.each_index do |i|
|
905
|
+
assert_equal(d1[i], d2[i])
|
906
|
+
assert_equal_after_sort(d1[i].posts, d2[i].posts)
|
907
|
+
post_types[1..-1].each do |post_type|
|
908
|
+
# test including post_types together
|
909
|
+
d3 = find_all_ordered(className, [:posts, post_type])
|
910
|
+
assert_equal(d1[i], d3[i])
|
911
|
+
assert_equal_after_sort(d1[i].posts, d3[i].posts)
|
912
|
+
assert_equal_after_sort(d1[i].send(post_type), d2[i].send(post_type), d3[i].send(post_type))
|
913
|
+
end
|
914
|
+
end
|
915
|
+
end
|
916
|
+
end
|
917
|
+
|
918
|
+
def test_eager_with_multiple_associations_with_same_table_has_one
|
919
|
+
d1 = find_all_ordered(Firm)
|
920
|
+
d2 = find_all_ordered(Firm, :account)
|
921
|
+
d1.each_index do |i|
|
922
|
+
assert_equal(d1[i], d2[i])
|
923
|
+
assert_equal(d1[i].account, d2[i].account)
|
924
|
+
end
|
925
|
+
end
|
926
|
+
|
927
|
+
def test_eager_with_multiple_associations_with_same_table_belongs_to
|
928
|
+
firm_types = [:firm, :firm_with_basic_id, :firm_with_other_name, :firm_with_condition]
|
929
|
+
d1 = find_all_ordered(Client)
|
930
|
+
d2 = find_all_ordered(Client, firm_types)
|
931
|
+
d1.each_index do |i|
|
932
|
+
assert_equal(d1[i], d2[i])
|
933
|
+
firm_types.each { |type| assert_equal(d1[i].send(type), d2[i].send(type)) }
|
934
|
+
end
|
935
|
+
end
|
936
|
+
def test_eager_with_valid_association_as_string_not_symbol
|
937
|
+
assert_nothing_raised { Post.all.merge!(:includes => 'comments').to_a }
|
938
|
+
end
|
939
|
+
|
940
|
+
def test_eager_with_floating_point_numbers
|
941
|
+
assert_queries(2) do
|
942
|
+
# Before changes, the floating point numbers will be interpreted as table names and will cause this to run in one query
|
943
|
+
Comment.all.merge!(:where => "123.456 = 123.456", :includes => :post).to_a
|
944
|
+
end
|
945
|
+
end
|
946
|
+
|
947
|
+
def test_preconfigured_includes_with_belongs_to
|
948
|
+
author = posts(:welcome).author_with_posts
|
949
|
+
assert_no_queries {assert_equal 5, author.posts.size}
|
950
|
+
end
|
951
|
+
|
952
|
+
def test_preconfigured_includes_with_has_one
|
953
|
+
comment = posts(:sti_comments).very_special_comment_with_post
|
954
|
+
assert_no_queries {assert_equal posts(:sti_comments), comment.post}
|
955
|
+
end
|
956
|
+
|
957
|
+
def test_eager_association_with_scope_with_joins
|
958
|
+
assert_nothing_raised do
|
959
|
+
Post.includes(:very_special_comment_with_post_with_joins).to_a
|
960
|
+
end
|
961
|
+
end
|
962
|
+
|
963
|
+
def test_preconfigured_includes_with_has_many
|
964
|
+
posts = authors(:david).posts_with_comments
|
965
|
+
one = posts.detect { |p| p.id == 1 }
|
966
|
+
assert_no_queries do
|
967
|
+
assert_equal 5, posts.size
|
968
|
+
assert_equal 2, one.comments.size
|
969
|
+
end
|
970
|
+
end
|
971
|
+
|
972
|
+
def test_preconfigured_includes_with_habtm
|
973
|
+
posts = authors(:david).posts_with_categories
|
974
|
+
one = posts.detect { |p| p.id == 1 }
|
975
|
+
assert_no_queries do
|
976
|
+
assert_equal 5, posts.size
|
977
|
+
assert_equal 2, one.categories.size
|
978
|
+
end
|
979
|
+
end
|
980
|
+
|
981
|
+
def test_preconfigured_includes_with_has_many_and_habtm
|
982
|
+
posts = authors(:david).posts_with_comments_and_categories
|
983
|
+
one = posts.detect { |p| p.id == 1 }
|
984
|
+
assert_no_queries do
|
985
|
+
assert_equal 5, posts.size
|
986
|
+
assert_equal 2, one.comments.size
|
987
|
+
assert_equal 2, one.categories.size
|
988
|
+
end
|
989
|
+
end
|
990
|
+
|
991
|
+
def test_count_with_include
|
992
|
+
assert_equal 3, authors(:david).posts_with_comments.where("length(comments.body) > 15").references(:comments).count
|
993
|
+
end
|
994
|
+
|
995
|
+
def test_association_loading_notification
|
996
|
+
notifications = messages_for('instantiation.active_record') do
|
997
|
+
Developer.all.merge!(:includes => 'projects', :where => { 'developers_projects.access_level' => 1 }, :limit => 5).to_a.size
|
998
|
+
end
|
999
|
+
|
1000
|
+
message = notifications.first
|
1001
|
+
payload = message.last
|
1002
|
+
count = Developer.all.merge!(:includes => 'projects', :where => { 'developers_projects.access_level' => 1 }, :limit => 5).to_a.size
|
1003
|
+
|
1004
|
+
# eagerloaded row count should be greater than just developer count
|
1005
|
+
assert_operator payload[:record_count], :>, count
|
1006
|
+
assert_equal Developer.name, payload[:class_name]
|
1007
|
+
end
|
1008
|
+
|
1009
|
+
def test_base_messages
|
1010
|
+
notifications = messages_for('instantiation.active_record') do
|
1011
|
+
Developer.all.to_a
|
1012
|
+
end
|
1013
|
+
message = notifications.first
|
1014
|
+
payload = message.last
|
1015
|
+
|
1016
|
+
assert_equal Developer.all.to_a.count, payload[:record_count]
|
1017
|
+
assert_equal Developer.name, payload[:class_name]
|
1018
|
+
end
|
1019
|
+
|
1020
|
+
def messages_for(name)
|
1021
|
+
notifications = []
|
1022
|
+
ActiveSupport::Notifications.subscribe(name) do |*args|
|
1023
|
+
notifications << args
|
1024
|
+
end
|
1025
|
+
yield
|
1026
|
+
notifications
|
1027
|
+
ensure
|
1028
|
+
ActiveSupport::Notifications.unsubscribe(name)
|
1029
|
+
end
|
1030
|
+
|
1031
|
+
def test_load_with_sti_sharing_association
|
1032
|
+
assert_queries(2) do #should not do 1 query per subclass
|
1033
|
+
Comment.includes(:post).to_a
|
1034
|
+
end
|
1035
|
+
end
|
1036
|
+
|
1037
|
+
def test_conditions_on_join_table_with_include_and_limit
|
1038
|
+
assert_equal 3, Developer.all.merge!(:includes => 'projects', :where => { 'developers_projects.access_level' => 1 }, :limit => 5).to_a.size
|
1039
|
+
end
|
1040
|
+
|
1041
|
+
def test_dont_create_temporary_active_record_instances
|
1042
|
+
Developer.instance_count = 0
|
1043
|
+
developers = Developer.all.merge!(:includes => 'projects', :where => { 'developers_projects.access_level' => 1 }, :limit => 5).to_a
|
1044
|
+
assert_equal developers.count, Developer.instance_count
|
1045
|
+
end
|
1046
|
+
|
1047
|
+
def test_order_on_join_table_with_include_and_limit
|
1048
|
+
assert_equal 5, Developer.all.merge!(:includes => 'projects', :order => 'developers_projects.joined_on DESC', :limit => 5).to_a.size
|
1049
|
+
end
|
1050
|
+
|
1051
|
+
def test_eager_loading_with_order_on_joined_table_preloads
|
1052
|
+
posts = assert_queries(2) do
|
1053
|
+
Post.all.merge!(:joins => :comments, :includes => :author, :order => 'comments.id DESC').to_a
|
1054
|
+
end
|
1055
|
+
assert_equal posts(:eager_other), posts[1]
|
1056
|
+
assert_equal authors(:mary), assert_no_queries { posts[1].author}
|
1057
|
+
end
|
1058
|
+
|
1059
|
+
def test_eager_loading_with_conditions_on_joined_table_preloads
|
1060
|
+
posts = assert_queries(2) do
|
1061
|
+
Post.all.merge!(:select => 'distinct posts.*', :includes => :author, :joins => [:comments], :where => "comments.body like 'Thank you%'", :order => 'posts.id').to_a
|
1062
|
+
end
|
1063
|
+
assert_equal [posts(:welcome)], posts
|
1064
|
+
assert_equal authors(:david), assert_no_queries { posts[0].author}
|
1065
|
+
|
1066
|
+
posts = assert_queries(2) do
|
1067
|
+
Post.all.merge!(:select => 'distinct posts.*', :includes => :author, :joins => [:comments], :where => "comments.body like 'Thank you%'", :order => 'posts.id').to_a
|
1068
|
+
end
|
1069
|
+
assert_equal [posts(:welcome)], posts
|
1070
|
+
assert_equal authors(:david), assert_no_queries { posts[0].author}
|
1071
|
+
|
1072
|
+
posts = assert_queries(2) do
|
1073
|
+
Post.all.merge!(:includes => :author, :joins => {:taggings => :tag}, :where => "tags.name = 'General'", :order => 'posts.id').to_a
|
1074
|
+
end
|
1075
|
+
assert_equal posts(:welcome, :thinking), posts
|
1076
|
+
|
1077
|
+
posts = assert_queries(2) do
|
1078
|
+
Post.all.merge!(:includes => :author, :joins => {:taggings => {:tag => :taggings}}, :where => "taggings_tags.super_tag_id=2", :order => 'posts.id').to_a
|
1079
|
+
end
|
1080
|
+
assert_equal posts(:welcome, :thinking), posts
|
1081
|
+
end
|
1082
|
+
|
1083
|
+
def test_preload_has_many_with_association_condition_and_default_scope
|
1084
|
+
post = Post.create!(:title => 'Beaches', :body => "I like beaches!")
|
1085
|
+
Reader.create! :person => people(:david), :post => post
|
1086
|
+
LazyReader.create! :person => people(:susan), :post => post
|
1087
|
+
|
1088
|
+
assert_equal 1, post.lazy_readers.to_a.size
|
1089
|
+
assert_equal 2, post.lazy_readers_skimmers_or_not.to_a.size
|
1090
|
+
|
1091
|
+
post_with_readers = Post.includes(:lazy_readers_skimmers_or_not).find(post.id)
|
1092
|
+
assert_equal 2, post_with_readers.lazy_readers_skimmers_or_not.to_a.size
|
1093
|
+
end
|
1094
|
+
|
1095
|
+
def test_eager_loading_with_conditions_on_string_joined_table_preloads
|
1096
|
+
posts = assert_queries(2) do
|
1097
|
+
Post.all.merge!(:select => 'distinct posts.*', :includes => :author, :joins => "INNER JOIN comments on comments.post_id = posts.id", :where => "comments.body like 'Thank you%'", :order => 'posts.id').to_a
|
1098
|
+
end
|
1099
|
+
assert_equal [posts(:welcome)], posts
|
1100
|
+
assert_equal authors(:david), assert_no_queries { posts[0].author}
|
1101
|
+
|
1102
|
+
posts = assert_queries(2) do
|
1103
|
+
Post.all.merge!(:select => 'distinct posts.*', :includes => :author, :joins => ["INNER JOIN comments on comments.post_id = posts.id"], :where => "comments.body like 'Thank you%'", :order => 'posts.id').to_a
|
1104
|
+
end
|
1105
|
+
assert_equal [posts(:welcome)], posts
|
1106
|
+
assert_equal authors(:david), assert_no_queries { posts[0].author}
|
1107
|
+
end
|
1108
|
+
|
1109
|
+
def test_eager_loading_with_select_on_joined_table_preloads
|
1110
|
+
posts = assert_queries(2) do
|
1111
|
+
Post.all.merge!(:select => 'posts.*, authors.name as author_name', :includes => :comments, :joins => :author, :order => 'posts.id').to_a
|
1112
|
+
end
|
1113
|
+
assert_equal 'David', posts[0].author_name
|
1114
|
+
assert_equal posts(:welcome).comments, assert_no_queries { posts[0].comments}
|
1115
|
+
end
|
1116
|
+
|
1117
|
+
def test_eager_loading_with_conditions_on_join_model_preloads
|
1118
|
+
authors = assert_queries(2) do
|
1119
|
+
Author.all.merge!(:includes => :author_address, :joins => :comments, :where => "posts.title like 'Welcome%'").to_a
|
1120
|
+
end
|
1121
|
+
assert_equal authors(:david), authors[0]
|
1122
|
+
assert_equal author_addresses(:david_address), authors[0].author_address
|
1123
|
+
end
|
1124
|
+
|
1125
|
+
def test_preload_belongs_to_uses_exclusive_scope
|
1126
|
+
people = Person.males.merge(:includes => :primary_contact).to_a
|
1127
|
+
assert_not_equal people.length, 0
|
1128
|
+
people.each do |person|
|
1129
|
+
assert_no_queries {assert_not_nil person.primary_contact}
|
1130
|
+
assert_equal Person.find(person.id).primary_contact, person.primary_contact
|
1131
|
+
end
|
1132
|
+
end
|
1133
|
+
|
1134
|
+
def test_preload_has_many_uses_exclusive_scope
|
1135
|
+
people = Person.males.includes(:agents).to_a
|
1136
|
+
people.each do |person|
|
1137
|
+
assert_equal Person.find(person.id).agents, person.agents
|
1138
|
+
end
|
1139
|
+
end
|
1140
|
+
|
1141
|
+
def test_preload_has_many_using_primary_key
|
1142
|
+
expected = Firm.first.clients_using_primary_key.to_a
|
1143
|
+
firm = Firm.includes(:clients_using_primary_key).first
|
1144
|
+
assert_no_queries do
|
1145
|
+
assert_equal expected, firm.clients_using_primary_key
|
1146
|
+
end
|
1147
|
+
end
|
1148
|
+
|
1149
|
+
def test_include_has_many_using_primary_key
|
1150
|
+
expected = Firm.find(1).clients_using_primary_key.sort_by(&:name)
|
1151
|
+
# Oracle adapter truncates alias to 30 characters
|
1152
|
+
if current_adapter?(:OracleAdapter)
|
1153
|
+
firm = Firm.all.merge!(:includes => :clients_using_primary_key, :order => 'clients_using_primary_keys_companies'[0,30]+'.name').find(1)
|
1154
|
+
elsif current_adapter?(:IBM_DBAdapter)
|
1155
|
+
#firm = Firm.all.merge!(:includes => :clients_using_primary_key).find(1)
|
1156
|
+
firm = Firm.all.merge!(:includes => :clients_using_primary_key, :order => 'clients_using_primary_keys_companies.name').find(1)
|
1157
|
+
else
|
1158
|
+
firm = Firm.all.merge!(:includes => :clients_using_primary_key, :order => 'clients_using_primary_keys_companies.name').find(1)
|
1159
|
+
end
|
1160
|
+
assert_no_queries do
|
1161
|
+
assert_equal expected, firm.clients_using_primary_key
|
1162
|
+
end
|
1163
|
+
end
|
1164
|
+
|
1165
|
+
def test_preload_has_one_using_primary_key
|
1166
|
+
expected = accounts(:signals37)
|
1167
|
+
firm = Firm.all.merge!(:includes => :account_using_primary_key, :order => 'companies.id').first
|
1168
|
+
assert_no_queries do
|
1169
|
+
assert_equal expected, firm.account_using_primary_key
|
1170
|
+
end
|
1171
|
+
end
|
1172
|
+
|
1173
|
+
def test_include_has_one_using_primary_key
|
1174
|
+
expected = accounts(:signals37)
|
1175
|
+
firm = Firm.all.merge!(:includes => :account_using_primary_key, :order => 'accounts.id').to_a.detect {|f| f.id == 1}
|
1176
|
+
assert_no_queries do
|
1177
|
+
assert_equal expected, firm.account_using_primary_key
|
1178
|
+
end
|
1179
|
+
end
|
1180
|
+
|
1181
|
+
def test_preloading_empty_belongs_to
|
1182
|
+
c = Client.create!(:name => 'Foo', :client_of => Company.maximum(:id) + 1)
|
1183
|
+
|
1184
|
+
client = assert_queries(2) { Client.preload(:firm).find(c.id) }
|
1185
|
+
assert_no_queries { assert_nil client.firm }
|
1186
|
+
end
|
1187
|
+
|
1188
|
+
def test_preloading_empty_belongs_to_polymorphic
|
1189
|
+
t = Tagging.create!(:taggable_type => 'Post', :taggable_id => Post.maximum(:id) + 1, :tag => tags(:general))
|
1190
|
+
|
1191
|
+
tagging = assert_queries(2) { Tagging.preload(:taggable).find(t.id) }
|
1192
|
+
assert_no_queries { assert_nil tagging.taggable }
|
1193
|
+
end
|
1194
|
+
|
1195
|
+
def test_preloading_through_empty_belongs_to
|
1196
|
+
c = Client.create!(:name => 'Foo', :client_of => Company.maximum(:id) + 1)
|
1197
|
+
|
1198
|
+
client = assert_queries(2) { Client.preload(:accounts).find(c.id) }
|
1199
|
+
assert_no_queries { assert client.accounts.empty? }
|
1200
|
+
end
|
1201
|
+
|
1202
|
+
def test_preloading_has_many_through_with_uniq
|
1203
|
+
mary = Author.includes(:unique_categorized_posts).where(:id => authors(:mary).id).first
|
1204
|
+
assert_equal 1, mary.unique_categorized_posts.length
|
1205
|
+
assert_equal 1, mary.unique_categorized_post_ids.length
|
1206
|
+
end
|
1207
|
+
|
1208
|
+
def test_preloading_polymorphic_with_custom_foreign_type
|
1209
|
+
sponsor = sponsors(:moustache_club_sponsor_for_groucho)
|
1210
|
+
groucho = members(:groucho)
|
1211
|
+
|
1212
|
+
sponsor = assert_queries(2) {
|
1213
|
+
Sponsor.includes(:thing).where(:id => sponsor.id).first
|
1214
|
+
}
|
1215
|
+
assert_no_queries { assert_equal groucho, sponsor.thing }
|
1216
|
+
end
|
1217
|
+
|
1218
|
+
def test_joins_with_includes_should_preload_via_joins
|
1219
|
+
post = assert_queries(1) { Post.includes(:comments).joins(:comments).order('posts.id desc').to_a.first }
|
1220
|
+
|
1221
|
+
assert_queries(0) do
|
1222
|
+
assert_not_equal 0, post.comments.to_a.count
|
1223
|
+
end
|
1224
|
+
end
|
1225
|
+
|
1226
|
+
def test_join_eager_with_empty_order_should_generate_valid_sql
|
1227
|
+
assert_nothing_raised(ActiveRecord::StatementInvalid) do
|
1228
|
+
Post.includes(:comments).order("").where(:comments => {:body => "Thank you for the welcome"}).first
|
1229
|
+
end
|
1230
|
+
end
|
1231
|
+
|
1232
|
+
def test_join_eager_with_nil_order_should_generate_valid_sql
|
1233
|
+
assert_nothing_raised(ActiveRecord::StatementInvalid) do
|
1234
|
+
Post.includes(:comments).order(nil).where(:comments => {:body => "Thank you for the welcome"}).first
|
1235
|
+
end
|
1236
|
+
end
|
1237
|
+
|
1238
|
+
def test_deep_including_through_habtm
|
1239
|
+
# warm up habtm cache
|
1240
|
+
posts = Post.all.merge!(:includes => {:categories => :categorizations}, :order => "posts.id").to_a
|
1241
|
+
posts[0].categories[0].categorizations.length
|
1242
|
+
|
1243
|
+
posts = Post.all.merge!(:includes => {:categories => :categorizations}, :order => "posts.id").to_a
|
1244
|
+
assert_no_queries { assert_equal 2, posts[0].categories[0].categorizations.length }
|
1245
|
+
assert_no_queries { assert_equal 1, posts[0].categories[1].categorizations.length }
|
1246
|
+
assert_no_queries { assert_equal 2, posts[1].categories[0].categorizations.length }
|
1247
|
+
end
|
1248
|
+
|
1249
|
+
test "scoping with a circular preload" do
|
1250
|
+
assert_equal Comment.find(1), Comment.preload(:post => :comments).scoping { Comment.find(1) }
|
1251
|
+
end
|
1252
|
+
|
1253
|
+
test "circular preload does not modify unscoped" do
|
1254
|
+
expected = FirstPost.unscoped.find(2)
|
1255
|
+
FirstPost.preload(:comments => :first_post).find(1)
|
1256
|
+
assert_equal expected, FirstPost.unscoped.find(2)
|
1257
|
+
end
|
1258
|
+
|
1259
|
+
test "preload ignores the scoping" do
|
1260
|
+
assert_equal(
|
1261
|
+
Comment.find(1).post,
|
1262
|
+
Post.where('1 = 0').scoping { Comment.preload(:post).find(1).post }
|
1263
|
+
)
|
1264
|
+
end
|
1265
|
+
|
1266
|
+
test "deep preload" do
|
1267
|
+
post = Post.preload(author: :posts, comments: :post).first
|
1268
|
+
|
1269
|
+
assert_predicate post.author.association(:posts), :loaded?
|
1270
|
+
assert_predicate post.comments.first.association(:post), :loaded?
|
1271
|
+
end
|
1272
|
+
|
1273
|
+
test "preloading does not cache has many association subset when preloaded with a through association" do
|
1274
|
+
author = Author.includes(:comments_with_order_and_conditions, :posts).first
|
1275
|
+
assert_no_queries { assert_equal 2, author.comments_with_order_and_conditions.size }
|
1276
|
+
assert_no_queries { assert_equal 5, author.posts.size, "should not cache a subset of the association" }
|
1277
|
+
end
|
1278
|
+
|
1279
|
+
test "preloading a through association twice does not reset it" do
|
1280
|
+
members = Member.includes(current_membership: :club).includes(:club).to_a
|
1281
|
+
assert_no_queries {
|
1282
|
+
assert_equal 3, members.map(&:current_membership).map(&:club).size
|
1283
|
+
}
|
1284
|
+
end
|
1285
|
+
|
1286
|
+
test "works in combination with order(:symbol) and reorder(:symbol)" do
|
1287
|
+
author = Author.includes(:posts).references(:posts).order(:name).find_by('posts.title IS NOT NULL')
|
1288
|
+
assert_equal authors(:bob), author
|
1289
|
+
|
1290
|
+
author = Author.includes(:posts).references(:posts).reorder(:name).find_by('posts.title IS NOT NULL')
|
1291
|
+
assert_equal authors(:bob), author
|
1292
|
+
end
|
1293
|
+
|
1294
|
+
test "preloading with a polymorphic association and using the existential predicate but also using a select" do
|
1295
|
+
assert_equal authors(:david), authors(:david).essays.includes(:writer).first.writer
|
1296
|
+
|
1297
|
+
assert_nothing_raised do
|
1298
|
+
authors(:david).essays.includes(:writer).select(:name).any?
|
1299
|
+
end
|
1300
|
+
end
|
1301
|
+
|
1302
|
+
test "preloading the same association twice works" do
|
1303
|
+
Member.create!
|
1304
|
+
members = Member.preload(:current_membership).includes(current_membership: :club).all.to_a
|
1305
|
+
assert_no_queries {
|
1306
|
+
members_with_membership = members.select(&:current_membership)
|
1307
|
+
assert_equal 3, members_with_membership.map(&:current_membership).map(&:club).size
|
1308
|
+
}
|
1309
|
+
end
|
1310
|
+
|
1311
|
+
test "preloading with a polymorphic association and using the existential predicate" do
|
1312
|
+
assert_equal authors(:david), authors(:david).essays.includes(:writer).first.writer
|
1313
|
+
|
1314
|
+
assert_nothing_raised do
|
1315
|
+
authors(:david).essays.includes(:writer).any?
|
1316
|
+
end
|
1317
|
+
end
|
1318
|
+
|
1319
|
+
test "preloading associations with string joins and order references" do
|
1320
|
+
author = assert_queries(2) {
|
1321
|
+
Author.includes(:posts).joins("LEFT JOIN posts ON posts.author_id = authors.id").order("posts.title DESC").first
|
1322
|
+
}
|
1323
|
+
assert_no_queries {
|
1324
|
+
assert_equal 5, author.posts.size
|
1325
|
+
}
|
1326
|
+
end
|
1327
|
+
|
1328
|
+
test "including associations with where.not adds implicit references" do
|
1329
|
+
author = assert_queries(2) {
|
1330
|
+
Author.includes(:posts).where.not(posts: { title: 'Welcome to the weblog'} ).last
|
1331
|
+
}
|
1332
|
+
|
1333
|
+
assert_no_queries {
|
1334
|
+
assert_equal 2, author.posts.size
|
1335
|
+
}
|
1336
|
+
end
|
1337
|
+
|
1338
|
+
test "including association based on sql condition and no database column" do
|
1339
|
+
assert_equal pets(:parrot), Owner.including_last_pet.first.last_pet
|
1340
|
+
end
|
1341
|
+
|
1342
|
+
test "include instance dependent associations is deprecated" do
|
1343
|
+
message = "association scope 'posts_with_signature' is"
|
1344
|
+
assert_deprecated message do
|
1345
|
+
begin
|
1346
|
+
Author.includes(:posts_with_signature).to_a
|
1347
|
+
rescue NoMethodError
|
1348
|
+
# it's expected that preloading of this association fails
|
1349
|
+
end
|
1350
|
+
end
|
1351
|
+
|
1352
|
+
assert_deprecated message do
|
1353
|
+
Author.preload(:posts_with_signature).to_a rescue NoMethodError
|
1354
|
+
end
|
1355
|
+
|
1356
|
+
assert_deprecated message do
|
1357
|
+
Author.eager_load(:posts_with_signature).to_a
|
1358
|
+
end
|
1359
|
+
end
|
1360
|
+
|
1361
|
+
test "associations with extensions are not instance dependent" do
|
1362
|
+
assert_not_deprecated do
|
1363
|
+
Author.includes(:posts_with_extension).to_a
|
1364
|
+
end
|
1365
|
+
end
|
1366
|
+
|
1367
|
+
test "including associations with extensions and an instance dependent scope is deprecated" do
|
1368
|
+
assert_deprecated do
|
1369
|
+
Author.includes(:posts_with_extension_and_instance).to_a
|
1370
|
+
end
|
1371
|
+
end
|
1372
|
+
|
1373
|
+
test "preloading readonly association" do
|
1374
|
+
# has-one
|
1375
|
+
firm = Firm.where(id: "1").preload(:readonly_account).first!
|
1376
|
+
assert firm.readonly_account.readonly?
|
1377
|
+
|
1378
|
+
# has_and_belongs_to_many
|
1379
|
+
project = Project.where(id: "2").preload(:readonly_developers).first!
|
1380
|
+
assert project.readonly_developers.first.readonly?
|
1381
|
+
|
1382
|
+
# has-many :through
|
1383
|
+
david = Author.where(id: "1").preload(:readonly_comments).first!
|
1384
|
+
assert david.readonly_comments.first.readonly?
|
1385
|
+
end
|
1386
|
+
|
1387
|
+
test "eager-loading readonly association" do
|
1388
|
+
skip "eager_load does not yet preserve readonly associations"
|
1389
|
+
# has-one
|
1390
|
+
firm = Firm.where(id: "1").eager_load(:readonly_account).first!
|
1391
|
+
assert firm.readonly_account.readonly?
|
1392
|
+
|
1393
|
+
# has_and_belongs_to_many
|
1394
|
+
project = Project.where(id: "2").eager_load(:readonly_developers).first!
|
1395
|
+
assert project.readonly_developers.first.readonly?
|
1396
|
+
|
1397
|
+
# has-many :through
|
1398
|
+
david = Author.where(id: "1").eager_load(:readonly_comments).first!
|
1399
|
+
assert david.readonly_comments.first.readonly?
|
1400
|
+
end
|
1401
|
+
|
1402
|
+
test "preloading a polymorphic association with references to the associated table" do
|
1403
|
+
post = Post.includes(:tags).references(:tags).where('tags.name = ?', 'General').first
|
1404
|
+
assert_equal posts(:welcome), post
|
1405
|
+
end
|
1406
|
+
|
1407
|
+
test "eager-loading a polymorphic association with references to the associated table" do
|
1408
|
+
post = Post.eager_load(:tags).where('tags.name = ?', 'General').first
|
1409
|
+
assert_equal posts(:welcome), post
|
1410
|
+
end
|
1411
|
+
end
|