Ensure AR #second, #third, etc. finders work through associations

This commit fixes two regressions introduced in cafe31a078 where
newly created finder methods #second, #third, #forth, and #fifth
caused a NoMethodError error on reload associations and where we
were pulling the wrong element out of cached associations.

Examples:

  some_book.authors.reload.second

  # Before
  # => NoMethodError: undefined method 'first' for nil:NilClass

  # After
  # => #<Author id: 2, name: "Sally Second", ...>

  some_book.first.authors.first
  some_book.first.authors.second

  # Before
  # => #<Author id: 1, name: "Freddy First", ...>
  # => #<Author id: 1, name: "Freddy First", ...>

  # After
  # => #<Author id: 1, name: "Freddy First", ...>
  # => #<Author id: 2, name: "Sally Second", ...>

Fixes #13783.
This commit is contained in:
Jason Meller 2014-01-21 17:34:39 -05:00
parent 9383de42a2
commit 03855e790d
9 changed files with 168 additions and 85 deletions

View File

@ -96,11 +96,31 @@ module ActiveRecord
end
def first(*args)
first_or_last(:first, *args)
first_nth_or_last(:first, *args)
end
def second(*args)
first_nth_or_last(:second, *args)
end
def third(*args)
first_nth_or_last(:third, *args)
end
def fourth(*args)
first_nth_or_last(:fourth, *args)
end
def fifth(*args)
first_nth_or_last(:fifth, *args)
end
def forty_two(*args)
first_nth_or_last(:forty_two, *args)
end
def last(*args)
first_or_last(:last, *args)
first_nth_or_last(:last, *args)
end
def build(attributes = {}, &block)
@ -526,7 +546,7 @@ module ActiveRecord
# * target already loaded
# * owner is new record
# * target contains new or changed record(s)
def fetch_first_or_last_using_find?(args)
def fetch_first_nth_or_last_using_find?(args)
if args.first.is_a?(Hash)
true
else
@ -564,10 +584,10 @@ module ActiveRecord
end
# Fetches the first/last using SQL if possible, otherwise from the target array.
def first_or_last(type, *args)
def first_nth_or_last(type, *args)
args.shift if args.first.is_a?(Hash) && args.first.empty?
collection = fetch_first_or_last_using_find?(args) ? scope : load_target
collection = fetch_first_nth_or_last_using_find?(args) ? scope : load_target
collection.send(type, *args).tap do |record|
set_inverse_instance record if record.is_a? ActiveRecord::Base
end

View File

@ -170,6 +170,32 @@ module ActiveRecord
@association.first(*args)
end
# Same as +first+ except returns only the second record.
def second(*args)
@association.second(*args)
end
# Same as +first+ except returns only the third record.
def third(*args)
@association.third(*args)
end
# Same as +first+ except returns only the fourth record.
def fourth(*args)
@association.fourth(*args)
end
# Same as +first+ except returns only the fifth record.
def fifth(*args)
@association.fifth(*args)
end
# Same as +first+ except returns only the forty second record.
# Also known as accessing "the reddit".
def forty_two(*args)
@association.forty_two(*args)
end
# Returns the last record, or the last +n+ records, from the collection.
# If the collection is empty, the first form returns +nil+, and the second
# form returns an empty array.

View File

@ -129,7 +129,7 @@ module ActiveRecord
if limit
find_nth_with_limit(offset_value, limit)
else
find_nth(offset_value)
find_nth(:first, offset_value)
end
end
@ -179,7 +179,7 @@ module ActiveRecord
# Person.offset(3).second # returns the second object from OFFSET 3 (which is OFFSET 4)
# Person.where(["user_name = :u", { u: user_name }]).second
def second
find_nth(offset_value ? offset_value + 1 : 1)
find_nth(:second, offset_value ? offset_value + 1 : 1)
end
# Same as +second+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record
@ -195,7 +195,7 @@ module ActiveRecord
# Person.offset(3).third # returns the third object from OFFSET 3 (which is OFFSET 5)
# Person.where(["user_name = :u", { u: user_name }]).third
def third
find_nth(offset_value ? offset_value + 2 : 2)
find_nth(:third, offset_value ? offset_value + 2 : 2)
end
# Same as +third+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record
@ -211,7 +211,7 @@ module ActiveRecord
# Person.offset(3).fourth # returns the fourth object from OFFSET 3 (which is OFFSET 6)
# Person.where(["user_name = :u", { u: user_name }]).fourth
def fourth
find_nth(offset_value ? offset_value + 3 : 3)
find_nth(:fourth, offset_value ? offset_value + 3 : 3)
end
# Same as +fourth+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record
@ -227,7 +227,7 @@ module ActiveRecord
# Person.offset(3).fifth # returns the fifth object from OFFSET 3 (which is OFFSET 7)
# Person.where(["user_name = :u", { u: user_name }]).fifth
def fifth
find_nth(offset_value ? offset_value + 4 : 4)
find_nth(:fifth, offset_value ? offset_value + 4 : 4)
end
# Same as +fifth+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record
@ -243,7 +243,7 @@ module ActiveRecord
# Person.offset(3).forty_two # returns the fifth object from OFFSET 3 (which is OFFSET 44)
# Person.where(["user_name = :u", { u: user_name }]).forty_two
def forty_two
find_nth(offset_value ? offset_value + 41 : 41)
find_nth(:forty_two, offset_value ? offset_value + 41 : 41)
end
# Same as +forty_two+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record
@ -444,9 +444,9 @@ module ActiveRecord
end
end
def find_nth(offset)
def find_nth(ordinal, offset)
if loaded?
@records.first
@records.send(ordinal)
else
@offsets[offset] ||= find_nth_with_limit(offset, 1).first
end

View File

@ -215,6 +215,31 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
bulbs.first({})
end
assert_no_queries do
bulbs.second()
bulbs.second({})
end
assert_no_queries do
bulbs.third()
bulbs.third({})
end
assert_no_queries do
bulbs.fourth()
bulbs.fourth({})
end
assert_no_queries do
bulbs.fifth()
bulbs.fifth({})
end
assert_no_queries do
bulbs.forty_two()
bulbs.forty_two({})
end
assert_no_queries do
bulbs.last()
bulbs.last({})
@ -242,11 +267,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
# sometimes tests on Oracle fail if ORDER BY is not provided therefore add always :order with :first
def test_counting_with_counter_sql
assert_equal 2, Firm.all.merge!(:order => "id").first.clients.count
assert_equal 3, Firm.all.merge!(:order => "id").first.clients.count
end
def test_counting
assert_equal 2, Firm.all.merge!(:order => "id").first.plain_clients.count
assert_equal 3, Firm.all.merge!(:order => "id").first.plain_clients.count
end
def test_counting_with_single_hash
@ -254,7 +279,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
end
def test_counting_with_column_name_and_hash
assert_equal 2, Firm.all.merge!(:order => "id").first.plain_clients.count(:name)
assert_equal 3, Firm.all.merge!(:order => "id").first.plain_clients.count(:name)
end
def test_counting_with_association_limit
@ -264,17 +289,17 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
end
def test_finding
assert_equal 2, Firm.all.merge!(:order => "id").first.clients.length
assert_equal 3, Firm.all.merge!(:order => "id").first.clients.length
end
def test_finding_array_compatibility
assert_equal 2, Firm.order(:id).find{|f| f.id > 0}.clients.length
assert_equal 3, Firm.order(:id).find{|f| f.id > 0}.clients.length
end
def test_find_many_with_merged_options
assert_equal 1, companies(:first_firm).limited_clients.size
assert_equal 1, companies(:first_firm).limited_clients.to_a.size
assert_equal 2, companies(:first_firm).limited_clients.limit(nil).to_a.size
assert_equal 3, companies(:first_firm).limited_clients.limit(nil).to_a.size
end
def test_find_should_append_to_association_order
@ -283,8 +308,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
end
def test_dynamic_find_should_respect_association_order
assert_equal companies(:second_client), companies(:first_firm).clients_sorted_desc.where("type = 'Client'").first
assert_equal companies(:second_client), companies(:first_firm).clients_sorted_desc.find_by_type('Client')
assert_equal companies(:another_first_firm_client), companies(:first_firm).clients_sorted_desc.where("type = 'Client'").first
assert_equal companies(:another_first_firm_client), companies(:first_firm).clients_sorted_desc.find_by_type('Client')
end
def test_cant_save_has_many_readonly_association
@ -297,7 +322,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
end
def test_finding_with_different_class_name_and_order
assert_equal "Microsoft", Firm.all.merge!(:order => "id").first.clients_sorted_desc.first.name
assert_equal "Apex", Firm.all.merge!(:order => "id").first.clients_sorted_desc.first.name
end
def test_finding_with_foreign_key
@ -355,7 +380,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_find_all
firm = Firm.all.merge!(:order => "id").first
assert_equal 2, firm.clients.where("#{QUOTED_TYPE} = 'Client'").to_a.length
assert_equal 3, firm.clients.where("#{QUOTED_TYPE} = 'Client'").to_a.length
assert_equal 1, firm.clients.where("name = 'Summit'").to_a.length
end
@ -364,7 +389,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert ! firm.clients.loaded?
assert_queries(3) do
assert_queries(4) do
firm.clients.find_each(:batch_size => 1) {|c| assert_equal firm.id, c.firm_id }
end
@ -434,15 +459,15 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_find_grouped
all_clients_of_firm1 = Client.all.merge!(:where => "firm_id = 1").to_a
grouped_clients_of_firm1 = Client.all.merge!(:where => "firm_id = 1", :group => "firm_id", :select => 'firm_id, count(id) as clients_count').to_a
assert_equal 2, all_clients_of_firm1.size
assert_equal 3, all_clients_of_firm1.size
assert_equal 1, grouped_clients_of_firm1.size
end
def test_find_scoped_grouped
assert_equal 1, companies(:first_firm).clients_grouped_by_firm_id.size
assert_equal 1, companies(:first_firm).clients_grouped_by_firm_id.length
assert_equal 2, companies(:first_firm).clients_grouped_by_name.size
assert_equal 2, companies(:first_firm).clients_grouped_by_name.length
assert_equal 3, companies(:first_firm).clients_grouped_by_name.size
assert_equal 3, companies(:first_firm).clients_grouped_by_name.length
end
def test_find_scoped_grouped_having
@ -470,17 +495,17 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
force_signal37_to_load_all_clients_of_firm
natural = Client.new("name" => "Natural Company")
companies(:first_firm).clients_of_firm << natural
assert_equal 2, companies(:first_firm).clients_of_firm.size # checking via the collection
assert_equal 2, companies(:first_firm).clients_of_firm(true).size # checking using the db
assert_equal 3, companies(:first_firm).clients_of_firm.size # checking via the collection
assert_equal 3, companies(:first_firm).clients_of_firm(true).size # checking using the db
assert_equal natural, companies(:first_firm).clients_of_firm.last
end
def test_adding_using_create
first_firm = companies(:first_firm)
assert_equal 2, first_firm.plain_clients.size
first_firm.plain_clients.create(:name => "Natural Company")
assert_equal 3, first_firm.plain_clients.length
assert_equal 3, first_firm.plain_clients.size
first_firm.plain_clients.create(:name => "Natural Company")
assert_equal 4, first_firm.plain_clients.length
assert_equal 4, first_firm.plain_clients.size
end
def test_create_with_bang_on_has_many_when_parent_is_new_raises
@ -519,8 +544,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_adding_a_collection
force_signal37_to_load_all_clients_of_firm
companies(:first_firm).clients_of_firm.concat([Client.new("name" => "Natural Company"), Client.new("name" => "Apple")])
assert_equal 3, companies(:first_firm).clients_of_firm.size
assert_equal 3, companies(:first_firm).clients_of_firm(true).size
assert_equal 4, companies(:first_firm).clients_of_firm.size
assert_equal 4, companies(:first_firm).clients_of_firm(true).size
end
def test_transactions_when_adding_to_persisted
@ -573,7 +598,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
company = companies(:first_firm) # company already has one client
company.clients_of_firm.build("name" => "Another Client")
company.clients_of_firm.build("name" => "Yet Another Client")
assert_equal 3, company.clients_of_firm.size
assert_equal 4, company.clients_of_firm.size
end
def test_collection_not_empty_after_building
@ -649,14 +674,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
Firm.column_names
Client.column_names
assert_equal 1, first_firm.clients_of_firm.size
assert_equal 2, first_firm.clients_of_firm.size
first_firm.clients_of_firm.reset
assert_queries(1) do
first_firm.clients_of_firm.create(:name => "Superstars")
end
assert_equal 2, first_firm.clients_of_firm.size
assert_equal 3, first_firm.clients_of_firm.size
end
def test_create
@ -669,7 +694,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_create_many
companies(:first_firm).clients_of_firm.create([{"name" => "Another Client"}, {"name" => "Another Client II"}])
assert_equal 3, companies(:first_firm).clients_of_firm(true).size
assert_equal 4, companies(:first_firm).clients_of_firm(true).size
end
def test_create_followed_by_save_does_not_load_target
@ -681,8 +706,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_deleting
force_signal37_to_load_all_clients_of_firm
companies(:first_firm).clients_of_firm.delete(companies(:first_firm).clients_of_firm.first)
assert_equal 0, companies(:first_firm).clients_of_firm.size
assert_equal 0, companies(:first_firm).clients_of_firm(true).size
assert_equal 1, companies(:first_firm).clients_of_firm.size
assert_equal 1, companies(:first_firm).clients_of_firm(true).size
end
def test_deleting_before_save
@ -779,8 +804,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_deleting_a_collection
force_signal37_to_load_all_clients_of_firm
companies(:first_firm).clients_of_firm.create("name" => "Another Client")
assert_equal 2, companies(:first_firm).clients_of_firm.size
companies(:first_firm).clients_of_firm.delete([companies(:first_firm).clients_of_firm[0], companies(:first_firm).clients_of_firm[1]])
assert_equal 3, companies(:first_firm).clients_of_firm.size
companies(:first_firm).clients_of_firm.delete([companies(:first_firm).clients_of_firm[0], companies(:first_firm).clients_of_firm[1], companies(:first_firm).clients_of_firm[2]])
assert_equal 0, companies(:first_firm).clients_of_firm.size
assert_equal 0, companies(:first_firm).clients_of_firm(true).size
end
@ -789,7 +814,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
force_signal37_to_load_all_clients_of_firm
companies(:first_firm).dependent_clients_of_firm.create("name" => "Another Client")
clients = companies(:first_firm).dependent_clients_of_firm.to_a
assert_equal 2, clients.count
assert_equal 3, clients.count
assert_difference "Client.count", -(clients.count) do
companies(:first_firm).dependent_clients_of_firm.delete_all
@ -799,7 +824,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_delete_all_with_not_yet_loaded_association_collection
force_signal37_to_load_all_clients_of_firm
companies(:first_firm).clients_of_firm.create("name" => "Another Client")
assert_equal 2, companies(:first_firm).clients_of_firm.size
assert_equal 3, companies(:first_firm).clients_of_firm.size
companies(:first_firm).clients_of_firm.reset
companies(:first_firm).clients_of_firm.delete_all
assert_equal 0, companies(:first_firm).clients_of_firm.size
@ -832,7 +857,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_clearing_an_association_collection
firm = companies(:first_firm)
client_id = firm.clients_of_firm.first.id
assert_equal 1, firm.clients_of_firm.size
assert_equal 2, firm.clients_of_firm.size
firm.clients_of_firm.clear
@ -866,7 +891,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_clearing_a_dependent_association_collection
firm = companies(:first_firm)
client_id = firm.dependent_clients_of_firm.first.id
assert_equal 1, firm.dependent_clients_of_firm.size
assert_equal 2, firm.dependent_clients_of_firm.size
assert_equal 1, Client.find_by_id(client_id).client_of
# :delete_all is called on each client since the dependent options is :destroy
@ -897,7 +922,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_clearing_an_exclusively_dependent_association_collection
firm = companies(:first_firm)
client_id = firm.exclusively_dependent_clients_of_firm.first.id
assert_equal 1, firm.exclusively_dependent_clients_of_firm.size
assert_equal 2, firm.exclusively_dependent_clients_of_firm.size
assert_equal [], Client.destroyed_client_ids[firm.id]
@ -953,10 +978,10 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_delete_all_association_with_primary_key_deletes_correct_records
firm = Firm.first
# break the vanilla firm_id foreign key
assert_equal 2, firm.clients.count
assert_equal 3, firm.clients.count
firm.clients.first.update_columns(firm_id: nil)
assert_equal 1, firm.clients(true).count
assert_equal 1, firm.clients_using_primary_key_with_delete_all.count
assert_equal 2, firm.clients(true).count
assert_equal 2, firm.clients_using_primary_key_with_delete_all.count
old_record = firm.clients_using_primary_key_with_delete_all.first
firm = Firm.first
firm.destroy
@ -988,8 +1013,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
force_signal37_to_load_all_clients_of_firm
summit = Client.find_by_name('Summit')
companies(:first_firm).clients_of_firm.delete(summit)
assert_equal 1, companies(:first_firm).clients_of_firm.size
assert_equal 1, companies(:first_firm).clients_of_firm(true).size
assert_equal 2, companies(:first_firm).clients_of_firm.size
assert_equal 2, companies(:first_firm).clients_of_firm(true).size
assert_equal 2, summit.client_of
end
@ -1026,8 +1051,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
companies(:first_firm).clients_of_firm.destroy(companies(:first_firm).clients_of_firm.first)
end
assert_equal 0, companies(:first_firm).reload.clients_of_firm.size
assert_equal 0, companies(:first_firm).clients_of_firm(true).size
assert_equal 1, companies(:first_firm).reload.clients_of_firm.size
assert_equal 1, companies(:first_firm).clients_of_firm(true).size
end
def test_destroying_by_fixnum_id
@ -1037,8 +1062,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
companies(:first_firm).clients_of_firm.destroy(companies(:first_firm).clients_of_firm.first.id)
end
assert_equal 0, companies(:first_firm).reload.clients_of_firm.size
assert_equal 0, companies(:first_firm).clients_of_firm(true).size
assert_equal 1, companies(:first_firm).reload.clients_of_firm.size
assert_equal 1, companies(:first_firm).clients_of_firm(true).size
end
def test_destroying_by_string_id
@ -1048,21 +1073,21 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
companies(:first_firm).clients_of_firm.destroy(companies(:first_firm).clients_of_firm.first.id.to_s)
end
assert_equal 0, companies(:first_firm).reload.clients_of_firm.size
assert_equal 0, companies(:first_firm).clients_of_firm(true).size
assert_equal 1, companies(:first_firm).reload.clients_of_firm.size
assert_equal 1, companies(:first_firm).clients_of_firm(true).size
end
def test_destroying_a_collection
force_signal37_to_load_all_clients_of_firm
companies(:first_firm).clients_of_firm.create("name" => "Another Client")
assert_equal 2, companies(:first_firm).clients_of_firm.size
assert_equal 3, companies(:first_firm).clients_of_firm.size
assert_difference "Client.count", -2 do
companies(:first_firm).clients_of_firm.destroy([companies(:first_firm).clients_of_firm[0], companies(:first_firm).clients_of_firm[1]])
end
assert_equal 0, companies(:first_firm).reload.clients_of_firm.size
assert_equal 0, companies(:first_firm).clients_of_firm(true).size
assert_equal 1, companies(:first_firm).reload.clients_of_firm.size
assert_equal 1, companies(:first_firm).clients_of_firm(true).size
end
def test_destroy_all
@ -1078,7 +1103,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_dependence
firm = companies(:first_firm)
assert_equal 2, firm.clients.size
assert_equal 3, firm.clients.size
firm.destroy
assert Client.all.merge!(:where => "firm_id=#{firm.id}").to_a.empty?
end
@ -1091,14 +1116,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_destroy_dependent_when_deleted_from_association
# sometimes tests on Oracle fail if ORDER BY is not provided therefore add always :order with :first
firm = Firm.all.merge!(:order => "id").first
assert_equal 2, firm.clients.size
assert_equal 3, firm.clients.size
client = firm.clients.first
firm.clients.delete(client)
assert_raise(ActiveRecord::RecordNotFound) { Client.find(client.id) }
assert_raise(ActiveRecord::RecordNotFound) { firm.clients.find(client.id) }
assert_equal 1, firm.clients.size
assert_equal 2, firm.clients.size
end
def test_three_levels_of_dependence
@ -1113,12 +1138,12 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_dependence_with_transaction_support_on_failure
firm = companies(:first_firm)
clients = firm.clients
assert_equal 2, clients.length
assert_equal 3, clients.length
clients.last.instance_eval { def overwrite_to_raise() raise "Trigger rollback" end }
firm.destroy rescue "do nothing"
assert_equal 2, Client.all.merge!(:where => "firm_id=#{firm.id}").to_a.size
assert_equal 3, Client.all.merge!(:where => "firm_id=#{firm.id}").to_a.size
end
def test_dependence_on_account
@ -1239,7 +1264,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
end
def test_get_ids
assert_equal [companies(:first_client).id, companies(:second_client).id], companies(:first_firm).client_ids
assert_equal [companies(:first_client).id, companies(:second_client).id, companies(:another_first_firm_client).id], companies(:first_firm).client_ids
end
def test_get_ids_for_loaded_associations
@ -1254,7 +1279,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_get_ids_for_unloaded_associations_does_not_load_them
company = companies(:first_firm)
assert !company.clients.loaded?
assert_equal [companies(:first_client).id, companies(:second_client).id], company.client_ids
assert_equal [companies(:first_client).id, companies(:second_client).id, companies(:another_first_firm_client).id], company.client_ids
assert !company.clients.loaded?
end
@ -1263,7 +1288,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
end
def test_get_ids_for_ordered_association
assert_equal [companies(:second_client).id, companies(:first_client).id], companies(:first_firm).clients_ordered_by_name_ids
assert_equal [companies(:another_first_firm_client).id, companies(:second_client).id, companies(:first_client).id], companies(:first_firm).clients_ordered_by_name_ids
end
def test_get_ids_for_association_on_new_record_does_not_try_to_find_records
@ -1357,9 +1382,10 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal false, firm.clients.include?(client)
end
def test_calling_first_or_last_on_association_should_not_load_association
def test_calling_first_nth_or_last_on_association_should_not_load_association
firm = companies(:first_firm)
firm.clients.first
firm.clients.second
firm.clients.last
assert !firm.clients.loaded?
end
@ -1384,30 +1410,33 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_queries 1 do
firm.clients.first
firm.clients.second
firm.clients.last
end
assert firm.clients.loaded?
end
def test_calling_first_or_last_on_existing_record_with_create_should_not_load_association
def test_calling_first_nth_or_last_on_existing_record_with_create_should_not_load_association
firm = companies(:first_firm)
firm.clients.create(:name => 'Foo')
assert !firm.clients.loaded?
assert_queries 2 do
assert_queries 3 do
firm.clients.first
firm.clients.second
firm.clients.last
end
assert !firm.clients.loaded?
end
def test_calling_first_or_last_on_new_record_should_not_run_queries
def test_calling_first_nth_or_last_on_new_record_should_not_run_queries
firm = Firm.new
assert_no_queries do
firm.clients.first
firm.clients.second
firm.clients.last
end
end
@ -1494,7 +1523,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_calling_many_should_return_true_if_more_than_one
firm = companies(:first_firm)
assert firm.clients.many?
assert_equal 2, firm.clients.size
assert_equal 3, firm.clients.size
end
def test_joins_with_namespaced_model_should_use_correct_type

View File

@ -401,7 +401,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
assert_equal new_client, companies(:first_firm).clients_of_firm.last
assert !companies(:first_firm).save
assert !new_client.persisted?
assert_equal 1, companies(:first_firm).clients_of_firm(true).size
assert_equal 2, companies(:first_firm).clients_of_firm(true).size
end
def test_adding_before_save
@ -455,7 +455,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
company.name += '-changed'
assert_queries(2) { assert company.save }
assert new_client.persisted?
assert_equal 2, company.clients_of_firm(true).size
assert_equal 3, company.clients_of_firm(true).size
end
def test_build_many_before_save
@ -464,7 +464,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
company.name += '-changed'
assert_queries(3) { assert company.save }
assert_equal 3, company.clients_of_firm(true).size
assert_equal 4, company.clients_of_firm(true).size
end
def test_build_via_block_before_save
@ -475,7 +475,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
company.name += '-changed'
assert_queries(2) { assert company.save }
assert new_client.persisted?
assert_equal 2, company.clients_of_firm(true).size
assert_equal 3, company.clients_of_firm(true).size
end
def test_build_many_via_block_before_save
@ -488,7 +488,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
company.name += '-changed'
assert_queries(3) { assert company.save }
assert_equal 3, company.clients_of_firm(true).size
assert_equal 4, company.clients_of_firm(true).size
end
def test_replace_on_new_object

View File

@ -278,7 +278,7 @@ class CalculationsTest < ActiveRecord::TestCase
c = Company.group("UPPER(#{QUOTED_TYPE})").count(:all)
assert_equal 2, c[nil]
assert_equal 1, c['DEPENDENTFIRM']
assert_equal 4, c['CLIENT']
assert_equal 5, c['CLIENT']
assert_equal 2, c['FIRM']
end
@ -286,7 +286,7 @@ class CalculationsTest < ActiveRecord::TestCase
c = Company.group("UPPER(companies.#{QUOTED_TYPE})").count(:all)
assert_equal 2, c[nil]
assert_equal 1, c['DEPENDENTFIRM']
assert_equal 4, c['CLIENT']
assert_equal 5, c['CLIENT']
assert_equal 2, c['FIRM']
end

View File

@ -900,8 +900,8 @@ class FinderTest < ActiveRecord::TestCase
end
def test_select_values
assert_equal ["1","2","3","4","5","6","7","8","9", "10"], Company.connection.select_values("SELECT id FROM companies ORDER BY id").map! { |i| i.to_s }
assert_equal ["37signals","Summit","Microsoft", "Flamboyant Software", "Ex Nihilo", "RailsCore", "Leetsoft", "Jadedpixel", "Odegy", "Ex Nihilo Part Deux"], Company.connection.select_values("SELECT name FROM companies ORDER BY id")
assert_equal ["1","2","3","4","5","6","7","8","9", "10", "11"], Company.connection.select_values("SELECT id FROM companies ORDER BY id").map! { |i| i.to_s }
assert_equal ["37signals","Summit","Microsoft", "Flamboyant Software", "Ex Nihilo", "RailsCore", "Leetsoft", "Jadedpixel", "Odegy", "Ex Nihilo Part Deux", "Apex"], Company.connection.select_values("SELECT name FROM companies ORDER BY id")
end
def test_select_rows

View File

@ -222,9 +222,9 @@ class InheritanceTest < ActiveRecord::TestCase
end
def test_inheritance_condition
assert_equal 10, Company.count
assert_equal 11, Company.count
assert_equal 2, Firm.count
assert_equal 4, Client.count
assert_equal 5, Client.count
end
def test_alt_inheritance_condition

View File

@ -57,3 +57,11 @@ odegy:
id: 9
name: Odegy
type: ExclusivelyDependentFirm
another_first_firm_client:
id: 11
type: Client
firm_id: 1
client_of: 1
name: Apex
firm_name: 37signals