9

In my Rails app I'm trying to get the MIME type of a file like so:

MIME::Types.type_for("example.m4v").to_s

But it's not recognizing it.

I tried adding the following to config/initializers/mime_types.rb (and restarted the server) without any luck:

Mime::Type.register "video/mp4", :m4v

Shpigford
  • 24,748
  • 58
  • 163
  • 252
  • What does `it's not recognizing it` means? – Dmytrii Nagirniak Mar 10 '10 at 05:31
  • Meaning nothing is returned when I do `type_for` as in my example above. Other extensions (.mov, .mp3, etc) return the type fine. – Shpigford Mar 10 '10 at 05:38
  • Have your sure that mime-type is send by your browser ? Because if it's not send by your browser, you can't use it in your Rails APP – shingara Mar 10 '10 at 08:01
  • My initial example works fine for pretty much any other extension. Again, if I change my example file name above to "example.mov" then that `type_for` returns `video/quicktime`...I just need to add a custom MIME type but can't figure out how to do that. – Shpigford Mar 10 '10 at 15:09

2 Answers2

8

You need to add the following lines to your config/initializers/mime_types.rb file:

# register MIME type with Rails 
Mime::Type.register "video/mp4", :m4v

# register MIME type with MIME::Type gem 
MIME::Types.add(MIME::Type.from_array("video/mp4", %(m4v)))

Now in the console you can test the results

MIME::Types.type_for("abc.m4v").to_s
#=> "video/mp4"
Harish Shetty
  • 64,083
  • 21
  • 152
  • 198
0

So I think there is Mime::Type and MIME::Types which are completely separate from each other. Notice that it is "Mime" vs "MIME".

For example,

MIME::Types.type_for("foo.json") 

returns

 [#<MIME::Type:0x1038b3108 @system=nil, @encoding="8bit", @simplified="application/json", @sub_type="json", @registered=true, @url=["IANA", "RFC4627"], @docs=nil, @obsolete=nil, @extensions=["json"], @raw_sub_type="json", @media_type="application", @raw_media_type="application", @content_type="application/json">]

Yet,

Mime::Type.lookup_by_extension("json")

returns

#<Mime::Type:0x1051c4d40 @symbol=:json, @string="text/x-json", @synonyms=[]>

So it looks like if you want to add a type so that it is returned when using type_for you can use the following:

>> t = MIME::Type.from_array('video/mp4', %w(m4v))
=> #<MIME::Type:0x1055de3b8 @system=nil, @encoding="base64", @simplified="video/mp4", @sub_type="mp4", @registered=true, @url=nil, @docs=nil, @obsolete=nil, @extensions=["m4v"], @raw_sub_type="mp4", @media_type="video", @raw_media_type="video", @content_type="video/mp4">
>> MIME::Types.add(t)
Type video/mp4 already registered as a variant of video/mp4.
=> [#<MIME::Type:0x1055de3b8 @system=nil, @encoding="base64", @simplified="video/mp4", @sub_type="mp4", @registered=true, @url=nil, @docs=nil, @obsolete=nil, @extensions=["m4v"], @raw_sub_type="mp4", @media_type="video", @raw_media_type="video", @content_type="video/mp4">]
>> MIME::Types.type_for("example.m4v")
=> [#<MIME::Type:0x1055de3b8 @system=nil, @encoding="base64", @simplified="video/mp4", @sub_type="mp4", @registered=true, @url=nil, @docs=nil, @obsolete=nil, @extensions=["m4v"], @raw_sub_type="mp4", @media_type="video", @raw_media_type="video", @content_type="video/mp4">]
>>

The warning when add is called is a little concerning so you should probably figure out how to append your extension to the "video/mp4" type. For more information check out the documentation for MIME::Types and MIME::Type.

Randy Simon
  • 3,324
  • 21
  • 19
  • But the question here is how can I add a custom MIME type so the .m4v extension is recognized (as per my original example). – Shpigford Mar 12 '10 at 17:32
  • I updated my answer to include some code on how to add a custom MIME type. I'm not an expert in this area but hopefully this helps. – Randy Simon Mar 12 '10 at 17:59