Shrine

Shrine logo: a red paperclip

Shrine is a toolkit for handling file attachments in Ruby applications. Some highlights:

If you’re curious how it compares to other file attachment libraries, see the Advantages of Shrine. Otherwise, follow along with the Getting Started guide.

ResourceURL
Website & Documentationshrinerb.com
Demo codeRoda / Rails
Wikigithub.com/shrinerb/shrine/wiki
Help & Discussiondiscourse.shrinerb.com

Setup

Add the gem to your Gemfile:

Gemfile

gem “shrine”, “~> 3.0”

Then add config/initializers/shrine.rb which sets up the storage and loads ORM integration:

“ require “shrine” require “shrine/storage/file_system”

Shrine.storages = { cache: Shrine::Storage::FileSystem.new(“public”, prefix: “uploads/cache”), # temporary store: Shrine::Storage::FileSystem.new(“public”, prefix: “uploads”), # permanent }

Shrine.plugin :activerecord # loads Active Record integration Shrine.plugin :cached_attachment_data # enables retaining cached file across form redisplays Shrine.plugin :restore_cached_data # extracts metadata for assigned cached files

Next, add the <name>_data column to the table you want to attach files to. For an “image” attachment on a photos table this would be an image_data column:

“ rails generate migration add_image_data_to_photos image_data:text # or :jsonb

“f using jsonb consider adding a gin index for fast key-value pair searchability within image_data.

Now create an uploader class (which you can put in app/uploaders) and register the attachment on your model:

“ class ImageUploader < Shrine # plugins and uploading logic end

“ class Photo < ActiveRecord::Base include ImageUploader::Attachment(:image) # adds an image virtual attribute end

In our views let’s now add form fields for our attachment attribute that will allow users to upload files:

“b <%= form_for @photo do |f| %> <%= f.hidden_field :image, value: @photo.cached_image_data %> <%= f.file_field :image %> <%= f.submit %> <% end %>

When the form is submitted, in your controller you can assign the file from request params to the attachment attribute on the model:

“ class PhotosController < ApplicationController def create Photo.create(photo_params) # attaches the uploaded file # … end

private

def photo_params params.require(:photo).permit(:image) end end

Once a file is uploaded and attached to the record, you can retrieve the file URL and display it on the page:

“b <%= image_tag @photo.image_url %>

See the Getting Started guide for further documentation.

Inspiration

Shrine was heavily inspired by Refile and Roda. From Refile it borrows the idea of “backends” (here named “storages”), attachment interface, and direct uploads. From Roda it borrows the implementation of an extensible plugin system.

Similar libraries

  • Paperclip
  • CarrierWave
  • Dragonfly
  • Refile
  • Active Storage

Contributing

Please refer to the contributing page.

Code of Conduct

Everyone interacting in the Shrine project’s codebases, issue trackers, and mailing lists is expected to follow the Shrine code of conduct.

License

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