Rails 6, ActiveStorage and Empty Mime-Types

Phil Smy
3 min readNov 24, 2019

We are working on a new application and writing this in Rails 6. It’s my first time using this new framework. I’ve been working in Ruby on Rails since pre-version 1, back in 2003!

But there are always things to learn, and a new programming framework is an exciting challenge to take up. So I’ll probably be dropping a lot of Rails 6-related articles in the next little while!

The Problem

In this new rails app we are letting users upload files, including .mobi (Amazon Kindle) files. That’s nice. And it’s a good chance to use the new ActiveStorage component in Rails 6.

It was going easy, letting users upload images took a few seconds to add.

But .mobi…that was an issue.

ActiveStorage uses the Javascript File Types method (see here) to determine the content type of the file. Unfortunately, this is pretty slim in it’s supported file types. For .mobi files, it came back with a Content-Type of ‘’ (i.e. — none) and ActiveStorage requires a content type to save it.

The Solution

This turned out to be pretty easy, once I figured it out (isn’t everything?!)

Step 1: Override the Direct Uploads controller.

In my case I created a new controller called BookUploadsController and subclassed it from ActiveStorage::DirectUploadsController. Then, if content type was blank, try to figure it out from the file name.

The controller is just a few lines and looks like this:

class BookUploadsController < ActiveStorage::DirectUploadsController
def create
if params[:blob][:filename].present? and params[:blob][:content_type].empty?
case params[:blob][:filename].downcase
when /mobi$/
params[:blob][:content_type] = 'application/x-mobipocket-ebook'
when /epub$/
params[:blob][:content_type] = 'application/epub+zip'
end
end
super
end
end

Step 2: Override the Route

Next, you need to tell Direct Upload to use this new controller. That’s a matter of overriding the route.

Open up your routes.rb and add this

scope ActiveStorage.routes_prefix do
post "/direct_uploads" => "book_uploads#create", as: :rails_direct_uploads_bmc
end

If you want the as: part then you need to give it something unique. Rails won’t let you have two as’s the same. So hopefully nothing is referring to that route by name. If they do, the correct route will be determined on access.

Hope that helps some of you out there!

Talk to me!

You can find me on Twitter where I share insights on Ruby on Rails, discuss my journey with Zonmaster, and explore various aspects of life. You can also check out my YouTube channel where I cover various topics related to web development, including Ruby on Rails.

And guess what? I’ve recently released my first guide, “Getting Started with Ruby on Rails: A Step-by-Step Guide for Beginners” on Gumroad! 📚🚀 It’s a ‘Fair Price’ ebook, so you can get it for free, but any payment is greatly appreciated as it helps support my work and future guides. Don’t miss out on this opportunity to level up your web development skills with Rails!

Drop me a note on Twitter or LinkedIn if you have any questions or need help with your Rails project. Happy coding! 😊🎉

--

--

Phil Smy
Phil Smy

Written by Phil Smy

Thinker, musician, writer and chief cook and code washer at ZonMaster.com. He’s also a published fiction author.

Responses (1)