Tag: Rails 4.0.1

Rails + Paperclip + Open-Uri – Downloading files from the internet and saving them with Paperclip

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).

State machine gem: undefined method underscore for ActiveModel::Name

If  you encounter this issue:

Failure/Error: ::Mobile::App::Talk.make!
NoMethodError:
  undefined method `underscore' for #<ActiveModel::Name:0x0000000ebae880>

When using state machine, machinist and machinist_mongo, please add this to your app/config/initializers/state_machine.rb:

# It seems that there is no underscore method on ActiveModel name
# It is added here, so it will be accessible and state machine
# can work. It should be removed after this is fixed
class ActiveModel::Name
  def underscore
    to_s.underscore
  end
end

This should be enough to make it work :)

Copyright © 2024 Closer to Code

Theme by Anders NorenUp ↑