How to get the default extension for a given content type?

MimeMagic

In addition to the above answers, I personally like using MimeMagic.

require 'mimemagic'
MimeMagic.new('image/jpeg').extensions.first #=> 'jpg'
# Note that this does not include the dot (.) in the extension.

TL;DR;

Other possible useful functions of MimeMagic

MimeMagic.new('image/jpeg').image? #=> true
MimeMagic.by_magic('<?xml version="1.0" ?><test></test>').type #=> 'application/xml'
MimeMagic.by_extension('.html').type #=> 'text/html'

I recently moved from Rack::Mime to MimeMagic because I also try to detect from file content what the Mime Type is. To make sure this is reverse compatible, I need to use MM for all directions of conversion:

  • content > Mime Type
  • Mime Type > Extension
  • Extension > Mime Type

Different results

The main reason why I switched was a difference when translating application/xml to an extension:

MimeMagic.new('application/xml').extensions #=> ["xml", "xbl", "xsd", "rng"]
Rack::Mime::MIME_TYPES.invert['application/xml'] #=> ".xsl"

So suddenly I saw some xml files being saved with an .xsl extension.


All you need to is use ruby's Hash.invert method.

This answer shows how to do it:

Rack::Mime has this ability (and Rack is a dependency of Rails):

require 'rack/mime'
Rack::Mime::MIME_TYPES.invert['image/jpeg']  #=> ".jpg"

You may wish to memoize the inverted hash if you’re going to do the lookup often, as it’s not an inexpensive operation.

From your tags, it seems you are using rails anyway.


Your second solution with the mime type is the solution, which you should choose. There are several reasons for that:

  • The second solution is exactly designed for your use case
  • Hack the string could be inconsistent or return unexpected results (think about application/postscript has the extension eps!)
  • Please consider, that we probably can't say, that every mime type has it's default extension. For example: who has defined the default extension for jpg (or jpeg or JPG..) images?