我有几种表单(通过 Controller )提交给Virtus对象。有些表格包含extras属性,有些则没有。

我目前无法区分extras是否已设置为空数组(即用户取消选择了表单上的所有复选框)还是未提交额外内容。无论哪种情况,extras都是一个空数组。

我需要这种区别,因为如果用户取消选择所有extras,则需要更新它们。另一方面,如果Extras不是该表单的一部分(即不在params中),则我不应该对其进行更新。

class UpdateForm
  include Virtus.model(nullify_blank: true)
  include ActiveModel::Model
  attribute :extras, Array
  attribute :booking_time, Time

  def save
    updatable_attributes = self.attributes.delete_if { |key, value| value.blank? }
    some_object.update(updatable_attributes)
  end
end

如果我这样称呼我,我该如何使Virtus对extras无效:
UpdateForm.new(booking_time: Time.current)

还是有更好的模式来做到这一点?

最佳答案

默认情况下,@extras属性将设置为空数组(即使您将add default: nil设置为该属性)。
您可以做的是重写初始化程序,以便除非实际定义了它,否则它将@extras设置为nil
并使用#nil?而不是#blank?,它在空数组上返回true。

class UpdateForm
  include Virtus.model(nullify_blank: true)
  include ActiveModel::Model
  attribute :extras, Array
  attribute :booking_time, Time

  def initialize(opts={})
    super
    @extras = nil unless (opts[:extras] || opts['extras'])
  end

  def save
    updatable_attributes = self.attributes.delete_if { |key, value| value.nil? }
    some_object.update(updatable_attributes)
  end
end

关于ruby-on-rails - Virtus : distinguish empty arrays from an unset attribute,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31954440/

10-10 01:35