dry-schema icon indicating copy to clipboard operation
dry-schema copied to clipboard

Deeply nested recursive attributes

Open vrtsev opened this issue 5 years ago • 12 comments

Hi, i'm using v 0.11.0 in hanami framework. I have following params:

{
    "body": {
        "type": "doc",
        "content": [
            {
                "type": "paragraph",
                "content": [
                    {
                        "type": "paragraph",
                        "content": [
                        	{
                        	   "type": "text",
                        	   "text": "something"
                        	}

Each 'content' param contains repeatable attributes from previous section. I'm trying to do something like this:

sch = Dry::Validation.Form do
    required(:type).value(included_in?: ALLOWED_TYPES)
    optional(:content).each do
      schema(  # --  HERE I NEED TO CHECK THE SAME ATTRIBUTES --)
  end
end

Is it possible to call recursively the same schema?

vrtsev avatar Apr 29 '19 15:04 vrtsev

Hey, this is not supported, but that's an interesting use case. Is there a limit how deep this can go?

solnic avatar May 02 '19 19:05 solnic

@solnic Thanks for your response. In my case there is max 5 nested levels. For better understanding I'm using https://tiptap.scrumpy.io/export lib on frontend that generates JSON with nested elements according to user's post formatting. But I think it would be great if there will be ability to iterate & validate all received nested content without knowing exact nesting levels

vrtsev avatar May 03 '19 08:05 vrtsev

@vrtsev this is something that we can consider to add in the future. We'll see if more people ask about it.

ps. I moved your issue from dry-validation to dry-schema because this is the new engine for schema DSL and it's used in dry-validation 1.0.0 (soon to be released).

solnic avatar May 04 '19 16:05 solnic

👍 I'll add my vote to the mix. I was trying to accomplish something similar with dry-types.

class A < Dry::Struct
  attribute :type, Types::Coercible::String.constrained(eq: "a")
  attribute :child, self | B
end

class B < Dry::Struct
  attribute :type, Types::Coercible::String.constrained(eq: "b")
  attribute :child, self | A
end

class Z < Dry::Struct
  attribute :type, Types::Coercible::String.constrained(eq: "z")
end

class Root < Dry::Struct
  attribute :child, A | B | Z
end

Root.new({
  child: {
    type: "a",
    child: {
      type: "b",
      child: {
        type: "b",
        child: {
          type: "a",
          child: {
            type: "z"
          }
        }
      }
    }
  }
})

iamveen avatar Jun 13 '19 01:06 iamveen

I've just run into the same issue trying to make a dry-schema for a node in a decision tree, so +1 from me

ChrisMarffy avatar Oct 18 '22 12:10 ChrisMarffy

I would use this feature too.

masterT avatar Nov 22 '22 11:11 masterT

Same as the guys above.

PeterRunich avatar Dec 29 '22 11:12 PeterRunich

+1

twmills avatar May 24 '23 17:05 twmills

+1 here

pyromaniac avatar Oct 23 '23 02:10 pyromaniac

If any of you folks would like to have a go at implementing this, I'd be happy to support you.

timriley avatar Oct 23 '23 04:10 timriley