# Extending a validation schema

**URL:** <https://discourse.dry-rb.org/t/extending-a-validation-schema/638>\
**Category:** dry-validation\
**Created:** [October 22, 2018, 11:10am UTC](https://discourse.dry-rb.org/t/extending-a-validation-schema/638 "2018-10-22T11:10:01Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![krisleech](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/krisleech/32/19_2.png) [@krisleech](https://discourse.dry-rb.org/u/krisleech)\
**Post date:** [October 22, 2018, 11:10am UTC](https://discourse.dry-rb.org/t/extending-a-validation-schema/638/1 "2018-10-22T11:10:01Z")

</div>

I’m working on switching a project from ActiveRecord validations to dry-validations. Some of the ActiveRecord models are in a Rails engine and re-opened in a Rails application to add additional validations. In the short term I’d like to mimic this.

```
# in the engine
class Form < Dry::Struct
  def schema
    @schema ||= Dry::Validation.Params do
      required(:short_title).filled
    end
  end
end

```

In essence I want to take the original schema and extend it.

My guess is that it that the schema object is frozen so it isn’t directly possible. So my first idea was composition:

```
# in the app, re-opening the class and adding more validations
class Form
  def schema 
    @schema ||= Dry::Validation.Params do
      schema { super } # merge original validations
      required(:email).filled # add new validation
    end
  end
end

```

However I’m monkey patching so I can’t call `super`. Even so it does not seem to work:

```
v1 = Dry::Validation.Params { required(:name).filled }
v2 = Dry::Validation.Params { schema { v1 } }
v2.call(name: nil).errors # => {}

```

Any pointers/thought would be appreciated.

---

<div class="post-metadata">

**Author:** ![krisleech](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/krisleech/32/19_2.png) [@krisleech](https://discourse.dry-rb.org/u/krisleech)\
**Post date:** [October 22, 2018, 3:57pm UTC](https://discourse.dry-rb.org/t/extending-a-validation-schema/638/2 "2018-10-22T15:57:47Z")

</div>

I can get some of the way with:

```
class V1 < Dry::Validation::Schema
  define! { required(:short_title).filled }
end

V2 = Dry::Validation.Params(V1) { required(:email).filled }

```

But that means I have to define the schema in two different ways.

And also using inheritance:

```
class V1 < Dry::Validation::Schema
  define! { required(:short_title).filled }
end

class V2 < V1
  define! { required(:email).filled }
end
```

---

<div class="post-metadata">

**Author:** ![art-solopov](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/art-solopov/32/310_2.png) [@art-solopov](https://discourse.dry-rb.org/u/art-solopov)\
**Post date:** [October 27, 2018, 7:59pm UTC](https://discourse.dry-rb.org/t/extending-a-validation-schema/638/3 "2018-10-27T19:59:53Z")

</div>

There are several ways to inherit schema without necessarily writing the class.

The key to the first one is the `build` option in the `Dry::Validation.Schema` method:

```ruby
S1 = Dry::Validation.Schema(build: false) do
  required(:name).filled
end

S2 = Dry::Validation.Params(S1) do
  required(:age).filled(:int?, gt?: 0)
end

```

Be warned, however, that `S1` in this case would be the **class** of the schema, not the schema itself. So instead of doing this:

```ruby
S1.({name: 'William'})

```

You will have to do this:

```ruby
S1.new.({name: 'William'})

```

The second option is just use the parent schema’s class in the child schema:

```ruby
S1 = Dry::Validation.Schema do
  required(:name).filled
end

S2 = Dry::Validation.Params(S1.class) do
  required(:age).filled(:int?, gt?: 0)
end

```

---

<div class="post-metadata">

**Author:** ![swinner2](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/swinner2/32/278_2.png) [@swinner2](https://discourse.dry-rb.org/u/swinner2)\
**Post date:** [November 3, 2018, 9:54pm UTC](https://discourse.dry-rb.org/t/extending-a-validation-schema/638/4 "2018-11-03T21:54:46Z")

</div>

Is there a way to extend more than one schema?
