Skip to content

Conversation

@seanabrahams
Copy link

@seanabrahams seanabrahams commented Jun 21, 2022

Building directly on top of rails#41178 (which built on top of rails#35390) this PR attempts to pick up where rails#41178 left off in implementing validations for ActiveStorage attributes with support for direct uploads as well.

There are two major differences:

  1. To know which validations to run for a direct upload we need to know not only the Model but also the Attribute (User.avatar). This way we know to apply the ActiveStorage validations defined for the User model's avatar attribute. Further, rather than pass this information in public, leaving it open to tampering, it is signed:
@user.avatar.to_signed_validation_id
User.new.avatar.to_signed_validation_id # Also works with models that are not yet persisted

I'm not entirely happy with the method name, to_signed_validation_id, and welcome suggestions. Perhaps direct_upload_validation_id? I went with the to_*_id format to match GlobalID's to_global_id method but it feels odd in this context. @user.avatar.direct_upload_validation_id?

This is what a direct upload input element ends up looking like:

<input data-direct-upload-url="http://test.host/rails/active_storage/direct_uploads" data-direct-upload-signed-validation-id="ImdpZDovL0FjdGl2ZVN0b3JhZ2VFeGFtcGxlQXBwL1VzZXIvMS0tYXZhdGFyIg==--6862642c90f8f13256f6424c0fdd847a1d030719" type="file" name="user[avatar]" id="user_avatar" />
  1. When a direct upload request fails validation we now return a JSON payload with the error messages so that it's clear why it failed:
{
  "errors": {
    "content_type": [
      "is not included in the list"
    ],
    "byte_size": [
      "must be less than or equal to 5 MB"
    ]
  }
}

One question:

  1. There was a previous note in active_storage/validations/attachment_content_type_validator.rb:

    # TODO: implement check_options_validity from AM::Validators::FormatValidator

    It wasn't clear to me how best to share the code from ActiveModel::Validators::FormatValidator thus I opted to copy, paste, and refine it for this use case. Would be grateful for a seasoned Rails contributor to chime in here.


Thank you Abhishek Chandrasekhar and Alex Ghiculescu for your original work!

Co-authored-by: Abhishek Chandrasekhar me@abhchand.me
Co-authored-by: Alex Ghiculescu alex@tanda.co

@seanabrahams seanabrahams changed the title ActiveStorage Validations: content_type and byte_size ActiveStorage Validations: content_type, byte_size, and presence Jun 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants