mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
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:
parent
8a5fe2bcde
commit
934fccd522
5 changed files with 95 additions and 3 deletions
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
# Provides asynchronous purging of ActiveStorage::Blob records via ActiveStorage::Blob#purge_later.
|
# Provides asynchronous purging of ActiveStorage::Blob records via ActiveStorage::Blob#purge_later.
|
||||||
class ActiveStorage::PurgeJob < ActiveStorage::BaseJob
|
class ActiveStorage::PurgeJob < ActiveStorage::BaseJob
|
||||||
discard_on ActiveRecord::RecordNotFound, ActiveRecord::InvalidForeignKey
|
discard_on ActiveRecord::RecordNotFound
|
||||||
|
|
||||||
def perform(blob)
|
def perform(blob)
|
||||||
blob.purge
|
blob.purge
|
||||||
|
|
|
@ -207,6 +207,7 @@ class ActiveStorage::Blob < ActiveRecord::Base
|
||||||
def purge
|
def purge
|
||||||
destroy
|
destroy
|
||||||
delete
|
delete
|
||||||
|
rescue ActiveRecord::InvalidForeignKey
|
||||||
end
|
end
|
||||||
|
|
||||||
# Enqueues an ActiveStorage::PurgeJob to call #purge. This is the recommended way to purge blobs from a transaction,
|
# Enqueues an ActiveStorage::PurgeJob to call #purge. This is the recommended way to purge blobs from a transaction,
|
||||||
|
|
|
@ -468,6 +468,33 @@ class ActiveStorage::ManyAttachedTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
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
|
test "purging later" do
|
||||||
[ create_blob(filename: "funky.jpg"), create_blob(filename: "town.jpg") ].tap do |blobs|
|
[ create_blob(filename: "funky.jpg"), create_blob(filename: "town.jpg") ].tap do |blobs|
|
||||||
@user.highlights.attach blobs
|
@user.highlights.attach blobs
|
||||||
|
@ -485,6 +512,35 @@ class ActiveStorage::ManyAttachedTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
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
|
test "purging dependent attachment later on destroy" do
|
||||||
[ create_blob(filename: "funky.jpg"), create_blob(filename: "town.jpg") ].tap do |blobs|
|
[ create_blob(filename: "funky.jpg"), create_blob(filename: "town.jpg") ].tap do |blobs|
|
||||||
@user.highlights.attach blobs
|
@user.highlights.attach blobs
|
||||||
|
|
|
@ -412,6 +412,22 @@ class ActiveStorage::OneAttachedTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
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
|
test "purging later" do
|
||||||
create_blob(filename: "funky.jpg").tap do |blob|
|
create_blob(filename: "funky.jpg").tap do |blob|
|
||||||
@user.avatar.attach blob
|
@user.avatar.attach blob
|
||||||
|
@ -427,6 +443,25 @@ class ActiveStorage::OneAttachedTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
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
|
test "purging dependent attachment later on destroy" do
|
||||||
create_blob(filename: "funky.jpg").tap do |blob|
|
create_blob(filename: "funky.jpg").tap do |blob|
|
||||||
@user.avatar.attach blob
|
@user.avatar.attach blob
|
||||||
|
|
|
@ -174,10 +174,10 @@ class ActiveStorage::BlobTest < ActiveSupport::TestCase
|
||||||
assert_not ActiveStorage::Blob.service.exist?(variant.key)
|
assert_not ActiveStorage::Blob.service.exist?(variant.key)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "purge fails when attachments exist" do
|
test "purge does nothing when attachments exist" do
|
||||||
create_blob.tap do |blob|
|
create_blob.tap do |blob|
|
||||||
User.create! name: "DHH", avatar: 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)
|
assert ActiveStorage::Blob.service.exist?(blob.key)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue