Skip to content

[FEATURE] Object/Hash Validator #9

@danielnottingham

Description

@danielnottingham

Problem Statement

I'm always frustrated when I need to validate complex nested objects like user registration forms, API request payloads, or configuration hashes. There's no way to define and validate the shape of an object with multiple fields and nested structures.

Proposed Solution

Add an ObjectValidator class that provides schema-based validation:

# Define schema
user_validator = ValidatorRb.object({
  name: ValidatorRb.string.min(1).required,
  email: ValidatorRb.string.email.required,
  age: ValidatorRb.integer.min(0).optional,
  tags: ValidatorRb.array.of(ValidatorRb.string).optional,
  address: ValidatorRb.object({
    street: ValidatorRb.string.required,
    city: ValidatorRb.string.required,
    zip: ValidatorRb.string.regex(/^\d{5}$/).optional
  }).optional
})
# Validate
result = user_validator.validate({
  name: "John Doe",
  email: "john@example.com",
  age: 30,
  tags: ["ruby", "rails"],
  address: {
    street: "123 Main St",
    city: "Springfield",
    zip: "12345"
  }
})
# Partial validation (makes all fields optional)
partial_validator = user_validator.partial
# Pick specific keys
login_validator = user_validator.pick([:email, :password])
# Omit keys
public_validator = user_validator.omit([:password])
# Strict mode (reject unknown keys)
strict_validator = user_validator.strict
# Error messages with paths
result.errors
# => {
#   "name" => ["is required"],
#   "email" => ["must be a valid email"],
#   "address.zip" => ["must match pattern"]
# }

Alternatives Considered

  • Validating each field manually - extremely verbose and error-prone
  • Using separate validators for each field - doesn't validate object structure
  • Rails ActiveModel validations - ties you to Rails and different API
  • Dry-validation - different gem, want to keep ecosystem simple

Use Case

User Registration:

  • Validate name, email, password, optional profile fields
  • Address validation with nested structure

API Request Validation:

  • REST API endpoint payloads
  • GraphQL mutation inputs
  • Webhook payload validation

Configuration Objects:

  • Application settings validation
  • Feature flags with nested options
  • Complex form objects

Data Transformation:

  • ETL pipelines
  • Data migration validation
  • Import/export formats

This is essential for any application with forms, API endpoints, or complex data structures. It's the foundation for building type-safe applications in Ruby.

Additional Context

  • This is the most complex validator to implement
  • Consider error message format (flat vs nested hash)
  • Performance with deeply nested objects
  • Rails/ActiveModel integration path
  • Reference: Zod objects https://zod.dev/?id=objects
  • JSON Schema validation patterns
  • Consider thread safety for schema definitions

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions