I don't like hotlinking. Being dependent on someone’s else infrastructure makes me a bit worried. Especially when I don't know who this "someone" is. That's why I've decided to download all the images that users embed in comments. After download, I attach them with Paperclip to their comments. Thanks to that, I can be sure, that they will always be served from my own servers (also I can use them later for some fancy stuff).
Theoretically, to obtain this, we could do something like that:
# We will use open-uri to download embedded images require "open-uri" file = open(image_url) current_comment.pictures.create!(file: file)
Unfortunately this will "almost" work. If we try to get the file url:
current_picture.file.url #=> '/images/pictures/12313/file.'
we'll get it without an file extension. This happens, because open-uri creates a Tempfile without a file extension. Unluckily Paperclip uses file name to determine extension. To get around this issue, we need to create a new Tempfile with a valid extension and copy open-uri Tempfile content to newly created one:
# We will use open-uri to download embedded images require "open-uri" file = Tempfile.new ['', ".#{image_url.split('.').last}"] file.binmode # note that our tempfile must be in binary mode file.write open(image_url).read file.rewind file current_comment.pictures.create!(file: file)
Update - Paperclip can do this on its own!
Posted by Aditya Sanghi (thanks a lot!):
current_comments.pictures.create!(file: URI.parse(image_url))
Although keep in mind, that you still need to handle 500, 404, etc errors (Paperclip can raise them).