Reusing schema definition and validating Hash
Nobody has claimed this yet.
- Dominant language
- Ruby
- Stars
- 492
- Forks
- 123
- PR merge metrics
- No merged PRs in 30d
Description
Describe the bug
I'm having some schemas defined used in a contract for validating the HTTP params when creating an App, which can contain also an image as attachment (using nested attributes).
# frozen_string_literal: true
module Apps
module Schemas
class Base < Dry::Schema::Params
define do
required(:name).filled(:string, min_size?: 3)
optional(:description).maybe(:string)
optional(:public).filled(:bool)
optional(:status).filled(:string, included_in?: %w[draft in_review approved published])
optional(:contact_email).maybe(:string)
optional(:image_attributes).maybe(:hash) do
::Attachments::Schemas::Base.new
end
end
end
end
end
Since the Attachments can be reused in other models as well, it was extracted into an own schema.
# frozen_string_literal: true
module Attachments
module Schemas
class Base < Dry::Schema::Params
define do
optional(:id).maybe(:integer)
optional(:type).maybe(:string)
optional(:file).maybe(:string)
optional(:_destroy).maybe(:bool)
end
end
end
end
And this would be the App contract.
# frozen_string_literal: true
module Apps
module Contracts
class Base < Dry::Validation::Contract
params(::Apps::Schemas::Base.new)
end
end
end
The problem I'm seeing is that the contract will not extract the image_attributes from the params if I validate the image_attributes to be a hash.
To Reproduce
Set the params to be:
{
"id": "some_id",
"name": "test",
"description": "test",
"public": false,
"status": "draft",
"contact_email": nil,
"image_attributes":
{
"file": "{some payload}}",
"url": "https://some_url",
"type": "ImageAttachment"
}
}
and check the contract:
contract = ::Apps::Contracts::Base.new.call(params)
the result will not have image_attributes set:
#<Dry::Validation::Result{:name=>"test", :description=>"test", :public=>false, :status=>"draft", :contact_email=>nil, :image_attributes=>{}} errors={}>
Expected behavior
To extract the image_attributes from the params.
IMPORTANT:
I noticed that validating the image_attributes to be a hash works also fine when the attachment attributes are directly defined in the schema (cannot reuse the Attachment::Schema::Base):
optional(:image_attributes).maybe(:hash) do
optional(:id).maybe(:integer)
optional(:type).maybe(:string)
optional(:file).maybe(:string)
optional(:_destroy).maybe(:bool)
end
Your environment
- Ruby version: 2.6.6
- OS: Linux
- dry-validation: 1.5
- dry-schema: 1.5
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with Apps::Schemas::Base, Attachments::Schemas::Base, and Apps::Contracts::Base, then reproduce the result from contract.call(params) using the nested image_attributes hash. Trace how the reusable attachment schema is applied under the hash validation and compare it with the inline definition. Done means the validated result preserves the image_attributes values while retaining the existing validation behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ruby
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100