Scenario
There is an existing Invoice
model in the application.
A new column is being introduced to add a Reference.
We must backfill all existing Invoices with a Reference.
Upsert all
Attempt to backfill using upsert_all
.
We want to update only the reference
column on all Invoices, but leave all other columns untouched.
invoices = Invoice.where(reference: nil)
invoice_ids = invoices.pluck(:id)
upsert_attrs = invoice_ids.map do |invoice_id|
{id: invoice_id, reference: generate_reference}
end
invoices.upsert_all(upsert_attrs, unique_by: :id)
This code produces an error of No unique index found for id
Expected
Before backfilling
id | amount | paid | notes | reference |
---|---|---|---|---|
1 | 100.00 | true | Â | Â |
2 | 200.00 | true | Returned | Â |
3 | 500.00 | false | Due end of month | Â |
After backfilling
id | amount | paid | notes | reference |
---|---|---|---|---|
1 | 100.00 | true | Â | X122791 |
2 | 200.00 | true | Returned | AC12911 |
3 | 500.00 | false | Due end of month | ABI1000 |
Thoughts
It is unclear if this code block should work or if this is not the intended use case for upsert_all
.
It could be an older issue on Rails 6.0.