TIL: Attach binary file to Active Storage record
The #attach method can be tricky to work with when the file doesn’t come from a browser, so after struggling a bit with it, I’m writing this down!

class MyModel < ApplicationRecord
has_one_attached :file
end
class DownloadRemoteImageJob
def perform(my_model)
...
response = http_conn.get(my_model.url) # remote file
pathname = Pathname.new(my_model.url)
mime = Rack::Mime.mime_type(pathname.extname) # this is a poor way of getting the mime-type
# store response in tempfile
tmpfile = Tempfile.new(pathname.basename.to_s)
tmpfile.binmode
tmpfile.write(response.body)
tmpfile.rewind
my_model.file.attach(
io: tmpfile,
filename: pathname.basename.to_s,
content_type: mime
)
my_model.save!
ensure
tmpfile.close! if defined?(tmpfile)
end
end
Credits
- "File:'Attached to the Village' by Javad Alizadeh.jpg" by Javad Alizadeh is licensed under CC BY-SA 3.0
.
- This closed issue (rails/32711) from a couple of years ago.