I have several forms that submit to a Virtus object (through a controller). Some forms contain an extras attribute, others don't.
I currently can't distinguish whether extras has been set to an empty array (i.e. the user deselects all checkboxes on the form) or whether extras has never been submitted. In either case, extras will be an empty array.
I need this distinction because if the user deselects all extras I need to update them. On the other hand, if extras were not part of the form (i.e. not in the params), I shouldn't update them.
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
How can I make Virtus to give me a nil on extras if I call it like this:
UpdateForm.new(booking_time: Time.current)
Or is there a better pattern to do this?
By default @extras attribute will be set to an empty array (even if you add default: nil to the attribute).
What you can do is to override initializer so it will set @extras to nil unless it was actually defined.
And use #nil? instead of #blank? which returns true on empty array.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With