Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

array field and resource #335

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/.vitepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ const config = {
text: "CRUD UI",
items: [
{text: "Resources", link: "/3.0/resources.html"},
{text: "Array Resources", link: "/3.0/array-resources.html"},
{text: "Fields", link: "/3.0/fields.html"},
{text: "Field options", link: "/3.0/field-options.html"},
{text: "Controller configuration", link: "/3.0/controllers.html"},
Expand Down
106 changes: 106 additions & 0 deletions docs/3.0/array-resources.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
version: '3.16.2'
license: community
---

# Array Resources

## Overview

An **Array Resource** is a flexible resource that can be backed by an **array of hashes** or an **array of Active Record objects**. It is not constrained to an Active Record model and allows dynamic data handling.

:::info Related field
The Array Resource can be used in conjunction with the `Array` field to manage structured array data in your resources.

For more details on using the `Array` field, including examples and hierarchy of data fetching, check out the [Array Field documentation](./fields/array).

This integration allows for seamless configuration of dynamic or predefined array-based data within your application.
:::

## Creating an Array Resource

Generate an **Array Resource** using the `--array` flag:

```bash
bin/rails generate avo:resource Movie --array
```

This sets up a resource designed to work with an array of data.

## Defining the `records` Method

The `records` method serves as the fallback source for data in the resource. It returns an array of hashes or Active Record objects.

### Example

```ruby
def records
[
{
id: 1,
name: "The Shawshank Redemption",
release_date: "1994-09-23"
},
{
id: 2,
name: "The Godfather",
release_date: "1972-03-24",
fun_fact: "The iconic cat in the opening scene was a stray found by director Francis Ford Coppola on the studio lot."
},
{
id: 3,
name: "Pulp Fiction",
release_date: "1994-10-14"
}
]
end
```

## Defining Fields

Array Resources use fields like any other Avo resource. Here’s an example for a `Movie` resource:

```ruby
class Avo::Resources::Movie < Avo::Resources::ArrayResource
def records
[
{
id: 1,
name: "The Shawshank Redemption",
release_date: "1994-09-23"
},
{
id: 2,
name: "The Godfather",
release_date: "1972-03-24",
fun_fact: "The iconic cat in the opening scene was a stray found by director Francis Ford Coppola on the studio lot."
},
{
id: 3,
name: "Pulp Fiction",
release_date: "1994-10-14"
}
]
end

def fields
main_panel do
field :id, as: :id
field :name, as: :text
field :release_date, as: :date
field :fun_fact, only_on: :index, visible: -> { resource.record.fun_fact.present? } do
record.fun_fact.truncate_words(10)
end

sidebar do
field :fun_fact do
record.fun_fact || "There is no register of a fun fact for #{record.name}"
end
end
end
end
end
```


TODO: link to array field and vice versa
77 changes: 77 additions & 0 deletions docs/3.0/fields/array.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
version: '3.16.2'
license: community
---

# Array

The `Array` field in allows you to display and manage structured array data. This field supports flexibility in fetching and rendering data, making it suitable for various use cases.

:::warning Important
To use the `Array` field, you must create a resource specifically for it. Refer to the [Array Resource documentation](../array-resources) for detailed instructions.

For example, to use `field :attendees, as: :array`, you can generate an array resource by running the following command:

```bash
rails generate avo:resource Attendee --array
```

This step ensures the proper setup of your array field within the Avo framework.
:::

### Example 1: Array field with a block

You can define array data directly within a block. This is useful for static or pre-configured data:

```ruby{3-8}
class Avo::Resources::Course < Avo::BaseResource
def fields
field :attendees, as: :array do
[
{ id: 1, name: "John Doe", role: "Software Developer", organization: "TechCorp" },
{ id: 2, name: "Jane Smith", role: "Data Scientist", organization: "DataPros" }
]
end
end
end
```

### Example 2: Array field fetching data from the model's method

If no block is defined, Avo will attempt to fetch data by calling the corresponding method on the model:

```ruby
class Course < ApplicationRecord
def attendees
User.all.first(6) # Example fetching first 6 users
end
end
```

Here, the `attendees` field will use the `attendees` method from the `Course` model to render its data dynamically.

### Example 3: Fallback to the `records` method

If neither the block nor the model's method exists, Avo will fall back to the `records` method defined in the resource used to render the array field. This is useful for providing a default dataset.

When neither a block nor a model's method is defined, Avo will fall back to the `records` method in the resource used to render the field. This is a handy fallback for providing default datasets:

```ruby
class Avo::Resources::Attendee < Avo::Resources::ArrayResource
def records
[
{ id: 1, name: "Default Attendee", role: "Guest", organization: "DefaultOrg" }
]
end
end
```

## Summary of Data Fetching Hierarchy

When using `has_many` with `array: true`, Avo will fetch data in the following order:
1. Use data returned by the **block** provided in the field.
2. Fetch data from the **associated model method** (e.g., `Course#attendees`).
3. Fall back to the **`records` method** defined in the resource.

This hierarchy provides maximum flexibility and ensures seamless integration with both dynamic and predefined datasets.