Skip to content
This repository was archived by the owner on Apr 8, 2026. It is now read-only.

Rails setup for V6

Sebastian Tschan edited this page Sep 14, 2014 · 13 revisions

Prerequisites

  • have jQuery setup in your app

  • copy jQuery File Upload files in the proper directories of your Rails app

Models

For use with the Carrierwave gem

We'll use basic Carrierwave uploader:

class AvatarUploader < CarrierWave::Uploader::Base
  storage :file
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end
end

Let's set up a Picture model

class Picture < ActiveRecord::Base
  include Rails.application.routes.url_helpers
  mount_uploader :avatar, AvatarUploader

  #one convenient method to pass jq_upload the necessary information
  def to_jq_upload
    {
      "name" => read_attribute(:avatar),
      "size" => avatar.size,
      "url" => avatar.url,
      "thumbnail_url" => avatar.thumb.url,
      "delete_url" => picture_path(:id => id),
      "delete_type" => "DELETE" 
    }
  end
end

For use with the Dragonfly gem

set up a Picture model (make sure you have both avatar_uid and avatar_name columns in your database)

class Picture < ActiveRecord::Base
  include Rails.application.routes.url_helpers
  image_accessor :avatar

  #one convenient method to pass jq_upload the necessary information
  def to_jq_upload
    {
      "name" => read_attribute(:avatar_name),
      "size" => avatar.size,
      "url" => avatar.url,
      "thumbnail_url" => avatar.thumb('80x80#').url,
      "delete_url" => picture_path(:id => id),
      "delete_type" => "DELETE" 
    }
  end
end

Controller

First one controller to handle the downloads: (html response is for browsers using iframe sollution)

class PicturesController < ApplicationController

  def index
    @pictures = Picture.all
    render :json => @pictures.collect { |p| p.to_jq_upload }.to_json
  end

  def create
    @picture = Picture.new(params[:picture])
    if @picture.save
      respond_to do |format|
        format.html {  
          render :json => [@picture.to_jq_upload].to_json, 
          :content_type => 'text/html',
          :layout => false
        }
        format.json {  
          render :json => [@picture.to_jq_upload].to_json			
        }
      end
    else 
      render :json => [{:error => "custom_failure"}], :status => 304
    end
  end

  def destroy
    @picture = Picture.find(params[:id])
    @picture.destroy
    render :json => true
  end
end

And it's routes:

resources :pictures, :only => [:index, :create, :destroy]

Let's play

In whatever view file you want, copy paste this code and enjoy.

<h2><%= t('photos.title') %>h2>
<%= form_for Picture.new, :html => { :multipart => true, :id => "fileupload"  } do |f| %>
        
        <div class="row fileupload-buttonbar">
            <div class="span7">
                
                <span class="btn btn-success fileinput-button">
                    <i class="icon-plus icon-white">i>
                    <span>Add files...span>
                    <%= f.file_field :avatar %>
                span>
                <button type="submit" class="btn btn-primary start">
                    <i class="icon-upload icon-white">i>
                    <span>Start uploadspan>
                button>
                <button type="reset" class="btn btn-warning cancel">
                    <i class="icon-ban-circle icon-white">i>
                    <span>Cancel uploadspan>
                button>
                <button type="button" class="btn btn-danger delete">
                    <i class="icon-trash icon-white">i>
                    <span>Deletespan>
                button>
                <input type="checkbox" class="toggle">
            div>
            <div class="span5">
                
                <div class="progress progress-success progress-striped active fade">
                    <div class="bar" style="width:0%;">div>
                div>
            div>
        div>
        
        <div class="fileupload-loading">div>
        <br>
        
        <table class="table table-striped"><tbody class="files" data-toggle="modal-gallery" data-target="#modal-gallery">tbody>
        table>
    <% end %>
<script>
  var fileUploadErrors = {
    maxFileSize: 'File is too big',
    minFileSize: 'File is too small',
    acceptFileTypes: 'Filetype not allowed',
    maxNumberOfFiles: 'Max number of files exceeded',
    uploadedBytes: 'Uploaded bytes exceed file size',
    emptyResult: 'Empty file upload result'
  };
script>


<script id="template-upload" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
    <tr class="template-upload fade">
        <td class="preview"><span class="fade">span>td>
        <td class="name"><span>{%=file.name%}span>td>
        <td class="size"><span>{%=o.formatFileSize(file.size)%}span>td>
        {% if (file.error) { %}
            <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}span> {%=locale.fileupload.errors[file.error] || file.error%}td>
        {% } else if (o.files.valid && !i) { %}
            <td>
                <div class="progress progress-success progress-striped active"><div class="bar" style="width:0%;">div>div>
            td>
            <td class="start">{% if (!o.options.autoUpload) { %}
                <button class="btn btn-primary">
                    <i class="icon-upload icon-white">i>
                    <span>{%=locale.fileupload.start%}span>
                button>
            {% } %}td>
        {% } else { %}
            <td colspan="2">td>
        {% } %}
        <td class="cancel">{% if (!i) { %}
            <button class="btn btn-warning">
                <i class="icon-ban-circle icon-white">i>
                <span>{%=locale.fileupload.cancel%}span>
            button>
        {% } %}td>
    tr>
{% } %}
script>

<script id="template-download" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
    <tr class="template-download fade">
        {% if (file.error) { %}
            <td>td>
            <td class="name"><span>{%=file.name%}span>td>
            <td class="size"><span>{%=o.formatFileSize(file.size)%}span>td>
            <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}span> {%=locale.fileupload.errors[file.error] || file.error%}td>
        {% } else { %}
            <td class="preview">{% if (file.thumbnail_url) { %}
                <a href="{%=file.url%}" title="{%=file.name%}" rel="gallery" download="{%=file.name%}"><img src="{%=file.thumbnail_url%}">a>
            {% } %}td>
            <td class="name">
                <a href="{%=file.url%}" title="{%=file.name%}" rel="{%=file.thumbnail_url&&'gallery'%}" download="{%=file.name%}">{%=file.name%}a>
            td>
            <td class="size"><span>{%=o.formatFileSize(file.size)%}span>td>
            <td colspan="2">td>
        {% } %}
        <td class="delete">
            <button class="btn btn-danger" data-type="{%=file.delete_type%}" data-url="{%=file.delete_url%}">
                <i class="icon-trash icon-white">i>
                <span>{%=locale.fileupload.destroy%}span>
            button>
            <input type="checkbox" name="delete" value="1">
        td>
    tr>
{% } %}
script>




<%= javascript_include_tag 'jquery.ui.widget.js' %>

<script src="https://blueimp.github.com/JavaScript-Templates/tmpl.min.js">script>
<script src="https://blueimp.github.com/JavaScript-Load-Image/load-image.all.min.js">script>

<%= javascript_include_tag 'jquery.iframe-transport.js' %>
<%= javascript_include_tag 'jquery.fileupload.js' %>
<%= javascript_include_tag 'jquery.fileupload-ui.js' %>


<script type="text/javascript" charset="utf-8">
    $(function () {
        // Initialize the jQuery File Upload widget:
        $('#fileupload').fileupload();
        // 
        // Load existing files:
        $.getJSON($('#fileupload').prop('action'), function (files) {
          var fu = $('#fileupload').data('blueimp-fileupload'), 
            template;
          fu._adjustMaxNumberOfFiles(-files.length);
          template = fu._renderDownload(files)
            .appendTo($('#fileupload .files'));
          // Force reflow:
          fu._reflow = fu._transition && template.length &&
            template[0].offsetWidth;
          template.addClass('in');
          $('#loading').remove();
        });

    });
script>

Clone this wiki locally