Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save jotolo/e354744de94f21bcba1a27c6e88eb77f to your computer and use it in GitHub Desktop.

Select an option

Save jotolo/e354744de94f21bcba1a27c6e88eb77f to your computer and use it in GitHub Desktop.

Revisions

  1. @naoufalelh naoufalelh created this gist May 21, 2020.
    236 changes: 236 additions & 0 deletions active_storage_cheatsheet.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,236 @@
    # Rails Active Storage Cheatsheet

    - [Rails Active Storage Cheatsheet](#rails-active-storage-cheatsheet)
    - [Install Active Storage](#install-active-storage)
    - [Usage](#usage)
    - [Model](#model)
    - [Controller](#controller)
    - [Views (in ERB)](#views-in-erb)
    - [Display Image and its variants or Preview (PDF or Video)](#display-image-and-its-variants-or-preview-pdf-or-video)
    - [Install this libraries first](#install-this-libraries-first)
    - [Display an image (when document is an image)](#display-an-image-when-document-is-an-image)
    - [Generate a variant of an image with `variant`](#generate-a-variant-of-an-image-with-variant)
    - [Generate a preview with `preview`](#generate-a-preview-with-preview)
    - [Don't know the type of document? Use `representation`](#dont-know-the-type-of-document-use-representation)
    - [Content type and size](#content-type-and-size)
    - [Attach a local file](#attach-a-local-file)
    - [Validation with activestorage-validator gem](#validation-with-activestorage-validator-gem)
    - [Select all records with an attachment](#select-all-records-with-an-attachment)

    ---

    ## Install Active Storage

    Only for Rails version 5.2 and up (Rails 5.2.X & Rails 6.X.X).

    1. Install

    ```sh
    rails active_storage:install
    ```

    1. Run migration

    ```sh
    rails db:migrate
    ```

    ## Usage

    We will use User model with attachment(s) name document(s), this document can be an image or PDF or video or any other type.

    ### Model

    - **One attachment**

    ```ruby
    class User < ApplicationRecord

    has_one_attached :document
    end
    ```

    - **Many attachments**

    ```ruby
    class User < ApplicationRecord

    has_many_attached :documents
    end
    ```

    ### Controller

    - **One attachment**

    ```ruby
    class UsersController < ApplicationController
    # your controller methods (index, show ...).
    private

    # Only allow a list of trusted parameters through.
    def user_params
    params.require(:yser).permit(:first_name, :last_name, :document)
    end
    end
    ```

    - **Many attachments**

    ```ruby
    class UsersController < ApplicationController
    # your controller methods (index, show ...).
    private

    # Only allow a list of trusted parameters through.
    def user_params
    params.require(:user).permit(:first_name, :last_name, documents: [])
    end
    end
    ```

    ### Views (in ERB)

    Form filed:

    - **One attachment**

    ```erb
    <%= form.file_field :document %>
    ```

    - **Many attachments**

    ```erb
    <%= form.file_field :documents, multiple: true %>
    ```

    ### Display Image and its variants or Preview (PDF or Video)

    #### Install this libraries first

    First to generate **variants** and **previews** of PDFs and videos, you will need to :

    1. Add `gem 'image_processing', '~> 1.2'` to your Gemfile.
    2. Install [MiniMagick](https://imagemagick.org/script/download.php) for image variants.
    3. To generate previews of PDFs, install [Poppler](https://poppler.freedesktop.org).
    4. To generate previews of Videos, install [FFmpeg](https://www.ffmpeg.org/download.html).

    #### Display an image (when document is an image)

    To check if there is an image attached before displaying it use:

    ```ruby
    if user.documents.attached?
    ```

    - **One attachment**

    ```erb
    <% if user.document.attached? %>
    <%= image_tag user.document %>
    <% end %>
    ```

    - **Many attachments**

    At least one document is attached

    ```erb
    <% if user.documents.attached? %>
    <% user.documents.each do |document| %>
    <%= image_tag document %>
    <% end %>
    <% end %>
    ```

    #### Generate a variant of an image with `variant`

    Don't forget `user.document` should be an **image** in this case.

    ```erb
    <%= image_tag user.document.variant(resize_to_limit: [75, 75]).processed %>
    ```

    > `.processed` method will store the variant for performance reasons.
    For more variant transformations check [image_processing docs](https://github.com/janko/image_processing#installation).

    #### Generate a preview with `preview`

    For PDFs or videos.

    ```erb
    <% if user.document.previewable? %>
    <%= image_tag(user.document.preview(resize: '200x200') %>
    <% end %>
    ```

    > `.previewable?` method will check if you can create a preview of the document attached.
    #### Don't know the type of document? Use `representation`

    ```erb
    <% if user.document.representable? %>
    <%= image_tag(user.document.representation(resize: '200x200') %>
    <% end %>
    ```

    > `.representable?` method will check if you can create a preview or a variant of the document attached.
    ### Content type and size

    Document attachment content type:

    ```ruby
    user.document.content_type
    ```

    Video attachment file size:

    ```ruby
    user.video.byte_size
    ```

    ### Attach a local file

    In tests for example we want to be able to save/attach local files in Active Storage.

    ```ruby
    user.picture.attach(io: File.open('/path/to/file'), filename: 'my_picture.png')
    ```

    ### Validation with activestorage-validator gem

    To install [activestorage-validator](https://github.com/aki77/activestorage-validator) gem add in your application's Gemfile:

    ```ruby
    gem 'activestorage-validator'
    ```

    To use this gem, in your model add:

    ```ruby
    class User < ApplicationRecord
    has_one_attached :avatar
    has_many_attached :photos

    validates :avatar, presence: true, blob: { content_type: :image } # supported options: :image, :audio, :video, :text
    validates :photos, presence: true, blob: { content_type: ['image/png', 'image/jpg', 'image/jpeg'], size_range: 1..5.megabytes }
    # validates :photos, presence: true, blob: { content_type: %r{^image/}, size_range: 1..5.megabytes }
    end
    ```

    ### Select all records with an attachment

    From the comment in this [issue](https://github.com/rails/rails/issues/32295#issuecomment-374304126) in Rails repository in Github.

    ```ruby
    # Assuming a model defined like so:
    class Post < ApplicationRecord
    has_one_attached :image
    end

    # ...you can join against :image_attachment to select posts having attached images:
    Post.joins(:image_attachment).where('published_at >= ?', Time.now)
    ```