# app/avo/resources/comment.rb
class Avo::Resources::Comment < Avo::BaseResource
  self.title = -> {
    ActionView::Base.full_sanitizer.sanitize(record.body).truncate 30
  }
end
```
</Option>

<Option name="`self.description`">

You might want to display information about the current resource to your users. Then, using the `description` class attribute, you can add some text to the `Index`, `Show`, `Edit`, and `New` views.

<Image src="/assets/img/resources/description.png" width="1272" height="216" alt="Avo message" />

There are two ways of setting the description. The quick way as a `string` and the more customizable way as a `block`.

### Set the description as a string

```ruby{3}
class Avo::Resources::User < Avo::BaseResource
  self.title = :name
  self.description = "These are the users of the app."
end
```

This is the quick way to set the label, and it will be displayed **on all pages**. If you want to restrict the message to custom views, use a lambda function.

### Set the description as a block

This is the more customizable method where you can access the `record`, `resource`, `view`, `current_user`, and `params` objects.

```ruby{3-13}
class Avo::Resources::User < Avo::BaseResource
  self.title = :name
  self.description = -> do
    if view == :index
    "These are the users of the app"
    else
      if current_user.is_admin?
        "You can update all properties for this user: #{record.id}"
      else
        "You can update some properties for this user: #{record.id}"
      end
    end
  end
end
```
</Option>

<Option name="`self.includes`">

If you regularly need access to a resource's associations, you can tell Avo to eager load those associations on the `Index` view using `includes`.

That will help you avoid those nasty `n+1` performance issues.

```ruby
class Avo::Resources::Post < Avo::BaseResource
  self.includes = [:user, :tags]

  # or a very nested scenario
  self.includes = [files_attachments: :blob, users: [:comments, :teams, post: [comments: :user]]]
end
```

We know, the array notation looks weird, but it works.

</Option>

<Option name="`self.single_includes`">

`single_includes` works the same as `includes` but it's going to eager load the associations on the <Show /> and <Edit /> views only.
</Option>

<Option name="`self.attachments`">

Similar to how `includes` works, you can use `attachments` to eager load attachments on the `Index` view.

:::code-group
```ruby{2-4} [app/models/post.rb]
class Post < ApplicationRecord
  has_one_attached :cover_photo
  has_one_attached :audio
  has_many_attached :attachments
end
```

```ruby{5-7} [app/avo/resources/post.rb]
class Avo::Resources::Post < Avo::BaseResource
  self.attachments = [:cover_photo, :audio, :attachments]
end
```
:::

</Option>

<Option name="`self.single_attachments`">

`single_attachments` works the same as `attachments` but it's going to eager load the attachments on the <Show /> and <Edit /> views only.

</Option>

<Option name="`self.confirm_on_save`">

<VersionReq version="3.10.10" />
If you would like to ask for confirmation when saving a resource you can do so by setting `confirm_on_save` to `true`.

That will help add friction to the saving process, avoiding human error.

```ruby
class Avo::Resources::Post < Avo::BaseResource
  self.confirm_on_save = true
end
```

This option defaults to false

<Image src="/assets/img/customization/confirm-on-save.png" width="2494" height="845" alt="Confirm on save" />

</Option>

<Option name="`default_view_type`">

On <Index />, the most common view type is `:table`, but you might have some data that you want to display in a `:grid` or `:map`. You can change that by setting `default_view_type` to `:grid` and by adding the `grid` block.

<Image src="/assets/img/grid-view.jpg" width="1312" height="1096" alt="Avo grid view" />

```ruby{2}
class Avo::Resources::Post < Avo::BaseResource
  self.default_view_type = :grid
end
```

Find out more on the grid view documentation page.

<VersionReq version="3.5.6" /> `default_view_type` become callable. Within this block, you gain access to all attributes of `Avo::ExecutionContext` along with the `resource` and `view`. Example:

```ruby
class Avo::Resources::Post < Avo::BaseResource
  self.default_view_type = -> {
    mobile_user = request.user_agent =~ /Mobile/

    mobile_user ? :table : :grid
  }
end
```

</Option>

<Option name="`self.model_class`">

For some resources you might have a model that is namespaced, or you might have a secondary resource for a model. For that scenario, you can use the `self.model_class` option to tell Avo which model to reference in that resource.

```ruby{2}
class Avo::Resources::DelayedJob < Avo::BaseResource
  self.model_class = "Delayed::Job"

  def fields
    field :id, as: :id
  end
end
```

</Option>

<Option name="`self.devise_password_optional`">

If you use `devise` and update your user models (usually `User`) without passing a password, you will get a validation error. You can use `devise_password_optional` to stop receiving that error. It will [strip out](https://stackoverflow.com/questions/5113248/devise-update-user-without-password/11676957#11676957) the `password` key from `params`.

```ruby
class Avo::Resources::User < Avo::BaseResource
  self.devise_password_optional = true
end
```

### Related

- Password field

</Option>

<Option name="`self.visible_on_sidebar`">

When you get started, the sidebar will be auto-generated for you with all the dashboards, resources, and custom tools.
However, you may have resources that should not appear on the sidebar, which you can hide using the `visible_on_sidebar` option.

```ruby{2}
class Avo::Resources::TeamMembership < Avo::BaseResource
  self.visible_on_sidebar = false
end
```

:::warning
This option is used in the **auto-generated menu**, not in the menu editor.

You'll have to use your own logic in the `visible` block for that.
:::
</Option>

<Option name="`config.buttons_on_form_footers`">

If you have a lot of fields on a resource, that form might get pretty tall. So it would be useful to have the `Save` button in the footer of that form.

You can do that by setting the `buttons_on_form_footers` option to `true` in your initializer. That will add the `Back` and `Save` buttons on the footer of that form for the `New` and `Edit` screens.

```ruby{3}