this fork adds mongoid and rails_admin support.

ActiveRecord support is dropped!

This fork works when both simple form and formtastic are loaded

Also nested associations are working

HTML5 File uploader for rails

This gem use https://github.com/blueimp/jQuery-File-Upload for upload files.

Preview:

Uploader in use

Install

In Gemfile:

gem "glebtv-rails-uploader"

In routes:

mount Uploader::Engine => '/uploader'

HowTo for mongoid / carrierwave:

Asset Parent Model (common)

    # models/asset.rb
    class Asset
      include Mongoid::Document
      include Uploader::Asset

      field :guid, type: String
      belongs_to :assetable, polymorphic: true

      # this workaround is sometimes needed so IDs are ObjectIDs not strings  
      before_save do
        return true if self.assetable_id.nil? || !self.assetable_id.is_a?(String)
        if defined?(Moped::BSON)
          self.assetable_id = Moped::BSON::ObjectId.from_string(self.assetable_id) if Moped::BSON::ObjectId.legal?(self.assetable_id)
        else
          self.assetable_id = BSON::ObjectId.from_string(self.assetable_id) if BSON::ObjectId.legal?(self.assetable_id)
        end
        true
      end
    end

Your asset model

    # models/cover.rb
    class Cover < Asset
      # DO NOT add this!
      # belongs_to :post

      # optional built-in sorting for rails_admin
      field :sort, type: Integer

      # field name must be 'data'
      mount_uploader :data, CoverUploader

      validates :data,
          :presence => true,
          :file_size => {
              :maximum => 5.megabytes.to_i
          }

      def to_jq_upload
        {
            'id'  => id.to_s,
            "filename" => File.basename(data.path),
            "url" => data.url,
            'thumb_url' => data.thumb.url,
        }
      end
    end

Model to which you want to add assets

    # models/post.rb
    class Post
      include Mongoid::Document

      field :fileupload_guid, type: String

      include Uploader::Fileuploads
      has_one :cover, as: :assetable
      fileuploads :cover
    end

has_many

class Album
  has_many :pictures, as: :assetable, dependent: :destroy
  fileuploads :pictures

  accepts_nested_attributes_for :pictures

  rails_admin do
    edit do
      ...
      field :fileupload_guid, :hidden # this is needed or else rails_admin sanitizes it away
      field :pictures, :rails_uploader
    end
  end
end

CarrierWave uploader - all like usual

    # uploades/cover_uploader.rb
    class CoverUploader < CarrierWave::Uploader::Base
      include CarrierWave::MiniMagick

      storage :file

      def store_dir
        "uploads/covers/#{model.id}"
      end

      version :thumb do
        process resize_to_limit: [50, 50]
      end
    end

Active Admin and RailsAdmin are both working

RailsAdmin Integration

    rails_admin do
        edit do
          ...
          field :fileupload_guid, :hidden # this is needed or else rails_admin sanitizes it away
          field :pictures, :rails_uploader
        end
    end

Usage (Original description)

Architecture to store uploaded files (cancan integration):

class Asset < ActiveRecord::Base
  include Uploader::Asset

  def uploader_create(params, request = nil)
    ability = Ability.new(request.env['warden'].user)

    if ability.can? :create, self
      self.user = request.env['warden'].user
      super
    else
      errors.add(:id, :access_denied)
    end
  end

  def uploader_destroy(params, request = nil)
    ability = Ability.new(request.env['warden'].user)

    if ability.can? :delete, self
      super
    else
      errors.add(:id, :access_denied)
    end
  end
end

class Picture < Asset
  mount_uploader :data, PictureUploader

  validates_integrity_of :data
  validates_filesize_of :data, :maximum => 2.megabytes.to_i
end

For example user has one picture:

class User < ActiveRecord::Base
  has_one :picture, :as => :assetable, :dependent => :destroy

  fileuploads :picture

  # If your don't use strong_parameters, uncomment next line
  # attr_accessible :fileupload_guid
end

Find asset by foreign key or guid:

@user.fileupload_asset(:picture)

Mongoid

class Asset
  include Mongoid::Document
  include Uploader::Asset::Mongoid

  belongs_to :assetable, polymorphic: true
end

class Picture < Asset
  mount_uploader :data, ImageUploader

  default_scope asc( :sort_order )
end

class User
  include Mongoid::Document
  include Uploader::Fileuploads::Mongoid

  has_many :pictures, :as => :assetable

  fileuploads :pictures
end

Include assets

Javascripts:

//= require jquery.ui.widget
//= require uploader/application

Stylesheets:

*= require uploader/application

Views

<%= uploader_field_tag :article, :photo %>

or FormBuilder:

<%= form.uploader_field :photo, :sortable => true %>

Formtastic

<%= f.input :pictures, :as => :uploader %>

SimpleForm

<%= f.input :pictures, :as => :uploader, :input_html => {:sortable => true} %>

Confirming deletions

This is only working in Formtastic and FormBuilder:

# formtastic
<%= f.input :picture, :as => :uploader, :confirm_delete => true %>
# the i18n lookup key would be en.formtastic.delete_confirmations.picture

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Added some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Copyright (c) 2013 Fodojo, released under the MIT license