Search code examples
ruby-on-railsdeviserails-activestorage

How to prevent active storage updating model when validation fails?


My User model has_one_attached :avatar

Here I have some validation methods

  validate :validate_avatar_presence
  validate :validate_avatar_format
  validate :validate_avatar_size

  private

  def validate_avatar_presence
    errors.add(:avatar, 'should exist') unless self.avatar.attached?
  end

  def validate_avatar_size
    if self.avatar.attached?
      purge_avatar('File is too big') if self.avatar.blob.byte_size > 2000000
    end
  end

  def validate_avatar_format
    if self.avatar.attached?
      purge_avatar('Wrong format') unless self.avatar.blob.content_type.starts_with?('image/')
    end
  end

  def purge_avatar(msg)
    errors.add(:avatar, msg)
    avatar.purge_later
  end

Regardless of what I'm uploading, user avatar gets updated. If validations fail, avatar becomes nil, otherwise I get what I've uploaded. I tried to validate via before_update callback. It doesn't work.


Solution

  • Active Storage doesn’t currently support validations, but full support is coming in Rails 6.0. Until 6.0 is released, use Rails master, which avoids storing files when validations fail.