-
Notifications
You must be signed in to change notification settings - Fork 12
Open
Labels
priority: lowAdvanced features and enhancementsAdvanced features and enhancements
Description
Description
Allow models to define multiple schema variants for different contexts, similar to serializer views or API versioning.
Current State
A model has exactly one schema definition defined by the define_schema block:
class User
include EasyTalk::Model
define_schema do
property :id, Integer
property :name, String
property :email, String
property :password_hash, String
property :admin_notes, String
end
end
User.json_schema # Returns the single schemaProblem
In real-world applications, the same internal model often needs different representations for different contexts:
- Public vs Admin views: Hide sensitive fields from public API
- Create vs Update payloads:
idrequired for update, forbidden for create - API versioning: v1 returns
full_name, v2 returnsfirst_name+last_name - Input vs Output: Different validation rules for receiving vs sending data
Currently, users must create separate model classes for each context, leading to duplication.
Proposed Solution
Allow define_schema to accept a context name:
class User
include EasyTalk::Model
# Default schema (backward compatible)
define_schema do
property :id, Integer
property :name, String
property :email, String
end
# Public API view - excludes sensitive data
define_schema(:public) do
property :id, Integer
property :name, String
end
# Admin view - includes everything
define_schema(:admin) do
property :id, Integer
property :name, String
property :email, String
property :password_hash, String
property :admin_notes, String
property :created_at, DateTime
end
# Create payload - no id
define_schema(:create) do
property :name, String
property :email, String
property :password, String
end
# Update payload - id required, others optional
define_schema(:update) do
property :id, Integer
property :name, String, optional: true
property :email, String, optional: true
end
endUsage
User.json_schema # Default schema
User.json_schema(:public) # Public view
User.json_schema(:admin) # Admin view
User.json_schema(:create) # Create payload schema
User.json_schema(:update) # Update payload schemaSchema Inheritance
Allow contexts to inherit from other contexts:
define_schema(:admin, extends: :public) do
property :admin_notes, String
property :created_at, DateTime
endValidation Context Integration
Optionally tie validation to schema context:
user = User.new(name: 'John')
user.valid? # Validates against default schema
user.valid?(context: :create) # Validates against :create schemaBenefits
- DRY: Define related schemas in one place
- Maintainability: Changes to core fields propagate to contexts (with inheritance)
- Familiar pattern: Similar to ActiveModel Serializers, Blueprinter views
- API flexibility: Easy versioning and role-based responses
- Backward compatible: Default schema works as before
Implementation Considerations
- Store schemas in a hash:
{ default: schema, public: schema, ... } json_schema(context = :default)retrieves specific schema- Schema inheritance via
extends:option - Consider lazy evaluation for inherited schemas
- Validation context integration with ActiveModel
- Clear error messages for undefined contexts
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
priority: lowAdvanced features and enhancementsAdvanced features and enhancements