Shopify / Shopify/identity_cache
should inverse_of work?
Nobody has claimed this yet.
- Dominant language
- Ruby
- Stars
- 2k
- Forks
- 174
- Avg merge
- 13m
- Merged PRs (30d)
- 3
Description
Not sure if it's a misconfiguration on my side or if it's simply not supported.
Rails 5.1.4
identity_cache 0.5.1
Given:
class Person < ActiveRecord::Base
include IdentityCache
belongs_to :client, inverse_of: :persons
cache_belongs_to :client
end
class Client < ActiveRecord::Base
include IdentityCache
has_many :persons, -> { where partner_id: nil }, dependent: :destroy, inverse_of: :client
cache_has_many :persons
end
Without the cache the client isn't fetched again when we fetch persons on a client:
irb(main):002:0> client = Client.find(4)
Client Load (0.5ms) SELECT `clients`.* FROM `clients` WHERE `clients`.`id` = 4 LIMIT 1
=> #<Client id: 4, name: .... >
irb(main):003:0> client.persons.map{|p| p.client.object_id}
Person Load (0.7ms) SELECT `persons`.* FROM `persons` WHERE `persons`.`deleted_at` IS NULL AND `persons`.`client_id` = 4 AND `persons`.`partner_id` IS NULL
=> [70220559135500, 70220559135500, 70220559135500, 70220559135500, 70220559135500, 70220559135500, 70220559135500, 70220559135500]
With IdentityCache I get a client query for every person and different objects. Shouldn't IdentityCache simply setup the association to the existing client object?
irb(main):002:0> client = Client.find(4)
Client Load (0.5ms) SELECT `clients`.* FROM `clients` WHERE `clients`.`id` = 4 LIMIT 1
=> #<Client id: 4, name: .... >
irb(main):002:0> client.fetch_persons.map{|p| p.client.object_id}
(1.2ms) SELECT `persons`.`id` FROM `persons` WHERE `persons`.`deleted_at` IS NULL AND `persons`.`client_id` = 4 AND `persons`.`partner_id` IS NULL
Cache cas_multi: greenlight:1:IDC:7:blob:Person:7919784493729940308:9/IDC:7:blob:Person:7919784493729940308:10/IDC:7:blob:Person:7919784493729940308:11/IDC:7:blob:Person:7919784493729940308:3459/IDC:7:blob:Person:79197844937299403:md5:1e1faf6c2624ebf80c00411dbf35dcc9 ({:namespace=>"greenlight:1", :expires_in=>21600})
Person Load (0.8ms) SELECT `persons`.* FROM `persons` WHERE `persons`.`deleted_at` IS NULL AND `persons`.`id` IN (9, 10, 11, 3459, 4135, 4147, 4312, 4458)
Cache write: greenlight:1:IDC:7:blob:Person:7919784493729940308:9 ({:namespace=>"greenlight:1", :expires_in=>21600, :unless_exist=>true})
Cache write: greenlight:1:IDC:7:blob:Person:7919784493729940308:10 ({:namespace=>"greenlight:1", :expires_in=>21600, :unless_exist=>true})
Cache write: greenlight:1:IDC:7:blob:Person:7919784493729940308:11 ({:namespace=>"greenlight:1", :expires_in=>21600, :unless_exist=>true})
Cache write: greenlight:1:IDC:7:blob:Person:7919784493729940308:3459 ({:namespace=>"greenlight:1", :expires_in=>21600, :unless_exist=>true})
Cache write: greenlight:1:IDC:7:blob:Person:7919784493729940308:4135 ({:namespace=>"greenlight:1", :expires_in=>21600, :unless_exist=>true})
Cache write: greenlight:1:IDC:7:blob:Person:7919784493729940308:4147 ({:namespace=>"greenlight:1", :expires_in=>21600, :unless_exist=>true})
Cache write: greenlight:1:IDC:7:blob:Person:7919784493729940308:4312 ({:namespace=>"greenlight:1", :expires_in=>21600, :unless_exist=>true})
Cache write: greenlight:1:IDC:7:blob:Person:7919784493729940308:4458 ({:namespace=>"greenlight:1", :expires_in=>21600, :unless_exist=>true})
[IdentityCache] cache miss for IDC:7:blob:Person:7919784493729940308:9 (multi)
[IdentityCache] cache miss for IDC:7:blob:Person:7919784493729940308:10 (multi)
[IdentityCache] cache miss for IDC:7:blob:Person:7919784493729940308:11 (multi)
[IdentityCache] cache miss for IDC:7:blob:Person:7919784493729940308:3459 (multi)
[IdentityCache] cache miss for IDC:7:blob:Person:7919784493729940308:4135 (multi)
[IdentityCache] cache miss for IDC:7:blob:Person:7919784493729940308:4147 (multi)
[IdentityCache] cache miss for IDC:7:blob:Person:7919784493729940308:4312 (multi)
[IdentityCache] cache miss for IDC:7:blob:Person:7919784493729940308:4458 (multi)
Client Load (0.6ms) SELECT `clients`.* FROM `clients` WHERE `clients`.`id` = 4 LIMIT 1
Client Load (0.5ms) SELECT `clients`.* FROM `clients` WHERE `clients`.`id` = 4 LIMIT 1
Client Load (0.6ms) SELECT `clients`.* FROM `clients` WHERE `clients`.`id` = 4 LIMIT 1
Client Load (0.5ms) SELECT `clients`.* FROM `clients` WHERE `clients`.`id` = 4 LIMIT 1
Client Load (0.6ms) SELECT `clients`.* FROM `clients` WHERE `clients`.`id` = 4 LIMIT 1
Client Load (0.5ms) SELECT `clients`.* FROM `clients` WHERE `clients`.`id` = 4 LIMIT 1
Client Load (0.5ms) SELECT `clients`.* FROM `clients` WHERE `clients`.`id` = 4 LIMIT 1
Client Load (0.5ms) SELECT `clients`.* FROM `clients` WHERE `clients`.`id` = 4 LIMIT 1
=> [70220565335420, 70220557688780, 70220557994400, 70220558006100, 70220589297320, 70220589903960, 70220589965920, 70220560291960]
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the reported behavior with the Person and Client associations, including inverse_of, cache_belongs_to, cache_has_many, and fetch_persons. Trace the association-loading and cache-fetch paths, then add coverage for object identity and repeated Client queries. Done means the expected inverse association behavior is documented and verified by tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rails, ruby
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100