ActiveStorage File Attachment Validation

Came across this gem: https://github.com/igorkasyanchuk/active_storage_validations

    class User < ApplicationRecord
      has_one_attached :avatar
      has_many_attached :photos
    
      validates :name, presence: true
    
      validates :avatar, attached: true, content_type: 'image/png',
                                         dimension: { width: 200, height: 200 }
      validates :photos, attached: true, content_type: ['image/png', 'image/jpg', 'image/jpeg'],
                                         dimension: { width: { min: 800, max: 2400 },
                                                      height: { min: 600, max: 1800 }, message: 'is not given between dimension' }
    end

ActiveStorage doesn't support validations right now. According to https://github.com/rails/rails/issues/31656.


Update:

Rails 6 will support ActiveStorage validations.

https://github.com/rails/rails/commit/e8682c5bf051517b0b265e446aa1a7eccfd47bf7

Uploaded files assigned to a record are persisted to storage when the record
is saved instead of immediately.
In Rails 5.2, the following causes an uploaded file in `params[:avatar]` to
be stored:
```ruby
@user.avatar = params[:avatar]
```
In Rails 6, the uploaded file is stored when `@user` is successfully saved.

You can use awesome https://github.com/musaffa/file_validators gem

class Profile < ActiveRecord::Base
  has_one_attached :avatar
  validates :avatar, file_size: { less_than_or_equal_to: 100.kilobytes },
    file_content_type: { allow: ['image/jpeg', 'image/png'] }
end

I'm using it with form object so I'm not 100% sure it is working directly with AR but it should...


Well, it ain't pretty, but this may be necessary until they bake in some validation:

  validate :logo_validation

  def logo_validation
    if logo.attached?
      if logo.blob.byte_size > 1000000
        logo.purge
        errors[:base] << 'Too big'
      elsif !logo.blob.content_type.starts_with?('image/')
        logo.purge
        errors[:base] << 'Wrong format'
      end
    end
  end