diff options
Diffstat (limited to 'activerecord/test/cases/associations')
9 files changed, 228 insertions, 49 deletions
diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb index 1fca1be181..93dd427951 100644 --- a/activerecord/test/cases/associations/belongs_to_associations_test.rb +++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb @@ -367,6 +367,30 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase assert_equal "ODEGY", odegy_account.reload_firm.name end + def test_reload_the_belonging_object_with_query_cache + odegy_account_id = accounts(:odegy_account).id + + connection = ActiveRecord::Base.connection + connection.enable_query_cache! + connection.clear_query_cache + + # Populate the cache with a query + odegy_account = Account.find(odegy_account_id) + + # Populate the cache with a second query + odegy_account.firm + + assert_equal 2, connection.query_cache.size + + # Clear the cache and fetch the firm again, populating the cache with a query + assert_queries(1) { odegy_account.reload_firm } + + # This query is not cached anymore, so it should make a real SQL query + assert_queries(1) { Account.find(odegy_account_id) } + ensure + ActiveRecord::Base.connection.disable_query_cache! + end + def test_natural_assignment_to_nil client = Client.find(3) client.firm = nil @@ -694,7 +718,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase line_item = LineItem.create! Invoice.create!(line_items: [line_item]) - assert_queries(0) { line_item.save } + assert_no_queries { line_item.save } end def test_belongs_to_with_touch_option_on_destroy @@ -789,7 +813,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase def test_dont_find_target_when_foreign_key_is_null tagging = taggings(:thinking_general) - assert_queries(0) { tagging.super_tag } + assert_no_queries { tagging.super_tag } end def test_dont_find_target_when_saving_foreign_key_after_stale_association_loaded diff --git a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb index ba2104eb26..a9e22c7643 100644 --- a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb +++ b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb @@ -160,6 +160,16 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase end end + def test_preload_through_missing_records + post = Post.where.not(author_id: Author.select(:id)).preload(author: { comments: :post }).first! + assert_no_queries { assert_nil post.author } + end + + def test_eager_association_loading_with_missing_first_record + posts = Post.where(id: 3).preload(author: { comments: :post }).to_a + assert_equal posts.size, 1 + end + def test_eager_association_loading_with_recursive_cascading_four_levels_has_many_through source = Vertex.all.merge!(includes: { sinks: { sinks: { sinks: :sinks } } }, order: "vertices.id").first assert_equal vertices(:vertex_4), assert_no_queries { source.sinks.first.sinks.first.sinks.first } diff --git a/activerecord/test/cases/associations/eager_load_nested_include_test.rb b/activerecord/test/cases/associations/eager_load_nested_include_test.rb index c5b2b77bd4..525ad3197a 100644 --- a/activerecord/test/cases/associations/eager_load_nested_include_test.rb +++ b/activerecord/test/cases/associations/eager_load_nested_include_test.rb @@ -92,7 +92,7 @@ class EagerLoadPolyAssocsTest < ActiveRecord::TestCase def test_include_query res = ShapeExpression.all.merge!(includes: [ :shape, { paint: :non_poly } ]).to_a assert_equal NUM_SHAPE_EXPRESSIONS, res.size - assert_queries(0) do + assert_no_queries do res.each do |se| assert_not_nil se.paint.non_poly, "this is the association that was loading incorrectly before the change" assert_not_nil se.shape, "just making sure other associations still work" diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index 79b3b4a6ad..39034746c9 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -1346,7 +1346,7 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_joins_with_includes_should_preload_via_joins post = assert_queries(1) { Post.includes(:comments).joins(:comments).order("posts.id desc").to_a.first } - assert_queries(0) do + assert_no_queries do assert_not_equal 0, post.comments.to_a.count end end diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb index 482302055d..515eb65d37 100644 --- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb @@ -25,6 +25,8 @@ require "models/user" require "models/member" require "models/membership" require "models/sponsor" +require "models/lesson" +require "models/student" require "models/country" require "models/treaty" require "models/vertex" @@ -275,7 +277,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase def test_habtm_saving_multiple_relationships new_project = Project.new("name" => "Grimetime") amount_of_developers = 4 - developers = (0...amount_of_developers).collect { |i| Developer.create(name: "JME #{i}") }.reverse + developers = (0...amount_of_developers).reverse_each.map { |i| Developer.create(name: "JME #{i}") } new_project.developer_ids = [developers[0].id, developers[1].id] new_project.developers_with_callback_ids = [developers[2].id, developers[3].id] @@ -310,7 +312,11 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase def test_build devel = Developer.find(1) - proj = assert_no_queries(ignore_none: false) { devel.projects.build("name" => "Projekt") } + + # Load schema information so we don't query below if running just this test. + Project.define_attribute_methods + + proj = assert_no_queries { devel.projects.build("name" => "Projekt") } assert_not_predicate devel.projects, :loaded? assert_equal devel.projects.last, proj @@ -325,7 +331,11 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase def test_new_aliased_to_build devel = Developer.find(1) - proj = assert_no_queries(ignore_none: false) { devel.projects.new("name" => "Projekt") } + + # Load schema information so we don't query below if running just this test. + Project.define_attribute_methods + + proj = assert_no_queries { devel.projects.new("name" => "Projekt") } assert_not_predicate devel.projects, :loaded? assert_equal devel.projects.last, proj @@ -546,7 +556,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase developer = project.developers.first - assert_no_queries(ignore_none: false) do + assert_no_queries do assert_predicate project.developers, :loaded? assert_includes project.developers, developer end @@ -741,7 +751,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase def test_get_ids_for_loaded_associations developer = developers(:david) developer.projects.reload - assert_queries(0) do + assert_no_queries do developer.project_ids developer.project_ids end @@ -772,6 +782,16 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase assert_equal [projects(:active_record), projects(:action_controller)].map(&:id).sort, developer.project_ids.sort end + def test_singular_ids_are_reloaded_after_collection_concat + student = Student.create(name: "Alberto Almagro") + student.lesson_ids + + lesson = Lesson.create(name: "DSI") + student.lessons << lesson + + assert_includes student.lesson_ids, lesson.id + end + def test_scoped_find_on_through_association_doesnt_return_read_only_records tag = Post.find(1).tags.find_by_name("General") @@ -859,7 +879,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase def test_has_and_belongs_to_many_associations_on_new_records_use_null_relations projects = Developer.new.projects - assert_no_queries(ignore_none: false) do + assert_no_queries do assert_equal [], projects assert_equal [], projects.where(title: "omg") assert_equal [], projects.pluck(:title) diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index 0b44515e00..d13e1a86e9 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -458,7 +458,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_finder_method_with_dirty_target company = companies(:first_firm) new_clients = [] - assert_no_queries(ignore_none: false) do + + # Load schema information so we don't query below if running just this test. + Client.define_attribute_methods + + assert_no_queries do new_clients << company.clients_of_firm.build(name: "Another Client") new_clients << company.clients_of_firm.build(name: "Another Client II") new_clients << company.clients_of_firm.build(name: "Another Client III") @@ -478,7 +482,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_finder_bang_method_with_dirty_target company = companies(:first_firm) new_clients = [] - assert_no_queries(ignore_none: false) do + + # Load schema information so we don't query below if running just this test. + Client.define_attribute_methods + + assert_no_queries do new_clients << company.clients_of_firm.build(name: "Another Client") new_clients << company.clients_of_firm.build(name: "Another Client II") new_clients << company.clients_of_firm.build(name: "Another Client III") @@ -821,6 +829,48 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_not_same original_object, collection.first, "Expected #first after #reload to return a new object" end + def test_reload_with_query_cache + connection = ActiveRecord::Base.connection + connection.enable_query_cache! + connection.clear_query_cache + + # Populate the cache with a query + firm = Firm.first + # Populate the cache with a second query + firm.clients.load + + assert_equal 2, connection.query_cache.size + + # Clear the cache and fetch the clients again, populating the cache with a query + assert_queries(1) { firm.clients.reload } + # This query is cached, so it shouldn't make a real SQL query + assert_queries(0) { firm.clients.load } + + assert_equal 1, connection.query_cache.size + ensure + ActiveRecord::Base.connection.disable_query_cache! + end + + def test_reloading_unloaded_associations_with_query_cache + connection = ActiveRecord::Base.connection + connection.enable_query_cache! + connection.clear_query_cache + + firm = Firm.create!(name: "firm name") + client = firm.clients.create!(name: "client name") + firm.clients.to_a # add request to cache + + connection.uncached do + client.update!(name: "new client name") + end + + firm = Firm.find(firm.id) + + assert_equal [client.name], firm.clients.reload.map(&:name) + ensure + ActiveRecord::Base.connection.disable_query_cache! + end + def test_find_all_with_include_and_conditions assert_nothing_raised do Developer.all.merge!(joins: :audit_logs, where: { "audit_logs.message" => nil, :name => "Smith" }).to_a @@ -955,8 +1005,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_transactions_when_adding_to_new_record - assert_no_queries(ignore_none: false) do - firm = Firm.new + # Load schema information so we don't query below if running just this test. + Client.define_attribute_methods + + firm = Firm.new + assert_no_queries do firm.clients_of_firm.concat(Client.new("name" => "Natural Company")) end end @@ -970,7 +1023,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_new_aliased_to_build company = companies(:first_firm) - new_client = assert_no_queries(ignore_none: false) { company.clients_of_firm.new("name" => "Another Client") } + + # Load schema information so we don't query below if running just this test. + Client.define_attribute_methods + + new_client = assert_no_queries { company.clients_of_firm.new("name" => "Another Client") } assert_not_predicate company.clients_of_firm, :loaded? assert_equal "Another Client", new_client.name @@ -980,7 +1037,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_build company = companies(:first_firm) - new_client = assert_no_queries(ignore_none: false) { company.clients_of_firm.build("name" => "Another Client") } + + # Load schema information so we don't query below if running just this test. + Client.define_attribute_methods + + new_client = assert_no_queries { company.clients_of_firm.build("name" => "Another Client") } assert_not_predicate company.clients_of_firm, :loaded? assert_equal "Another Client", new_client.name @@ -1037,7 +1098,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_build_many company = companies(:first_firm) - new_clients = assert_no_queries(ignore_none: false) { company.clients_of_firm.build([{ "name" => "Another Client" }, { "name" => "Another Client II" }]) } + + # Load schema information so we don't query below if running just this test. + Client.define_attribute_methods + + new_clients = assert_no_queries { company.clients_of_firm.build([{ "name" => "Another Client" }, { "name" => "Another Client II" }]) } assert_equal 2, new_clients.size end @@ -1049,10 +1114,12 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_build_without_loading_association first_topic = topics(:first) - Reply.column_names assert_equal 1, first_topic.replies.length + # Load schema information so we don't query below if running just this test. + Reply.define_attribute_methods + assert_no_queries do first_topic.replies.build(title: "Not saved", content: "Superstars") assert_equal 2, first_topic.replies.size @@ -1063,7 +1130,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_build_via_block company = companies(:first_firm) - new_client = assert_no_queries(ignore_none: false) { company.clients_of_firm.build { |client| client.name = "Another Client" } } + + # Load schema information so we don't query below if running just this test. + Client.define_attribute_methods + + new_client = assert_no_queries { company.clients_of_firm.build { |client| client.name = "Another Client" } } assert_not_predicate company.clients_of_firm, :loaded? assert_equal "Another Client", new_client.name @@ -1073,7 +1144,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_build_many_via_block company = companies(:first_firm) - new_clients = assert_no_queries(ignore_none: false) do + + # Load schema information so we don't query below if running just this test. + Client.define_attribute_methods + + new_clients = assert_no_queries do company.clients_of_firm.build([{ "name" => "Another Client" }, { "name" => "Another Client II" }]) do |client| client.name = "changed" end @@ -1086,8 +1161,6 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_create_without_loading_association first_firm = companies(:first_firm) - Firm.column_names - Client.column_names assert_equal 2, first_firm.clients_of_firm.size first_firm.clients_of_firm.reset @@ -1266,7 +1339,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_calling_empty_with_counter_cache post = posts(:welcome) - assert_queries(0) do + assert_no_queries do assert_not_empty post.comments end end @@ -1364,8 +1437,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_transaction_when_deleting_new_record - assert_no_queries(ignore_none: false) do - firm = Firm.new + # Load schema information so we don't query below if running just this test. + Client.define_attribute_methods + + firm = Firm.new + assert_no_queries do client = Client.new("name" => "New Client") firm.clients_of_firm << client firm.clients_of_firm.destroy(client) @@ -1800,7 +1876,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase firm.clients = [] firm.save - assert_queries(0, ignore_none: true) do + assert_no_queries do firm.clients = [] end @@ -1822,8 +1898,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_transactions_when_replacing_on_new_record - assert_no_queries(ignore_none: false) do - firm = Firm.new + # Load schema information so we don't query below if running just this test. + Client.define_attribute_methods + + firm = Firm.new + assert_no_queries do firm.clients_of_firm = [Client.new("name" => "New Client")] end end @@ -1835,7 +1914,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_get_ids_for_loaded_associations company = companies(:first_firm) company.clients.reload - assert_queries(0) do + assert_no_queries do company.client_ids company.client_ids end @@ -1862,11 +1941,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_get_ids_for_association_on_new_record_does_not_try_to_find_records - Company.columns # Load schema information so we don't query below - Contract.columns # if running just this test. + # Load schema information so we don't query below if running just this test. + companies(:first_client).contract_ids company = Company.new - assert_queries(0) do + assert_no_queries do company.contract_ids end @@ -1972,7 +2051,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase firm.clients.load_target assert_predicate firm.clients, :loaded? - assert_no_queries(ignore_none: false) do + assert_no_queries do firm.clients.first assert_equal 2, firm.clients.first(2).size firm.clients.last @@ -2354,6 +2433,19 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_collection_association_with_private_kernel_method firm = companies(:first_firm) assert_equal [accounts(:signals37)], firm.accounts.open + assert_equal [accounts(:signals37)], firm.accounts.available + end + + def test_association_with_or_doesnt_set_inverse_instance_key + firm = companies(:first_firm) + accounts = firm.accounts.or(Account.where(firm_id: nil)).order(:id) + assert_equal [firm.id, nil], accounts.map(&:firm_id) + end + + def test_association_with_rewhere_doesnt_set_inverse_instance_key + firm = companies(:first_firm) + accounts = firm.accounts.rewhere(firm_id: [firm.id, nil]).order(:id) + assert_equal [firm.id, nil], accounts.map(&:firm_id) end test "first_or_initialize adds the record to the association" do @@ -2385,7 +2477,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase test "has many associations on new records use null relations" do post = Post.new - assert_no_queries(ignore_none: false) do + assert_no_queries do assert_equal [], post.comments assert_equal [], post.comments.where(body: "omg") assert_equal [], post.comments.pluck(:body) diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb index 442f4a93d4..7b405c74c4 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -274,7 +274,10 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase assert_queries(1) { posts(:thinking) } new_person = nil # so block binding catches it - assert_queries(0) do + # Load schema information so we don't query below if running just this test. + Person.define_attribute_methods + + assert_no_queries do new_person = Person.new first_name: "bob" end @@ -294,7 +297,10 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_associate_new_by_building assert_queries(1) { posts(:thinking) } - assert_queries(0) do + # Load schema information so we don't query below if running just this test. + Person.define_attribute_methods + + assert_no_queries do posts(:thinking).people.build(first_name: "Bob") posts(:thinking).people.new(first_name: "Ted") end @@ -571,10 +577,10 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase posts(:welcome).people = [people(:david)] end - assert_queries(0) { + assert_no_queries do assert_includes posts(:welcome).people, people(:david) assert_not_includes posts(:welcome).people, people(:michael) - } + end assert_includes posts(:welcome).reload.people.reload, people(:david) assert_not_includes posts(:welcome).reload.people.reload, people(:michael) @@ -698,7 +704,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase posts(:welcome).people.clear end - assert_queries(0) do + assert_no_queries do assert_empty posts(:welcome).people end @@ -788,7 +794,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_get_ids_for_loaded_associations person = people(:michael) person.posts.reload - assert_queries(0) do + assert_no_queries do person.post_ids person.post_ids end @@ -1198,7 +1204,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_has_many_through_associations_on_new_records_use_null_relations person = Person.new - assert_no_queries(ignore_none: false) do + assert_no_queries do assert_equal [], person.posts assert_equal [], person.posts.where(body: "omg") assert_equal [], person.posts.pluck(:body) diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb index 9eea34d2b9..adfb3ce072 100644 --- a/activerecord/test/cases/associations/has_one_associations_test.rb +++ b/activerecord/test/cases/associations/has_one_associations_test.rb @@ -37,10 +37,10 @@ class HasOneAssociationsTest < ActiveRecord::TestCase def test_has_one_cache_nils firm = companies(:another_firm) assert_queries(1) { assert_nil firm.account } - assert_queries(0) { assert_nil firm.account } + assert_no_queries { assert_nil firm.account } - firms = Firm.all.merge!(includes: :account).to_a - assert_queries(0) { firms.each(&:account) } + firms = Firm.includes(:account).to_a + assert_no_queries { firms.each(&:account) } end def test_with_select @@ -231,9 +231,13 @@ class HasOneAssociationsTest < ActiveRecord::TestCase end def test_build_association_dont_create_transaction - assert_no_queries(ignore_none: false) { - Firm.new.build_account - } + # Load schema information so we don't query below if running just this test. + Account.define_attribute_methods + + firm = Firm.new + assert_no_queries do + firm.build_account + end end def test_building_the_associated_object_with_implicit_sti_base_class @@ -329,6 +333,29 @@ class HasOneAssociationsTest < ActiveRecord::TestCase assert_equal 80, odegy.reload_account.credit_limit end + def test_reload_association_with_query_cache + odegy_id = companies(:odegy).id + + connection = ActiveRecord::Base.connection + connection.enable_query_cache! + connection.clear_query_cache + + # Populate the cache with a query + odegy = Company.find(odegy_id) + # Populate the cache with a second query + odegy.account + + assert_equal 2, connection.query_cache.size + + # Clear the cache and fetch the account again, populating the cache with a query + assert_queries(1) { odegy.reload_account } + + # This query is not cached anymore, so it should make a real SQL query + assert_queries(1) { Company.find(odegy_id) } + ensure + ActiveRecord::Base.connection.disable_query_cache! + end + def test_build firm = Firm.new("name" => "GlobalMegaCorp") firm.save diff --git a/activerecord/test/cases/associations/nested_through_associations_test.rb b/activerecord/test/cases/associations/nested_through_associations_test.rb index 03ed1c1d47..5821744530 100644 --- a/activerecord/test/cases/associations/nested_through_associations_test.rb +++ b/activerecord/test/cases/associations/nested_through_associations_test.rb @@ -137,7 +137,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase def test_has_many_through_has_one_through_with_has_one_source_reflection_preload members = assert_queries(4) { Member.includes(:nested_sponsors).to_a } mustache = sponsors(:moustache_club_sponsor_for_groucho) - assert_no_queries(ignore_none: false) do + assert_no_queries do assert_equal [mustache], members.first.nested_sponsors end end @@ -196,7 +196,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase # postgresql test if randomly executed then executes "SHOW max_identifier_length". Hence # the need to ignore certain predefined sqls that deal with system calls. - assert_no_queries(ignore_none: false) do + assert_no_queries do assert_equal [groucho_details, other_details], members.first.organization_member_details_2.sort_by(&:id) end end |