Shopify / Shopify/identity_cache
IdentityCache in combination with module causes "undefined method `all'"
Nobody has claimed this yet.
- Dominant language
- Ruby
- Stars
- 2k
- Forks
- 174
- Avg merge
- 13m
- Merged PRs (30d)
- 3
Description
Hi,
Thanks for developing this, it's neat (when it works ;)).
Recently I encountered a rather peculiar bug that I eventually traced down to IdentityCache.
At one point my code looked like this:
class Card < Identifiable
cache_index :card, unique: :true
belongs_to :employee, inverse_of: :cards
cache_belongs_to :employee
validates_associated :employee
validates :employee, presence: true
end
class PlateOwner < ApplicationRecord
self.abstract_class = true
include IdentityCache
acts_as_paranoid
end
class Numberplate < Identifiable
cache_index :plate, unique: :true
belongs_to :plate_owner, -> { with_deleted }, polymorphic: true, inverse_of: :numberplates
cache_belongs_to :plate_owner
validates_associated :plate_owner
validates :plate_owner, presence: true
end
I then refactored it to use concerns rather than using inheritance for identifiable. After the refactor, my code looked like this:
class Card < ApplicationRecord
include Identifiable
cache_index :card, unique: :true
belongs_to :employee, inverse_of: :cards
cache_belongs_to :employee
validates_associated :employee
validates :employee, presence: true
end
module Identifiable
extend ActiveSupport::Concern
included do
include IdentityCache
acts_as_paranoid
has_many :events, as: :identifiable, inverse_of: :identifiable
cache_has_many :events, embed: true
end
module ClassMethods
end
end
class Numberplate < ApplicationRecord
include Identifiable
cache_index :plate, unique: :true
belongs_to :plate_owner, -> { with_deleted }, polymorphic: true, inverse_of: :numberplates
cache_belongs_to :plate_owner
validates_associated :plate_owner
validates :plate_owner, presence: true
end
Then things went south. I started to get very weird errors like
undefined method all' for Identifiable:Module` when saving a new Card for instance.
Here's a stack trace:
app/controllers/cards_controller.rb:34:in `block in create'
app/controllers/cards_controller.rb:33:in `create'
app/controllers/application_controller.rb:22:in `block in identity_cache_memoization'
app/controllers/application_controller.rb:22:in `identity_cache_memoization'
It took quite some time to pinpoint the issue being caused by IdentityCache in combination with the new module. I'm not sure what's actually causing it, but no longer including identity cache in my code solves the problem for me.
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
Reproduce the reported Card and Numberplate setup using the IdentityCache and Identifiable examples, then follow the failure from app/controllers/cards_controller.rb and app/controllers/application_controller.rb. Inspect the interaction between the included module and IdentityCache while saving a new Card; done means the save no longer raises undefined method `all' for Identifiable:Module and the regression is covered by a test.
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
- Needs clarification
- Newbie friendliness
- 30/100