# Dry-validation: extract method

**URL:** <https://discourse.dry-rb.org/t/dry-validation-extract-method/258>\
**Category:** dry-validation\
**Created:** [April 27, 2017, 5:54pm UTC](https://discourse.dry-rb.org/t/dry-validation-extract-method/258 "2017-04-27T17:54:11Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![cutalion](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/cutalion/32/99_2.png) [@cutalion](https://discourse.dry-rb.org/u/cutalion)\
**Post date:** [April 27, 2017, 5:54pm UTC](https://discourse.dry-rb.org/t/dry-validation-extract-method/258/1 "2017-04-27T17:54:11Z")

</div>

Hi there!

Is it possible to extract and reuse methods inside Form (Schema)?

```auto
DryRequestForm = Dry::Validation.Form do
  configure do
    option :time_zone, String

    def time_span(date, start_hour, end_hour, time_zone)
      TimeRange.new(
        date: date,
        start_hour: start_hour,
        end_hour: end_hour,
        time_zone: time_zone
      ).range
    end
  end

  #... other fields
  required(:user_id).filled
  required(:date).filled(:date?)
  required(:start).filled(:int?, included_in?: START_HOURS)
  required(:end).filled(:int?, included_in?: END_HOURS)

  validate(:range_is_valid: [:date, :start, :end, :time_zone]) do |date, start_hour, end_hour, tz|
    time = time_span(date, start_hour, end_hour, tz)

    (time.begin >= Time.current + 2.hours) && (time.end > time.begin)
  end

  validate(:user_is_available, [:date, :start, :end, :time_zone, :user_id]) do |date, start_hour, end_hour, tz, user_id|
    time = time_span(date, start_hour, end_hour, tz)

    User.find(user_id).available?(time)
  end
end

```

I’d like to extract this time range object. It’d be nice if I could just define a method which can access all needed fields.  
Like so:

```auto
DryRequestForm = Dry::Validation.Form do
  configure do
    option :time_zone, String
  end

  # fields and validations

  validate(:user_is_available) { user.available?(time_span) }

  def user
    User.find(user_id)
  end

  def time_span
    TimeRange.new(
      date: date,
      start_hour: start_hour,
      end_hour: end_hour,
      time_zone: time_zone
    ).range
  end
end

```

Passing all params explicitly around is now way. (1-3 is ok, but no more)  
Is it possible to write cleaner code for complex schemas?
