Giter VIP home page Giter VIP logo

activestorage-delayed's Introduction

Activestorage Delayed

ActiveStorage in Rails 6 and 7 does not support to upload files in background which in most cases delays the submit process and then makes the visitor get bored or receive a timeout error.
This is a Ruby on Rails gem to upload activestorage files in background by saving them as base64 encoded in the database (important for apps hosted in kubernetes) and be processed later.

Features

  • Upload files in background
  • Ability to add new files instead of replacing the old ones when using using has_many_attached
  • Ability to upload files with the original filename or a custom one
  • Ability to preprocess the files before uploading them (Rails 7+)
    Note: This gem assumes that the app has already configured activestorage.

Installation

  • Add this line to your application's Gemfile:
      gem 'activestorage-delayed', '>= 0.1.3'
  • And then execute: bundle install
  • Generate the migration: rails g migration add_activestorage_delayed
  • Add the following content to the migration file:
      create_table :activestorage_delayed_uploads do |t|
        t.references :uploadable, polymorphic: true, null: false
        t.string :attr_name, null: false
        t.string :deleted_ids, default: ''
        t.boolean :clean_before, default: false
        t.text :files
        t.timestamps
      end
  • Run the migration: rails db:migrate

Usage

  • Include ActivestorageDelayed::DelayedConcern
  • Add delayed_attach to the files you want to upload in background
  class User < ApplicationRecord
  include ActivestorageDelayed::DelayedConcern

  has_one_attached :photo, required: true, use_filename: true, variant_info: { resize_to_fit: [400, 400], convert: 'jpg' }
  delayed_attach :photo

  has_many_attached :certificates
  delayed_attach :certificates
end

delayed_attach accepts an optional hash with the following options:

  • required: If set to true, the photo or the photo_tmp will be required before saving.
  • use_filename: If set to true, the image filename will be used as the name of uploaded file instead of the hash-key used by activestorage
  • variant_info: (Hash) Variant information to be performed before uploading the file.

Examples to upload files in background

  • Upload a single file

      User.create(photo_tmp: File.open('my_file.png')) # uploads the file in background
      User.create(photo: File.open('my_file.png')) # uploads the file directly

    HTML:

    f.file_field :photo_tmp
  • Upload multiple files

      User.create(certificates_tmp: [File.open('my_file.png'), File.open('my_file.png')])

    HTML:

    = f.file_field :certificates_tmp, multiple: true
  • Deletes first 2 certificates and uploads a new one

      file_ids = User.first.certificates.limit(2).pluck(:id)
      User.first.update(certificates_tmp: { deleted_ids: file_ids, files: [File.open('my_file.png')] })

    HTML

    = file_field_tag 'user[certificates_tmp][files][]', multiple: true
    - user.certificates.each do |file|
      %li
        = image_tag(file)
        = check_box_tag 'user[certificates_tmp][deleted_ids][]', value: file.id
  • Removes all certificates before uploading a new one

      User.first.update(certificates_tmp: { clean_before: true, files: [File.open('my_file.png')] })
  • Upload files with custom names (requires use_filename: true): <attr_name>_filename

    class User < ApplicationRecord
      def photo_filename(filename)
        "#{id}-#{full_name.parameterize}#{File.extname(filename)}"
      end
    end

    When <attr_name>_filename is defined, then it is called to fetch the uploaded file name.
    Note: Check this if you want to rename an already uploaded file (remote file)

  • Capture event when file upload has failed: <attr_name>_error_upload

      class User < ApplicationRecord
        # @param error [StandardError]
        # @param file_data [Hash<'filename'>]
        def photo_error_upload(error, file_data)
          puts "Failed uploading photo #{file_data['filename']}: #{error.message}"
        end
      end
  • Capture event when file has been uploaded: <attr_name>_after_upload

      class User < ApplicationRecord
        # @param file_data [Hash<'filename'>]
        def photo_after_upload(file_data)
          puts "Photo #{file_data['filename']} has been uploaded"
        end
    
        def photo_after_upload_all
          puts "All photos have been uploaded"
        end
      end

Note:
<attr_name>_delayed_uploads is a has_many association that contains the list of scheduled uploads for the corresponding attribute.

Contributing

Bug reports and pull requests are welcome on https://github.com/owen2345/activestorage-delayed. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

To ensure your contribution changes, run the tests with: docker-compose run test

License

The gem is available as open source under the terms of the MIT License.

activestorage-delayed's People

Contributors

owen2345 avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.