From 84ac15c68f8b6b4a54f0d022652979c98e067b4f Mon Sep 17 00:00:00 2001 From: Alex Schmitt Date: Wed, 22 Sep 2021 16:13:48 -0700 Subject: [PATCH 1/3] Update `image?` check for ActiveStorage fields [Lookup the type ](https://apidock.com/rails/v6.0.0/Mime/Type/lookup_by_extension/class)via the [extension](https://apidock.com/rails/ActiveStorage/Filename/extension_without_delimiter), and match against 'image' types. Rails provides a way to register custom mime types, allowing additional 'image' types to [be added to an Rails application](https://guides.rubyonrails.org/action_controller_overview.html#restful-downloads) without needing to maintain a list of specific filename extensions in `rails_admin` --- lib/rails_admin/config/fields/types/active_storage.rb | 3 ++- lib/rails_admin/config/fields/types/multiple_active_storage.rb | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/rails_admin/config/fields/types/active_storage.rb b/lib/rails_admin/config/fields/types/active_storage.rb index 3dafb4c6ea..d0ce0966c2 100644 --- a/lib/rails_admin/config/fields/types/active_storage.rb +++ b/lib/rails_admin/config/fields/types/active_storage.rb @@ -17,7 +17,8 @@ class ActiveStorage < RailsAdmin::Config::Fields::Types::FileUpload register_instance_option :image? do if value - value.filename.to_s.split('.').last =~ /jpg|jpeg|png|gif|svg/i + mime_type = Mime::Type.lookup_by_extension(value.filename.extension_without_delimiter) + mime_type.to_s.match?(/^image/) end end diff --git a/lib/rails_admin/config/fields/types/multiple_active_storage.rb b/lib/rails_admin/config/fields/types/multiple_active_storage.rb index 9cc59caa6b..d049d2868f 100644 --- a/lib/rails_admin/config/fields/types/multiple_active_storage.rb +++ b/lib/rails_admin/config/fields/types/multiple_active_storage.rb @@ -18,7 +18,8 @@ class ActiveStorageAttachment < RailsAdmin::Config::Fields::Types::MultipleFileU register_instance_option :image? do if value - value.filename.to_s.split('.').last =~ /jpg|jpeg|png|gif|svg/i + mime_type = Mime::Type.lookup_by_extension(value.filename.extension_without_delimiter) + mime_type.to_s.match?(/^image/) end end From d9a7db320fcd1cb055b11dc8725d6b825ca60c30 Mon Sep 17 00:00:00 2001 From: Alex Schmitt Date: Wed, 22 Sep 2021 16:36:40 -0700 Subject: [PATCH 2/3] Update #image? for remaining file upload field types --- lib/rails_admin/config/fields/types/dragonfly.rb | 3 ++- lib/rails_admin/config/fields/types/file_upload.rb | 3 ++- lib/rails_admin/config/fields/types/multiple_file_upload.rb | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/rails_admin/config/fields/types/dragonfly.rb b/lib/rails_admin/config/fields/types/dragonfly.rb index e324b40dcf..9ff23da100 100644 --- a/lib/rails_admin/config/fields/types/dragonfly.rb +++ b/lib/rails_admin/config/fields/types/dragonfly.rb @@ -12,7 +12,8 @@ class Dragonfly < RailsAdmin::Config::Fields::Types::FileUpload register_instance_option :image? do false unless value if abstract_model.model.new.respond_to?("#{name}_name") - bindings[:object].send("#{name}_name").to_s.split('.').last =~ /jpg|jpeg|png|gif/i + mime_type = Mime::Type.lookup_by_extension(bindings[:object].send("#{name}_name").to_s.split('.').last) + mime_type.to_s.match?(/^image/) else true # Dragonfly really is image oriented end diff --git a/lib/rails_admin/config/fields/types/file_upload.rb b/lib/rails_admin/config/fields/types/file_upload.rb index 2c8947442d..e955185ee6 100644 --- a/lib/rails_admin/config/fields/types/file_upload.rb +++ b/lib/rails_admin/config/fields/types/file_upload.rb @@ -50,7 +50,8 @@ class FileUpload < RailsAdmin::Config::Fields::Base end register_instance_option :image? do - (url = resource_url.to_s) && url.split('.').last =~ /jpg|jpeg|png|gif|svg/i + mime_type = Mime::Type.lookup_by_extension(resource_url.to_s.split('.').last) + mime_type.to_s.match?(/^image/) end register_instance_option :allowed_methods do diff --git a/lib/rails_admin/config/fields/types/multiple_file_upload.rb b/lib/rails_admin/config/fields/types/multiple_file_upload.rb index 5bfb586a1c..b6f734038a 100644 --- a/lib/rails_admin/config/fields/types/multiple_file_upload.rb +++ b/lib/rails_admin/config/fields/types/multiple_file_upload.rb @@ -45,7 +45,8 @@ def initialize(value) end register_instance_option :image? do - (url = resource_url.to_s) && url.split('.').last =~ /jpg|jpeg|png|gif|svg/i + mime_type = Mime::Type.lookup_by_extension(resource_url.to_s.split('.').last) + mime_type.to_s.match?(/^image/) end def resource_url(_thumb = false) From 7691afd0be54e1e4f0c168f1ee6660cb0add9052 Mon Sep 17 00:00:00 2001 From: Alex Schmitt Date: Sun, 26 Sep 2021 10:40:02 -0700 Subject: [PATCH 3/3] Update ActiveStorage field #image? spec to account for configured types `webp` is not currently a default configured image Mime::Type in Rails, so this includes a check where the application can register a type and RailsAdmin will render it accordingly. This updates existing coverage as well to test against common image file types. --- .../config/fields/types/active_storage_spec.rb | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/spec/rails_admin/config/fields/types/active_storage_spec.rb b/spec/rails_admin/config/fields/types/active_storage_spec.rb index 391d204235..47ff5feff9 100644 --- a/spec/rails_admin/config/fields/types/active_storage_spec.rb +++ b/spec/rails_admin/config/fields/types/active_storage_spec.rb @@ -17,11 +17,18 @@ end describe '#image?' do - context 'when attachment is an image' do - let(:record) { FactoryBot.create :field_test, active_storage_asset: {io: StringIO.new('dummy'), filename: "test.jpg", content_type: "image/jpeg"} } - - it 'returns true' do - expect(field.image?).to be_truthy + context 'configured Mime::Types' do + before { Mime::Type.register 'image/webp', :webp } + after { Mime::Type.unregister :webp } + + %w[jpg jpeg png gif svg webp].each do |image_type_ext| + context "when attachment is a '#{image_type_ext}' file" do + let(:record) { FactoryBot.create :field_test, active_storage_asset: {io: StringIO.new('dummy'), filename: "test.#{image_type_ext}"} } + + it 'returns true' do + expect(field.image?).to be_truthy + end + end end end