MissingRangeKey when destroying associated objects
Let's say I've got two simple models:
class Company
include Dynamoid::Document
table name: :company,
key: :name,
capacity_mode: :on_demand
range :metadata
has_many :reports
end
class Report
include Dynamoid::Document
belongs_to :company
field :content
end
Now I'll create a company (c = Company.create(name: 'test', metadata 'COMPANY#CA#LOSANGELES')) and create an association with it (r = c.report.create(content: 'this is my report')). Works fine.
Now I want to delete the report, which will lead to an error: p.destroy /Users/me/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/dynamoid-3.7.0/lib/dynamoid/finders.rb:165:in _find_by_id': Dynamoid::Errors::MissingRangeKey (Dynamoid::Errors::MissingRangeKey). Same error when I call c.report.first.destroy`.
What happens in DynamoDB, the report in the reports table will be deleted, but not from the company table. Why? I guess it has to do with having a combined range key in the Company table, so you can't locate the parent object. But how do I supply the range key to the destroy function?
Yeah, you are right. Dynamoid doesn't support associations for tables with a compound primary key (that's with range key) right now. It isn't mentioned yet in the documentation - my bad.
Similar issue - https://github.com/Dynamoid/dynamoid/issues/472
Wouldn't it be possible to allow to supply the range key query optionally in the Model of the associated table? My range key is a begins_with selector, so that'd be easy.
It's an interesting idea but right now Dynanoid uses GetItem and BatchGetItem to load associated model/models (to delete them later) and it fails when the required range key is missing.
Just FYI, my current workaround is:
class Report
def destroy_recursive
# See https://github.com/Dynamoid/dynamoid/issues/501
c = Company.name(self.company_ids.first)
c.company_ids.delete(self.id)
c.save
self.destroy rescue nil # Avoid the range key error
end
end
Not pretty, but works.