Skip to content

Commit

Permalink
Allow prefetch_associations on association that was prefetched before
Browse files Browse the repository at this point in the history
  • Loading branch information
kirs committed Feb 15, 2024
1 parent d1e53f7 commit 9deb4d7
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 9 deletions.
22 changes: 13 additions & 9 deletions lib/identity_cache/cached/belongs_to.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,20 @@ def fetch_async(load_strategy, records)
end
end

load_strategy.load_multi(
reflection.klass.cached_primary_index,
ids_to_owner_record.keys
) do |associated_records_by_id|
associated_records_by_id.each do |id, associated_record|
owner_record = ids_to_owner_record.fetch(id)
write(owner_record, associated_record)
end
if ids_to_owner_record.keys.any?
load_strategy.load_multi(
reflection.klass.cached_primary_index,
ids_to_owner_record.keys
) do |associated_records_by_id|
associated_records_by_id.each do |id, associated_record|
owner_record = ids_to_owner_record.fetch(id)
write(owner_record, associated_record)
end

yield associated_records_by_id.values.compact
yield associated_records_by_id.values.compact
end
else
yield records.filter_map { |record| record.instance_variable_get(records_variable_name) }
end
end
end
Expand Down
33 changes: 33 additions & 0 deletions test/prefetch_associations_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,39 @@ def test_fetch_multi_batch_fetches_first_level_associations_who_dont_include_ide
end
end

def test_fetch_multi_batch_fetches_non_embedded_second_level_belongs_to_associations_in_repeating_prefetch
Item.send(:cache_belongs_to, :item)
AssociatedRecord.send(:cache_belongs_to, :item)

@bob_child = @bob.associated_records.create!(name: "bob child")
@fred_child = @fred.associated_records.create!(name: "fred child")
@bob.update_attribute(:item_id, @bob.id)
@fred.update_attribute(:item_id, @fred.id)

# populate the cache entries and associated children ID variables
AssociatedRecord.fetch_multi(@bob_child.id, @fred_child.id)
Item.fetch_multi(@bob.id, @fred.id)

assert_memcache_operations(2) do
@cached_bob_child, @cached_fred_child = AssociatedRecord.fetch_multi(
@bob_child.id, @fred_child.id, includes: [:item]
)
end

assert_memcache_operations(1) do
AssociatedRecord.prefetch_associations({ item: :item }, [@cached_bob_child, @cached_fred_child])
end

assert_queries(0) do
assert_memcache_operations(0) do
@cached_bob_parent = @cached_bob_child.fetch_item
@cached_fred_parent = @cached_fred_child.fetch_item
assert_equal(@bob, @cached_bob_parent.fetch_item)
assert_equal(@fred, @cached_fred_parent.fetch_item)
end
end
end

def test_fetch_multi_batch_fetches_non_embedded_second_level_has_many_associations
Item.send(:cache_has_many, :associated_records, embed: :ids)
AssociatedRecord.send(:cache_has_many, :deeply_associated_records, embed: :ids)
Expand Down

0 comments on commit 9deb4d7

Please sign in to comment.