# config/initializers/avo.rb
Avo.configure do |config|
  config.buttons_on_form_footers = true
end
```

<Image src="/assets/img/resources/buttons_on_footer.png" width="1276" height="594" alt="Buttons on footer" />

</Option>

<Option name="`after_create_path`/`after_update_path`">

For some resources, it might make sense to redirect to something other than the `Show` view. With `after_create_path` and `after_update_path` you can control that.

The valid options are `:show` (default), `:edit`, or `:index`.

```ruby{2-3}
class Avo::Resources::Comment < Avo::BaseResource
  self.after_create_path = :index
  self.after_update_path = :edit
end
```

### Related

You can go more granular and customize these paths or response more using controller methods.

 - `after_create_path`
 - `after_update_path`
 - `after_destroy_path`
</Option>

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

You might have resources that will never be selected, and you do not need that checkbox to waste your horizontal space.

You can hide it using the `record_selector` class_attribute.

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

<Image src="/assets/img/resources/record_selector.png" width="688" height="361" alt="Hide the record selector." />
</Option>

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

Let's take an example. We have a `Person` model and `Sibling` and `Spouse` models that inherit from it using Single Table Inheritance (STI).

When you declare this option on the parent resource `Person` it has the following effect. When a user is on the <Index /> view of your the `Person` resource and clicks to visit a `Person` record they will be redirected to a `Child` or `Spouse` record instead of a `Person` record.

```ruby
class Avo::Resources::Person < Avo::BaseResource
  self.link_to_child_resource = true
end
```
</Option>

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

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

There are scenarios where you wouldn't want to close the filters panel when you change the values. For that, you can use the `keep_filters_panel_open` resource option.

```ruby{2}
class Avo::Resources::Course < Avo::BaseResource
  self.keep_filters_panel_open = true

  def fields
    field :id, as: :id
    field :name, as: :text
  end

  def filters
    filter Avo::Filters::CourseCountryFilter
    filter Avo::Filters::CourseCityFilter
  end
end
```

<Image src="/assets/img/filters/keep-filters-panel-open.gif" width="449" height="800" alt="Avo filters" />
</Option>

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

By default, for each view we render an component:

Index -> `Avo::Views::ResourceIndexComponent`<br>
Show -> `Avo::Views::ResourceShowComponent`<br>
New, Edit -> `Avo::Views::ResourceEditComponent`

It's possible to change this behavior by using the `self.components` resource option.

```ruby
self.components = {
  resource_index_component: Avo::Views::Users::ResourceIndexComponent,
  resource_show_component: "Avo::Views::Users::ResourceShowComponent",
  resource_edit_component: "Avo::Views::Users::ResourceEditComponent",
  resource_new_component: Avo::Views::Users::ResourceEditComponent
}
```

<VersionReq version="3.11.8" /> more components can be replaced. From this version, keys must be strings that match the original component with the exception of those from the snippet above.

Here is a list of all the supported customizable components:

```ruby
self.components = {
  "Avo::Views::ResourceIndexComponent": Avo::Custom::ResourceIndexComponent,
  "Avo::Views::ResourceShowComponent": "Avo::Custom::ResourceShowComponent",
  "Avo::Views::ResourceEditComponent": "Avo::Custom::ResourceEditComponent",
  "Avo::Index::GridItemComponent": "Avo::Custom::GridItemComponent",
  "Avo::Index::ResourceMapComponent": "Avo::Custom::ResourceMapComponent",
  "Avo::Index::ResourceTableComponent": "Avo::Custom::ResourceTableComponent",
  "Avo::Index::TableRowComponent": "Avo::Custom::TableRowComponent"
}
```

A resource configured with the example above will start using the declared components instead the default ones.

:::warning
The custom view components must ensure that their initializers are configured to receive all the arguments passed during the rendering of a component. You can verify this in our codebase through the following files:

Index -> `app/views/avo/base/index.html.erb`<br>
Show -> `app/views/avo/base/show.html.erb`<br>
New -> `app/views/avo/base/new.html.erb`<br>
Edit -> `app/views/avo/base/edit.html.erb`
:::
Creating a customized component for a view is most easily achieved by ejecting one of our pre-existing components using the `--scope` parameter. You can find step-by-step instructions in the documentation here.

Alternatively, there is another method which requires two additional manual steps. This involves crafting a personalized component by extracting an existing one and adjusting its namespace. Although changing the namespace is not mandatory, we strongly recommend it unless you intend for all resources to adopt the extracted component.

Example:
1. Execute the command `bin/rails generate avo:eject --component Avo::Views::ResourceIndexComponent` to eject the specified component.<br><br>
2. Access the newly ejected file and adjust the namespace. You can create a fresh directory like `my_dir` and transfer the component to that directory.<br><br>
2. You have the flexibility to establish multiple directories, just ensure that the class name corresponds to the path of the directories.<br><br>
3. Update the class namespace in the file from `Avo::Views::ResourceIndexComponent` to `Avo::MyDir::Views::ResourceIndexComponent`.<br><br>
4. You can now utilize the customized component in a resource.

```ruby
self.components = {
  resource_index_component: Avo::MyDir::Views::ResourceIndexComponent
}
```

This way you can choose the whatever namespace structure you want and you assure that the initializer is accepting the right arguments.
</Option>

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

### Unscoped queries on `Index`

You might have a `default_scope` on your model that you don't want to be applied when you render the `Index` view.
```ruby{2}
class Project < ApplicationRecord
  default_scope { order(name: :asc) }
end
```

You can unscope the query using the `index_query` method on that resource.

```ruby{3}
class Avo::Resources::Project < Avo::BaseResource
  self.title = :name
  self.index_query = -> { query.unscoped }
end
```
</Option>

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

<VersionReq version="3.10.7" />

By default, Avo sorts records on the <Index /> view by the `created_at` attribute. However, you can customize this behavior using the `default_sort_column` option in your resource file.

#### Default

`:created_at`

#### Possible values

Any symbol representing a sortable column in your model. If the specified column doesn't exist in the model, Avo will fall back to the default sort column (`created_at`).

```ruby
class Avo::Resources::User < Avo::BaseResource
  self.default_sort_column = :last_name

  def fields
    field :id, as: :id
    field :last_name, as: :text
  end

  # other resource configurations...
end
```

:::info
When changing the default sort column, it's recommended to add an index to that column in your database for better query performance.

```ruby