Return default image url on ActiveStorage errors in image loading

This commit is contained in:
Matt-Yorkley
2023-06-09 16:07:42 +01:00
parent 4c7e947738
commit 5ad37ce6a5
7 changed files with 47 additions and 9 deletions

View File

@@ -15,6 +15,6 @@
.columns.small-12.medium-6.large-6.product-img
%img{"ng-src" => "{{::product.largeImage}}", "ng-if" => "::product.largeImage"}
%img.placeholder{ src: "/noimage/large.png", "ng-if" => "::!product.largeImage"}
%img.placeholder{ src: Spree::Image.default_image_url(:large), "ng-if" => "::!product.largeImage"}
%ng-include{src: "'partials/close.html'"}

View File

@@ -15,6 +15,12 @@ module Spree
content_type: %r{\Aimage/(png|jpeg|gif|jpg|svg\+xml|webp)\Z}
validate :no_attachment_errors
def self.default_image_url(size)
return "/noimage/product.png" unless size&.to_sym.in?([:mini, :small, :product, :large])
"/noimage/#{size}.png"
end
def variant(name)
if attachment.variable?
attachment.variant(name)
@@ -24,12 +30,18 @@ module Spree
end
def url(size)
return unless attachment.attached?
return self.class.default_image_url(size) unless attachment.attached?
return variant(size).processed.url if attachment.service.name == :amazon_public
url_for(variant(size))
rescue ActiveStorage::Error => e
Rails.logger.error(e.message)
self.class.default_image_url(size)
end
private
# if there are errors from the plugin, then add a more meaningful message
def no_attachment_errors
return if errors[:attachment].empty?

View File

@@ -27,11 +27,11 @@ module Api
end
def image_url
object.images.first&.url(:product) || "/noimage/product.png"
object.images.first&.url(:product) || Spree::Image.default_image_url(:product)
end
def thumb_url
object.images.first&.url(:mini) || "/noimage/mini.png"
object.images.first&.url(:mini) || Spree::Image.default_image_url(:mini)
end
def on_hand

View File

@@ -40,7 +40,7 @@ class Api::VariantSerializer < ActiveModel::Serializer
end
def thumb_url
object.product.images.first&.url(:mini) || "/noimage/mini.png"
object.product.images.first&.url(:mini) || Spree::Image.default_image_url(:mini)
end
def unit_price_price

View File

@@ -99,7 +99,7 @@
%fieldset.no-border-bottom{ id: "image" }
%legend{align: "center"}= t(".image")
.row
= image_tag "/noimage/product.png", class: "four columns alpha"
= image_tag Spree::Image.default_image_url(:product), class: "four columns alpha"
.row
= f.fields_for 'images_attributes[]', f.object.images.build do |image_fields|
= image_fields.file_field :attachment

View File

@@ -1 +1 @@
= image_tag(variant.product.images.first&.url(:mini) || "/noimage/mini.png")
= image_tag(variant.product.images.first&.url(:mini) || Spree::Image.default_image_url(:mini))

View File

@@ -31,10 +31,36 @@ module Spree
)
end
it "returns nil when the attachment is missing" do
it "returns default image when the attachment is missing" do
subject.attachment = nil
expect(subject.url(:small)).to eq nil
expect(subject.url(:small)).to eq "/noimage/small.png"
end
context "when no image attachment is found" do
it "returns a default product image" do
expect(subject).to receive_message_chain(:attachment, :attached?) { false }
expect(subject.url(:mini)).to eq "/noimage/mini.png"
end
end
context "when accessing the image raises an ActiveStorage error" do
it "rescues the error and returns a default product image" do
expect(subject).to receive(:attachment) { raise ActiveStorage::FileNotFoundError }
expect(subject.url(:small)).to eq "/noimage/small.png"
end
end
end
describe "#default_image_url" do
it "returns default product image for a given size" do
expect(subject.class.default_image_url(:mini)).to eq "/noimage/mini.png"
end
it "returns default product image when no size is given" do
expect(subject.class.default_image_url(nil)).to eq "/noimage/product.png"
end
end