Skip to content

Commit

Permalink
Adds support for models using compound primary keys
Browse files Browse the repository at this point in the history
  • Loading branch information
richardpenner committed Oct 3, 2024
1 parent 24a883f commit a16cdda
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 3 deletions.
22 changes: 19 additions & 3 deletions lib/identity_cache/cached/attribute.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,14 @@ def initialize(model, attribute_or_proc, alias_name, key_fields, unique)
end

def attribute
@attribute ||= @attribute_proc.call.to_sym
@attribute ||= begin
res = @attribute_proc.call
if res.is_a?(Array)
res.map(&:to_sym)
else
res.to_sym
end
end
end

def fetch(db_key)
Expand Down Expand Up @@ -59,7 +66,11 @@ def cache_key(index_key)
def load_one_from_db(key)
query = model.reorder(nil).where(load_from_db_where_conditions(key))
query = query.limit(1) if unique
results = query.pluck(attribute)
results = if attribute.is_a?(Array)
query.pluck(*attribute)
else
query.pluck(attribute)
end
unique ? results.first : results
end

Expand Down Expand Up @@ -138,10 +149,15 @@ def field_types

def cache_key_prefix
@cache_key_prefix ||= begin
attribute_key_prefix = if attribute.is_a?(Array)
attribute.join("/")
else
attribute.to_s
end
unique_indicator = unique ? "" : "s"
"attr#{unique_indicator}" \
":#{model.base_class.name}" \
":#{attribute}" \
":#{attribute_key_prefix}" \
":#{key_fields.join("/")}:"
end
end
Expand Down
12 changes: 12 additions & 0 deletions test/custom_primary_keys_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,23 @@ def setup
@parent_record = CustomParentRecord.create!(parent_primary_key: 1)
@child_record_1 = CustomChildRecord.create!(custom_parent_record: @parent_record, child_primary_key: 1)
@child_record_2 = CustomChildRecord.create!(custom_parent_record: @parent_record, child_primary_key: 2)

CompositePrimaryKeyRecord.cache_has_many(:custom_child_records)
CPKReference.cache_belongs_to(:composite_primary_key_record)
@composite_record = CompositePrimaryKeyRecord.create!(key_part_one: 1, key_part_two: 2)
@cpk_reference = CPKReference.create!(composite_primary_key_record: @composite_record)
end

def test_fetch_parent
assert_nothing_raised do
CustomParentRecord.fetch(@parent_record.parent_primary_key)
end
end

def test_fetch_composite_primary_key_record
assert_nothing_raised do
cpk_record = CompositePrimaryKeyRecord.fetch([@composite_record.key_part_one, @composite_record.key_part_two])
refute_nil cpk_record
end
end
end
2 changes: 2 additions & 0 deletions test/helpers/active_record_objects.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ def teardown_models
Object.send(:remove_const, "Deeply")
Object.send(:remove_const, "CustomParentRecord")
Object.send(:remove_const, "CustomChildRecord")
Object.send(:remove_const, "CompositePrimaryKeyRecord")
Object.send(:remove_const, "CPKReference")
IdentityCache.const_get(:ParentModelExpiration).send(:lazy_hooks).clear
end
end
11 changes: 11 additions & 0 deletions test/helpers/models.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,14 @@ class CustomChildRecord < ActiveRecord::Base
belongs_to :custom_parent_record, foreign_key: :parent_id
self.primary_key = "child_primary_key"
end

class CompositePrimaryKeyRecord < ActiveRecord::Base
include IdentityCache
has_many :cpk_references, foreign_key: [:key_part_one, :key_part_two]
self.primary_key = [:key_part_one, :key_part_two]
end

class CPKReference < ActiveRecord::Base
include IdentityCache
belongs_to :composite_primary_key_record, foreign_key: [:key_part_one, :key_part_two]
end

0 comments on commit a16cdda

Please sign in to comment.