Reputation: 555
I am looking for a simple solution here for the problem statement below:
I have a array of hashes like this:
arr = [
{group_id: 51, product_id: 34345},
{group_id: 45, product_id: 22133},
{group_id: 90, product_id: 10045},
{group_id: 2, product_id: 15495},
{group_id: 23, product_id: 25085}
]
I am running BULK INSERT
query based on the unique index of group_id
and product_id
like this:
GroupProduct.insert_all(arr, unique_by: %i[ group_id product_id ])
This insert statement throws error of ActiveRecord::InvalidForeignKey
sometimes:
PG::ForeignKeyViolation: ERROR: insert or update on table "group_products" violates foreign key constraint "fk_rails_a3bed1e3ad" DETAIL: Key (product_id)=(15495) is not present in table "group_products".
So, I would like to perform insert_all
operation inside begin-resuce
block such that, if a key product_id
is not found/present, it will rebuild the array and retry.
Basically, I would like to capture product_id
inside rescue block
Here's what I would like to accomplish:
arr = [
{group_id: 51, product_id: 34345},
{group_id: 45, product_id: 22133},
{group_id: 90, product_id: 10045},
{group_id: 2, product_id: 15495},
{group_id: 23, product_id: 25085}
]
begin
GroupProduct.insert_all(arr, unique_by: %i[ group_id product_id ])
rescue ActiveRecord::InvalidForeignKey => e
arr = arr.reject {|r| r[:product_id] == PRODUCT_ID_I_WOULD_LIKE_TO_CAPTURE}
retry
end
Is there a direct way of getting product_id
say e.message.product_id
?
Upvotes: 0
Views: 581
Reputation: 857
begin
GroupProduct.insert_all(arr, unique_by: %i[ group_id product_id ])
rescue ActiveRecord::InvalidForeignKey => e
match_on_product_it = /\APG::ForeignKeyViolation:.+\(product_id\)=\((\d+)\)/.match e.message
arr = arr.reject {|r| r[:product_id] == match_on_product_it[1].to_i}
retry
end
Upvotes: 1