在改革中填充单一财产



我正在使用Reformgem。假设我有某种形式,我将两个日期作为参数中的两个独立属性传递给它。现在在表单中,我想实例化另一个名为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

populatorprepopulator假定相关属性存在于传入的数据中。在您的情况下,interval不是。

是否要验证interval值?如果没有,请在Operation步骤中计算interval,并且不涉及reform

如果要验证,可以选择:

  • 任一时间戳上的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"
    

最新更新