Authenticating user-selectable mimetypes

I’d like to let users select mime-types they’ll accept in the uploader. I’ve added a DataType model which I want to query a list of selected mimetypes from, and then validate using this list. The trouble is, the list of accepted datatypes doesn’t keep up with records added by users.

When I restart the server, the list is updated. Here’s my uploader

 class PhotoUploader < Shrine
	ALLOWED_TYPES = DataType.all.map{|d| d.mimetype}
	MAX_SIZE       = 10*1024*1024 # 10 MB

  plugin :remove_attachment
  plugin :validation_helpers
  plugin :store_dimensions, log_subscriber: nil

  Attacher.validate do
    validate_size 0..MAX_SIZE
    if validate_mime_type ALLOWED_TYPES
    end
  end
end

Is there a better way to do this?

The trouble is, the list of accepted datatypes doesn’t keep up with records added by users.

Can you elaborate a little more on this point?

Good point, after reading my question I have to admit, that was pretty weak.

Im noticing that the uploader doesn’t pull the most recent list of accepted datatypes from the DataType model. For example: in testing I added application/msword as the only accepted FileType. Then when testing the upload form, the results were as expected. All files except .doc were rejected.

Then I added a few other options to the FileType model(application/pdf and application/vnd.ms-excel). Then when I try to upload an .xls file I get the following error:

Attachments file type must be one of: application/msword

Here’s the output for FileType.all

[#<FileType:0x00007fd6c2a0dfe8
  id: 5,
  extension: ".doc",
  mimetype: "application/msword",
  slug: "application-msword",
  created_at: Wed, 08 Jul 2020 20:19:53 UTC +00:00,
  updated_at: Wed, 08 Jul 2020 20:19:53 UTC +00:00>,
 #<FileType:0x00007fd6c2a0de80
  id: 8,
  extension: ".xls",
  mimetype: "application/vnd.ms-excel",
  slug: "application-vnd-ms-excel",
  created_at: Fri, 10 Jul 2020 16:58:00 UTC +00:00,
  updated_at: Fri, 10 Jul 2020 16:58:00 UTC +00:00>,
 #<FileType:0x00007fd6c2a0ddb8
  id: 9,
  extension: ".xlsx",
  mimetype:
   "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  slug: "application-vnd-openxmlformats-officedocument-spreadsheetml-sheet",
  created_at: Fri, 10 Jul 2020 16:58:07 UTC +00:00,
  updated_at: Fri, 10 Jul 2020 16:58:07 UTC +00:00>]

It seems like the uploader is the wrong place to fetch a list of accepted mimetypes from the database. Is there somewhere I can place the validator which will pull an up to date list of accepted mimetypes from the database?

ALLOWED_TYPES is set to a constant in Ruby, isn’t it? If that that’s the case, I’m not sure how and when ruby constants are loaded and reloaded given you will constantly be updating DataTypes - but I would probably not use a ruby constant.

Is it possible for you just to run the query each time (don’t use the ruby constant) i.e. something like this:

 Attacher.validate do
    validate_size 0..MAX_SIZE
    if validate_mime_type DataType.all.pluck(:mimetype) # not using ruby constant here
    end
  end