Ignore ActiveRecord::InvalidForeignKey in ActiveStorage::Blob#purge

Do nothing instead of raising an error when it’s called on an attached blob.
This commit is contained in:
Jasper Martin 2018-07-26 21:24:31 +08:00 committed by George Claghorn
parent 8a5fe2bcde
commit 934fccd522
5 changed files with 95 additions and 3 deletions

View File

@ -2,7 +2,7 @@
# Provides asynchronous purging of ActiveStorage::Blob records via ActiveStorage::Blob#purge_later.
class ActiveStorage::PurgeJob < ActiveStorage::BaseJob
discard_on ActiveRecord::RecordNotFound, ActiveRecord::InvalidForeignKey
discard_on ActiveRecord::RecordNotFound
def perform(blob)
blob.purge

View File

@ -207,6 +207,7 @@ class ActiveStorage::Blob < ActiveRecord::Base
def purge
destroy
delete
rescue ActiveRecord::InvalidForeignKey
end
# Enqueues an ActiveStorage::PurgeJob to call #purge. This is the recommended way to purge blobs from a transaction,

View File

@ -468,6 +468,33 @@ class ActiveStorage::ManyAttachedTest < ActiveSupport::TestCase
end
end
test "purging attachment with shared blobs" do
[
create_blob(filename: "funky.jpg"),
create_blob(filename: "town.jpg"),
create_blob(filename: "worm.jpg")
].tap do |blobs|
@user.highlights.attach blobs
assert @user.highlights.attached?
another_user = User.create!(name: "John")
shared_blobs = [blobs.second, blobs.third]
another_user.highlights.attach shared_blobs
assert another_user.highlights.attached?
@user.highlights.purge
assert_not @user.highlights.attached?
assert_not ActiveStorage::Blob.exists?(blobs.first.id)
assert ActiveStorage::Blob.exists?(blobs.second.id)
assert ActiveStorage::Blob.exists?(blobs.third.id)
assert_not ActiveStorage::Blob.service.exist?(blobs.first.key)
assert ActiveStorage::Blob.service.exist?(blobs.second.key)
assert ActiveStorage::Blob.service.exist?(blobs.third.key)
end
end
test "purging later" do
[ create_blob(filename: "funky.jpg"), create_blob(filename: "town.jpg") ].tap do |blobs|
@user.highlights.attach blobs
@ -485,6 +512,35 @@ class ActiveStorage::ManyAttachedTest < ActiveSupport::TestCase
end
end
test "purging attachment later with shared blobs" do
[
create_blob(filename: "funky.jpg"),
create_blob(filename: "town.jpg"),
create_blob(filename: "worm.jpg")
].tap do |blobs|
@user.highlights.attach blobs
assert @user.highlights.attached?
another_user = User.create!(name: "John")
shared_blobs = [blobs.second, blobs.third]
another_user.highlights.attach shared_blobs
assert another_user.highlights.attached?
perform_enqueued_jobs do
@user.highlights.purge_later
end
assert_not @user.highlights.attached?
assert_not ActiveStorage::Blob.exists?(blobs.first.id)
assert ActiveStorage::Blob.exists?(blobs.second.id)
assert ActiveStorage::Blob.exists?(blobs.third.id)
assert_not ActiveStorage::Blob.service.exist?(blobs.first.key)
assert ActiveStorage::Blob.service.exist?(blobs.second.key)
assert ActiveStorage::Blob.service.exist?(blobs.third.key)
end
end
test "purging dependent attachment later on destroy" do
[ create_blob(filename: "funky.jpg"), create_blob(filename: "town.jpg") ].tap do |blobs|
@user.highlights.attach blobs

View File

@ -412,6 +412,22 @@ class ActiveStorage::OneAttachedTest < ActiveSupport::TestCase
end
end
test "purging an attachment with a shared blob" do
create_blob(filename: "funky.jpg").tap do |blob|
@user.avatar.attach blob
assert @user.avatar.attached?
another_user = User.create!(name: "John")
another_user.avatar.attach blob
assert another_user.avatar.attached?
@user.avatar.purge
assert_not @user.avatar.attached?
assert ActiveStorage::Blob.exists?(blob.id)
assert ActiveStorage::Blob.service.exist?(blob.key)
end
end
test "purging later" do
create_blob(filename: "funky.jpg").tap do |blob|
@user.avatar.attach blob
@ -427,6 +443,25 @@ class ActiveStorage::OneAttachedTest < ActiveSupport::TestCase
end
end
test "purging an attachment later with shared blob" do
create_blob(filename: "funky.jpg").tap do |blob|
@user.avatar.attach blob
assert @user.avatar.attached?
another_user = User.create!(name: "John")
another_user.avatar.attach blob
assert another_user.avatar.attached?
perform_enqueued_jobs do
@user.avatar.purge_later
end
assert_not @user.avatar.attached?
assert ActiveStorage::Blob.exists?(blob.id)
assert ActiveStorage::Blob.service.exist?(blob.key)
end
end
test "purging dependent attachment later on destroy" do
create_blob(filename: "funky.jpg").tap do |blob|
@user.avatar.attach blob

View File

@ -174,10 +174,10 @@ class ActiveStorage::BlobTest < ActiveSupport::TestCase
assert_not ActiveStorage::Blob.service.exist?(variant.key)
end
test "purge fails when attachments exist" do
test "purge does nothing when attachments exist" do
create_blob.tap do |blob|
User.create! name: "DHH", avatar: blob
assert_raises(ActiveRecord::InvalidForeignKey) { blob.purge }
assert_no_difference(-> { ActiveStorage::Blob.count }) { blob.purge }
assert ActiveStorage::Blob.service.exist?(blob.key)
end
end