# app/models/upload.rb class Upload < ActiveRecord::Base # ...normal attachment_fu code (has_attachment, etc)... # allow uploads via URL require 'open-uri' attr_reader :url def url=(uri) return nil if uri.blank? io = (open(URI.parse(uri)) rescue return nil) (class << io; self; end;).class_eval do define_method(:original_filename) { base_uri.path.split('/').last } end self.uploaded_data = io end end # app/controllers/uploads_controller.rb class UploadsController < ApplicationController # avoid raising exceptions for common errors (e.g. file not found) rescue_from Errno::ENOENT, :with => :url_upload_not_found rescue_from Errno::ETIMEDOUT, :with => :url_upload_not_found rescue_from OpenURI::HTTPError, :with => :url_upload_not_found rescue_from Timeout::Error, :with => :url_upload_not_found def new @upload = Upload.new end def create @upload = current_user.uploads.build(params[:upload]) if @upload.save redirect_to files_path else render :action => "new" end end def url_upload_not_found flash[:notice] = "Sorry, the URL you provided was not valid." redirect_to new_upload_path end end # app/views/uploads/new.html.erb <%= error_messages_for :upload %> <% form_for @upload, :html => { :multipart => true } do |f| -%> <%= f.file_field :uploaded_data # normal upload, or... %> <%= f.text_field :url # upload via url %> <%= submit_tag "Upload", :disable_with => "Upload" %> <% end %>