igorkasyanchuk/active_storage_validations
74.6
Strong · 20 September 2026
4.3k
lines of production code
Ruby
primary language
1
measurement over time
What this system is
This system is a Ruby gem that provides validation capabilities for Active Storage file attachments within Rails applications. It enforces constraints on file attributes such as content type, dimensions, size, duration, and page count, while offering robust metadata analysis through modular analyzers for images, audio, and PDFs. The library also includes a comprehensive suite of RSpec matchers to facilitate testing of these validations in consumer applications.
How it got here
2018 — Architecture refactor and testing overhaul
13 changes.
The project underwent a significant architectural refactor, replacing the monolithic codebase with a modular analyzer structure and upgrading to Rails 7+ and Ruby 3.3. This period also saw a comprehensive migration of the test suite from Minitest to RSpec, accompanied by the expansion of the dummy application to support new validators and improved spoofing protection.
2019–2026 — RSpec migration and analyzer refactoring
25 changes.
The project migrated its test suite from Minitest to RSpec, introducing comprehensive matchers, shared examples, and coverage integration. Concurrently, the internal architecture was restructured by extracting validation and analyzer logic into modular components, including a new Vips-based image analyzer and specialized content-type sniffers.
Features
Active Storage Validations upgraded to 4.1.1 with new analyzers and validators
The gem has been upgraded from version 0.2 to 4.1.1, introducing a new Analyzer base class that supports configurable command timeouts for external analysis tools. This release adds several new validation capabilities: a PagesValidator for PDF page counts, a WithAudioValidator to enforce the presence or absence of audio tracks, and a ProcessableFileValidator that correctly handles libvips untrusted content types (such as SVG and BMP) to prevent false validation errors. Additionally, the FormBuilder now automatically infers file accept types from content-type validators, and the Railtie has been refactored to use \ActiveSupport.on\_load\ hooks to resolve a stack overflow issue during initialization.
_lib/active\_storage\validations · high confidence
Add Vips-based image analyzer with command timeout support
Users can now analyze images using the libvips library via the ruby-vips gem, which is generally faster and more memory-efficient than the previous default. This new analyzer supports a configurable command timeout to prevent hanging on large or problematic files, and it gracefully handles unsupported or empty image files by returning nil instead of raising errors.
_lib/active\_storage\_validations/analyzer/image\analyzer · high confidence
Added performance benchmark suite for metadata validators
A new informational benchmark suite has been added to measure the performance of metadata validators, specifically comparing cold analysis against cached results and evaluating the speed difference between the libvips and MiniMagick image processors. The suite includes scripts to measure gem load time, validate individual metadata types (dimensions, duration, pages, content type, processability), and run head-to-head comparisons of image processors, with a checked-in baseline snapshot provided for regression tracking.
benchmark · high confidence
New Cursor AI rules and skills for commit conventions and test suite structure
This change introduces a set of Cursor AI configuration files to standardize development workflows. It adds a 'commit' skill and a 'git.mdc' rule that enforce Conventional Commits formatting, including specific types, scopes, and validation rules for commit messages. Additionally, it establishes shared RSpec conventions in 'spec.mdc' and domain-specific rules for validators, matchers, analyzers, and integration specs, guiding the AI on naming subjects, structuring describe/context blocks, and managing test fixtures. These rules ensure consistent code style and test organization across the gem's specification suite.
.cursor · high confidence
New RSpec matchers for all Active Storage validators
The library now provides dedicated RSpec matchers for every validation type, allowing you to test your model validations directly in specs. You can use \validate\_aspect\_ratio\_of\, \validate\_attached\_of\, \validate\_content\_type\_of\, \validate\_dimensions\_of\, \validate\_duration\_of\, \validate\_limits\_of\, \validate\_pages\_of\, \validate\_processable\_file\_of\, \validate\_size\_of\, \validate\_total\_size\_of\, and \validate\_with\_audio\_of\. These matchers support common testing patterns like \allowing\/\rejecting\ content types, \width\/\height\ ranges, \min\/\max\ file counts, and custom error messages, ensuring your Active Storage validations are covered by your test suite.
_lib/active\_storage\validations/matchers · high confidence
Removals
Removed unused Active Storage validations rake task
The placeholder rake task for Active Storage validations has been removed from the application. This cleanup eliminates dead code that was previously defined but not implemented, resulting in a cleaner task namespace and slightly faster Rake initialization.
lib/tasks · high confidence
Behavioural changes
Enhanced content-type validation with spoofing protection and robust external command handling
The content-type validator now includes optional spoofing protection (via the \spoofing\_protection\ option) to detect mismatches between declared and actual file types, and supports regex patterns for content-type matching. External analyzer commands (e.g., ImageMagick, ffprobe) are now executed with a configurable timeout and process-group kill logic to prevent hung processes from blocking the application.
_active\_storage\validations · high confidence
Global command timeout and refactored analyzer architecture
The gem now includes a global \command\_timeout\ configuration (defaulting to 10 seconds) that limits the execution time for external analyzer commands like ffprobe, magika, and MiniMagick, which can be overridden per-validator. This change accompanies a structural refactor that replaces the monolithic \lib/active\_storage\_validations.rb\ with a modular architecture, introducing dedicated analyzer classes (e.g., \ASVFFProbable\ for FFprobe) and explicit requires for validators and form builders, ensuring more robust and maintainable file analysis.
lib · high confidence
Improved MIME type detection and AWS-compatible metadata storage
The gem now extends Marcel's MIME type detection to correctly handle specific file types like RAR, AAC, Theora, and empty files, ensuring accurate content-type validation. Additionally, blob metadata is now stored as flattened key-value pairs prefixed with 'asv\_' rather than nested hashes, which resolves errors with AWS S3 services that only accept string values and ensures compatibility with AWS metadata constraints.
_lib/active\_storage\validations/extensors · high confidence
Migrate test suite from Minitest to RSpec
The gem's test suite has been migrated from Minitest to RSpec, replacing the \rake test\ task with \rake spec\ and introducing RuboCop configuration for RSpec style enforcement. This change updates the development workflow and test runner while keeping the consumer-facing test matchers (for RSpec and Minitest/Shoulda) unchanged.
(repo-wide) · high confidence
Refactored analyzers into a modular architecture with new audio and content-type sniffers
The analyzer subsystem has been restructured into distinct, specialized classes: a new AudioAnalyzer extracts duration, bitrate, sample rate, and audio presence; a new ContentTypeAnalyzer hierarchy introduces a File backend (using the system \file\ command) and a Magika backend (using Google's Magika CLI) for spoofing protection; the ImageAnalyzer is now an abstract base class for concrete implementations; and the PDFAnalyzer now correctly parses fractional page dimensions. Existing Video and Null analyzers remain, providing a cleaner separation of concerns and expanded metadata capabilities for audio and content-type validation.
_lib/active\_storage\validations/analyzer · high confidence
Refactored matcher internals into shared concerns
The internal implementation of the validation matchers has been restructured by extracting shared logic into dedicated modules (such as \ASVActiveStorageable\, \ASVAllowBlankable\, \ASVContextable\, \ASVExceptOnable\, \ASVMessageable\, \ASVRspecable\, \ASVSpoofingProtectable\, \ASVTimeoutable\, and \ASVValidatable\). This change improves code organization and maintainability for the library's test suite without altering the public API or the behavior of the validation matchers themselves.
_lib/active\_storage\validations/matchers/shared · high confidence
Refactored validation logic into shared modules
The validation logic in the gem has been reorganized into a set of shared modules (ASVActiveStorageable, ASVAnalyzable, ASVAttachable, ASVErrorable, ASVLoggable, ASVOptionable, and ASVSymbolizable) to improve code structure and maintainability. This change extracts helper methods for handling Active Storage attachments, analyzing file metadata, managing errors, and processing options into reusable components, ensuring that validators remain explicit and consistent across different file types and Rails versions.
_lib/active\_storage\validations/shared · high confidence
Test coverage
Add PDF test fixtures with decimal dimensions; Added RSpec shared examples for analyzer metadata validation; Added RSpec shared helpers for validator testing; Added RSpec support helpers for analyzers and matchers; Added RSpec test suite for Active Storage Validations matchers; Added RSpec test suite for image analyzers; Added RSpec test suite for locale integrity and Active Storage validations; Added integration tests for validator timeout, thread safety, and metadata caching; Added shared test suites for attachable and errorable validation logic; Added test fixtures and support helpers for file and locale validation; Added test fixtures for MIME type spoofing detection; Added tests for the File and Magika content-type analyzers; Comprehensive RSpec test suite for ActiveStorageValidations; Expanded dummy application models for comprehensive validator testing; Migrate test suite to RSpec with SimpleCov coverage integration; Migrate validator test suite to RSpec; Migrated test suite from Minitest to RSpec; Removed dummy application environment configuration files; Removed legacy Minitest test suite and helper; Removed legacy bin/test script; Simplify dummy app configuration and add DigitalOcean storage support; Updated dummy application test setup; Updated test dummy database schema for Active Storage V2 and expanded validator test coverage.
Dependencies
Updated CI gemfiles for Rails 7.0–8.1 and next
The gemfiles in the gemfiles/ directory have been regenerated to support testing against Rails 7.0.1, 7.1, 7.2, 8.0, 8.1.3.1, and the Rails main branch (8.2.0.alpha). These updates pin specific dependency versions to ensure CI stability: nokogiri is pinned to \>= 1.18 to support Ruby 3.4/4.0, sqlite3 is pinned to \>= 2.9 for Ruby 4.0 compatibility, and json is restricted to \< 3 for Rails 8.1 to avoid breaking changes in JSON.parse. Additionally, rspec-rails is pinned to \~\> 7.0 for Rails 7.0/7.1 and \~\> 8.0 for Rails 7.2/8.0/8.1, and ffi is pinned to \>= 1.17.1 for Rails 8.0.
gemfiles · high confidence
Upgrade to Rails 8.1 and Ruby 3.3 with updated gem dependencies
The gem now requires Ruby 3.3.0 or higher and Rails 7.0.1 or higher, with the local development environment pinned to Rails 8.1.3.1. This update replaces the older Rails 5.2 dependency with modern Active Storage subcomponents (activejob, activemodel, activestorage, activesupport) and enforces marcel \>= 1.0.3 for mime type spoofing detection. Development dependencies have been refreshed to include rspec-rails, combustion, rubocop, and simplecov, while the gemspec metadata has been expanded with standard RubyGems fields.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Baseline
- First survey — no prior run to compare against. CAI 75.
Lenses
- Code Health 99
- Architecture 100
- Maturity 61
- Readiness 77
- Security 93
Changes since last survey
- 300 commits — 241 feature/other, 59 fixes
By area
- (root) — 117 commits
- (repo) — 54 commits
- lib/active_storage_validations — 38 commits
- test/dummy — 17 commits
- config/locales — 12 commits
- spec/validators — 7 commits
- test/validators — 6 commits
- .github/workflows — 5 commits
- gemfiles/rails_6_1_4.gemfile.lock — 5 commits
- spec/matchers — 5 commits
- gemfiles/rails_7_1.gemfile — 4 commits
- spec/analyzers — 4 commits
- spec/spec_helper.rb — 4 commits
- gemfiles/rails_6_1_4.gemfile — 3 commits
- test/analyzers — 3 commits
- gemfiles/rails_7_0.gemfile — 2 commits
- gemfiles/rails_7_1.gemfile.lock — 2 commits
- test/extensors — 2 commits
- test/matchers — 2 commits
- .github/FUNDING.yml — 1 commit
Notable commits
- fix: Fix wrong Portuguese Brazilian translation
- fix: Merge pull request #345 from OdenTakashi/fix/wrong_japanese_translation
- fix: Merge pull request #383 from igorkasyanchuk/quick-fix
- fix: Merge pull request #422 from tmnb/fix-unsaved-blob-deduplication
- fix: [CHANGES] Add fix log to changelog
- fix: [CI] Fix CI
- fix: [CI] Fix CI
- fix: [CI] Fix CI
- fix: [CI] Fix CI
- fix: [CI] Fix CI
- fix: [CI] Fix CI
- fix: [CI] Fix CI
- fix: [CI] Fix CI
- fix: [CI] Fix rails_next CI issue
- fix: [Changelog] Add fix explanation
- fix: [Gem] Fix issue with developers not able to deifne their own Marcel content_types (#355)
- fix: [Matcher] Fix failing test
- fix: [Matcher] Fix issue when several matchers using metadata (#350)
- fix: [Metadata] Fix nasty bug due to AWS not allowing anything apart from String (#348)
- fix: [Performance] Fix issue due to unsaved metadata (#361)
- …and 280 more
Architecture
- 0 containers · 1 bounded contexts · 0 dependency edges (baseline)
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
igorkasyanchuk/active_storage_validations was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 20 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 2b9e915b0c2b29c01880c351c541c615d05792a9 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-b51f968c9b10.