module Shrine::Plugins::Activerecord

  1. lib/shrine/plugins/activerecord.rb

The activerecord plugin extends the “attachment” interface with support for ActiveRecord.

plugin :activerecord


Now the attachment module will add additional callbacks to the model:

  • “before save” – Used by the recache plugin.

  • “after commit” (save) – Promotes the attachment, deletes replaced ones.

  • “after commit” (destroy) – Deletes the attachment.

Note that ActiveRecord versions 3.x and 4.x have errors automatically silenced in hooks, which can make debugging more difficult, so it's recommended that you enable errors:

# This is the default in ActiveRecord 5
ActiveRecord::Base.raise_in_transactional_callbacks = true

If you want to put promoting/deleting into a background job, see the backgrounding plugin.

Since attaching first saves the record with a cached attachment, then saves again with a stored attachment, you can detect this in callbacks:

class User < ActiveRecord::Base

  before_save do
    if avatar_data_changed? && avatar_attacher.cached?
      # cached
    elsif avatar_data_changed? && avatar_attacher.stored?
      # promoted

If you don't want the attachment module to add any callbacks to the model, and would instead prefer to call these actions manually, you can disable callbacks:

plugin :activerecord, callbacks: false


Additionally, any Shrine validation errors will be added to ActiveRecord's errors upon validation. If you want to validate presence of the attachment, you can do it directly on the model.

class User < ActiveRecord::Base
  validates_presence_of :avatar

If don't want the attachment module to merge file validations errors into model errors, you can disable it:

plugin :activerecord, validations: false


Public Class

  1. configure

Public Class methods

configure (uploader, opts = {})
[show source]
# File lib/shrine/plugins/activerecord.rb, line 65
def self.configure(uploader, opts = {})
  uploader.opts[:activerecord_callbacks] = opts.fetch(:callbacks, uploader.opts.fetch(:activerecord_callbacks, true))
  uploader.opts[:activerecord_validations] = opts.fetch(:validations, uploader.opts.fetch(:activerecord_validations, true))