Заполнение одного свойства в реформе - PullRequest
1 голос
/ 03 февраля 2020

Я использую Reform драгоценный камень. Допустим, у меня есть какая-то форма, которой я передаю две даты как два отдельных атрибута в параметрах. Теперь в форме я хочу создать другой атрибут (который также является атрибутом существующей модели) с именем interval, чтобы вычислить интервал между этими двумя датами, а затем сохранить его в модели.

# some_form.rb

class SomeForm < Reform::Form
   property: :starts_on
   property: :ends_on
   property: :interval
end

Каков наилучший способ заполнить интервал на основе входящих дат, проверить его и сохранить на модели?

Я пробовал разные вещи, от переопределения метода validate и использования параметров populator / prepopulator, но безрезультатно.

В лучшем случае я бы предположил, что это будет выглядеть так:

class SomeForm < Reform::Form
   property: :starts_on
   property: :ends_on
   property: :interval, populate: :calculate_interval
end

def calcute_interval
    (starts_on..ends_on).count
end

1 Ответ

0 голосов
/ 03 февраля 2020

populator и prepopulator предполагают, что соответствующие свойства присутствуют во входящих данных. В вашем случае interval не является.

Вы хотите проверить значение interval? Если нет, вычислите interval с шагом Operation и не включайте reform.

Если вы хотите проверить, ваши варианты:

  • a populator на любой временной метке:

    # some_form.rb
    class SomeForm < Reform::Form
      property :starts_on
      property :ends_on, populator: ->(model:, fragment:, **) do
        self.interval = fragment - starts_on
        self.ends_on = fragment
      end
      property :interval, readable: false
    
      validation do
        required(:starts_on).filled(:time?)
        required(:ends_on).filled(:time?)
        required(:interval).filled(gt?: 2.hours) # or whatever value you like
      end
    end
    
  • пользовательский предикат + правило комбинированный:

    # some_form.rb
    class SomeForm < Reform::Form
      property :starts_on
      property :ends_on
    
      # NOTE: uses dry-validation v0.13 syntax
      validation do
          configure do
            config.messages_file = "/path/to/your/error_messages.yml"
    
            def gt?(interval, starts_on, ends_on)
              ends_on - starts_on > interval
            end
          end
        end
    
        required(:starts_on).filled(:time?)
        required(:ends_on).filled(:time?)
        rule(ends_on: [:ends_on, :starts_on]) do |ends_on, starts_on|
          ends_on.gt?(starts_on, 2.hours) # or whatever value you like
        end
      end
    end
    
    # error_messages.yml
    en:
      errors:
        rules:
          ends_on:
            gt?: "must be greater than starts_on by %{interval} seconds"
    
    
...