# Do this instead
field :name, as: :text, visible -> { resource.record&.enabled? }
```

## Computed Fields

You might need to show a field with a value you don't have in a database row. In that case, you may compute the value using a block that receives the `record` (the actual database record), the `resource` (the configured Avo resource), and the current `view`. With that information, you can compute what to show on the field in the <Index /> and <Show /> views.

```ruby
field 'Has posts', as: :boolean do
  record.posts.present?
rescue
  false
end
```

:::info
Computed fields are displayed only on the <Show /> and <Index /> views.
:::

This example will display a boolean field with the value computed from your custom block.

## Fields Formatter

Sometimes you will want to process the database value before showing it to the user.

There are several ways to format fields.

### Common formatting options

In all cases, you have access to a bunch of variables inside this block, all the defaults that `Avo::ExecutionContext` provides plus `value`, `record`, `resource`, `view` and `field`.

<Option name="`format_using`">
Format the field value using a block.

:::info
Notice that this block will have effect on **all** views.
:::

Formatting affects copyable value, when using `format_using` with `copyable`, the formatted value is what gets copied to the clipboard, not the original database value. For example, using `format_using: -> { value.truncate(20) }` will copy the truncated text (including the `...`). If you need to display a truncated value while copying the full value, consider using CSS truncation via the `html` option instead of `format_using`.

```ruby
field :is_writer, as: :text, format_using: -> {
  if view.form?
    value
  else
    value.present? ? '👍' : '👎'
  end
}
```

This example snippet will make the `:is_writer` field generate `👍` or `👎` emojis instead of `1` or `0` values on display views and the values `1` or `0` on form views.

<Image src="/assets/img/fields-reference/fields-formatter.png" width="943" height="156" alt="Fields formatter" />

Another example:

```ruby
field :company_url,
  as: :text,
  format_using: -> {
    if view.new? || view.edit?
      value
    else
      link_to(value, value, target: "_blank")
    end
  } do
  main_app.companies_url(record)
end
```

</Option>

<Option name="`format_{view}_using`">

Avo provides helper methods to format fields based on the current view.

- `format_index_using` - Format the field value **only** for the **index** view
- `format_show_using` - Format the field value **only** for the **show** view
- `format_edit_using` - Format the field value **only** for the **edit** view
- `format_new_using` - Format the field value **only** for the **new** view
- `format_form_using` - Format the field value **only** for the **forms** view (**new** and **edit**)
- `format_display_using` - Format the field value **only** for the **display** view (**index** and **show**)

This methods are available for all fields.

Example on how to format a field in the index and show views:

```ruby
field :is_writer, format_display_using: -> { value.present? ? '👍' : '👎' }
```

<Image src="/assets/img/fields-reference/fields-formatter.png" width="943" height="156" alt="Fields formatter" />

</Option>

## Formatting with Rails helpers

You can also format using Rails helpers like `number_to_currency` (note that `view_context` is used to access the helper):

```ruby
field :price, as: :number, format_using: -> { view_context.number_to_currency(value) }
```

## Parse value before update
When it's necessary to parse information before storing it in the database, the `update_using` option proves to be useful. Inside the block you can access the raw `value` from the form, and the returned value will be saved in the database.

```ruby
field :metadata,
  as: :code,
  update_using: -> do
    ActiveSupport::JSON.decode(value)
  end
```

## Sortable fields

One of the most common operations with database records is sorting the records by one of your fields. For that, Avo makes it easy using the `sortable` option.

Add it to any field to make that column sortable in the <Index /> view.

```ruby
field :name, as: :text, sortable: true
```

<Image src="/assets/img/fields-reference/sortable-fields.png" width="406" height="363" alt="Sortable fields" />

**Related:**
  - Add an index on the `created_at` column

## Custom sortable block

When using computed fields or `belongs_to` associations, you can't set `sortable: true` to that field because Avo doesn't know what to sort by. However, you can use a block to specify how the records should be sorted in those scenarios.

```ruby{4-7}
class Avo::Resources::User < Avo::BaseResource
  field :is_writer,
    as: :text,
    sortable: -> {
      # Order by something else completely, just to make a test case that clearly and reliably does what we want.
      query.order(id: direction)
    },
    hide_on: :edit do
      record.posts.to_a.size > 0 ? "yes" : "no"
    end
end
```

The block receives the `query` and the `direction` in which the sorting should be made and must return back a `query`.

In the example of a `Post` that `has_many` `Comment`s, you might want to order the posts by which one received a comment the latest.

You can do that using this query.

::: code-group

```ruby{5} [app/avo/resources/post.rb]
class Avo::Resources::Post < Avo::BaseResource
  field :last_commented_at,
    as: :date,
    sortable: -> {
      query.includes(:comments).order("comments.created_at #{direction}")
    }
end
```

```ruby{4-6} [app/models/post.rb]
class Post < ApplicationRecord
  has_many :comments

  def last_commented_at
    comments.last&.created_at
  end
end
```

:::

## Placeholder

Some fields support the `placeholder` option, which will be passed to the inputs on <Edit /> and <New /> views when they are empty.

```ruby
field :name, as: :text, placeholder: 'John Doe'
```

<Image src="/assets/img/fields-reference/placeholder.png" width="946" height="160" alt="Placeholder option" />

## Required
To indicate that a field is mandatory, you can utilize the `required` option, which adds an asterisk to the field as a visual cue.

Avo automatically examines each field to determine if the associated attribute requires a mandatory presence. If it does, Avo appends the asterisk to signify its mandatory status. It's important to note that this option is purely cosmetic and does not incorporate any validation logic into your model. You will need to manually include the validation logic yourself, such as (`validates :name, presence: true`).

```ruby
field :name, as: :text, required: true
```

<Image src="/assets/img/fields-reference/required.png" width="949" height="156" alt="Required option" />

<DemoVideo demo-video="https://youtu.be/peKt90XhdOg?t=937" />

You may use a block as well. It will be executed in the `Avo::ExecutionContext` and you will have access to the `view`, `record`, `params`, `context`, `view_context`, and `current_user`.

```ruby
field :name, as: :text, required: -> { view == :new } # make the field required only on the new view and not on edit
```

## Disabled

When you need to prevent the user from editing a field, the `disabled` option will render it as `disabled` on <New /> and <Edit /> views and the value will not be passed to that record in the database. This prevents a bad actor to go into the DOM, enable that field, update it, and then submit it, updating the record.

```ruby
field :name, as: :text, disabled: true
```

<Image src="/assets/img/fields-reference/readonly.png" width="953" height="164" alt="Disabled option" />

### Disabled as a block

<VersionReq version="2.14" class="mt-2" />

You may use a block as well. It will be executed in the `Avo::ExecutionContext` and you will have access to the `view`, `record`, `params`, `context`, `view_context`, and `current_user`.

```ruby
field :id, as: :number, disabled: -> { view == :edit } # make the field disabled only on the new edit view
```

## Readonly

When you need to prevent the user from editing a field, the `readonly` option will render it as `disabled` on <New /> and <Edit /> views. This does not, however, prevent the user from enabling the field in the DOM and send an arbitrary value to the database.

```ruby
field :name, as: :text, readonly: true
```

<Image src="/assets/img/fields-reference/readonly.png" width="953" height="164" alt="Readonly option" />

## Default Value

When you need to give a default value to one of your fields on the <New /> view, you may use the `default` block, which takes either a fixed value or a block.

```ruby