override defaults

Override the field method to add default values to field options

July 08, 2024 09:00

As with any framework, Avo has its own set of opinions. One of our principles is to minimize the manipulation of data before saving it. Our goal is to stay out of your way while providing the right tools to get your job done.

Recently, a customer suggested automatically converting all values from the number field to integers or at least floats. While this might seem straightforward for a number field, it can actually cause more issues than it solves. Some users prefer the value as a string, others need it as an integer, and some require the decimal points to remain.

So, what do we do? Nothing! ๐Ÿ˜ฑ

That's right! We don't make any assumptions. We simply pass the input to the record as is, resulting in a string.

But what if you need it as an integer or float?

No worries! We have a solution for that. You can use the format_using field option. This option accepts a block with several objects, including the value object, which represents the actual value of the field.

field :height, as: :number, format_using: -> { value.to_f }

This block's output will be passed to the record.

# equivalent to
user_params = params.require(:user).permit(:height)
value = user_params[:height]
user.height = value.to_f

That's it! ๐ŸŽ‰

Make this the default for all fields

You can easily set this as the default behavior.

Since most of Avo's DSL is simply Ruby code, you have two options:

  1. Create a new method that applies this formatting
  2. Extend the existing field method to include this formatting
# 1. Create a new method
def float_field(id, **args, &)
  args[:format_using] = -> (value) { value.to_f }
  args[:as] = :number

  field id, **args, &

# Use it like this
float_field :height

# 2. Extend the current `field` method
def field(id, **args, &)
  if args[:as] == :number
    args[:format_using] = -> (value) { value.to_f }

  super id, **args, &

# Use it as usual
field :height, as: :number

Simple and effective!