# Related List

## Definition

A related list allow you to link some records to another one. For example, a customer can be linked to several invoices.

Uccello allows to displayed all related records using `Related Lists`.

You can use 2 types of related lists : **n-1** and **n-n**.

## Related List types

### n-1

A `Related List n-1` in a module, is linked to an `entity` field from another module. To be more explicit, let's take an example: we want to see all **invoices** related to a **customer**.

To be able to link an invoice to a customer you must create an `entity` field into the `customer` module.

```php
// database/migrations/xxxx_xx_xx_xxxxxx_create_invoice_module.php
​
<?php
​
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Uccello\Core\Database\Migrations\Migration;
use Uccello\Core\Models\Field;
...
  
class CreateInvoiceModule extends Migration
{
  public function up()
  {
    ...
    $this->createTable();
    $this->createTabsBlocksFields($module);
  }
  
  protected function createTable()
  {
    Schema::create('invoices', function (Blueprint $table) {
      ...
      $table->unsignedInteger('customer_id')->nullable();
      ...
    });
  }
  
  protected function createTabsBlocksFields($module)
  {
    ...
      
    // Field customer
    $field = Field::create([
        'module_id' => $module->id,
        'block_id' => $block->id,
        'name' => 'customer',
        'uitype_id' => uitype('entity')->id,
        'displaytype_id' => displaytype('everywhere')->id,
        'sequence' => $block->fields()->count(),
        'data' => [ "rules" => "required", "module" => "customer" ] // Linked to the customer module
    ]);
  }
  
  ...
}
```

We will create a `Related List n-1` and link it to the field freshly created.

```php
// database/migrations/xxxx_xx_xx_xxxxxx_create_customer_module.php
​
<?php
​
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Uccello\Core\Database\Migrations\Migration;
use Uccello\Core\Models\Module;
use Uccello\Core\Models\Field;
use Uccello\Core\Models\Relatedlist;
...
  
class CreateCustomerModule extends Migration
{
  public function up()
  {
    ...
    $this->createRelatedLists($module);
  }
  
  protected function createRelatedLists($module)
  {
        $relatedModule = Module::where('name', 'invoice')->first();
​
        Relatedlist::create([
            'module_id' => $module->id,
            'related_module_id' => $relatedModule->id,
            'related_field_id' => $relatedModule->fields->where('name', 'customer')->first()->id, // Retrieve the field created before
            'tab_id' => null,
            'label' => 'relatedlist.invoices', // Will be translated
            'type' => 'n-1',
            'method' => 'getDependentList',
            'sequence' => $module->relatedlists()->count(),
            'data' => [ 'actions' => [ 'add' ] ]
        ]);
  }
  
  ...
}
```

Don't forget to add the new translation:

```php
// resources/lang/en/customer.php
​
return [
  ...
  'relatedlist' => [
    'invoices' => 'Invoices',
  ],
];
```

Now, if you visit a customer record, a new tab will display all the invoices related to it. You can create new ones and they will be directly linked to the customer.

### n-n

A `Related List n-n` allows to link a same record to others records from different modules. To be more explicit, let's take an example: we want to link several **documents** to several **customers**.

To be able to do this we need to create an association table:

```php
// database/migrations/xxxx_xx_xx_xxxxxx_create_rl_customers_documents_table.php
​
<?php
​
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
​
class CreateRlCustomersDocumentsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('rl_customers_documents', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('customer_id');
            $table->unsignedInteger('document_id');
            $table->timestamps();
​
            // Foreign keys
            $table->foreign('customer_id')
                    ->references('id')->on('customers')
                    ->onDelete('cascade');
​
            $table->foreign('document_id')
                    ->references('id')->on('documents')
                    ->onDelete('cascade');
        });
    }
​
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('rl_customers_documents');
    }
}
​
```

We will create a `Related List n-n`:

```php
// database/migrations/xxxx_xx_xx_xxxxxx_create_customer_module.php
​
<?php
​
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Uccello\Core\Database\Migrations\Migration;
use Uccello\Core\Models\Module;
use Uccello\Core\Models\Field;
use Uccello\Core\Models\Relatedlist;
...
  
class CreateCustomerModule extends Migration
{
  public function up()
  {
    ...
    $this->createRelatedLists($module);
  }
  
  protected function createRelatedLists($module)
  {
    ...
      
    $documentModule = Module::where('name', 'document')->first();
    Relatedlist::create([
      'module_id' => $module->id,
      'related_module_id' => $documentModule->id,
      'tab_id' => null,
      'label' => 'relatedlist.documents', // Will be translated
      'type' => 'n-n',
      'method' => 'getRelatedList',
      'sequence' => $module->relatedlists()->count(),
      'data' => [ 'actions' => [ 'add', 'select' ] ]
    ]);
  }
  
  ...
}
```

Don't forget to add the new translation:

```php
// resources/lang/en/customer.php
​
return [
  ...
  'relatedlist' => [
    ...
    'documents' => 'Documents',
  ],
];
```

Now we'll configure the models:

```php
// app/Customer.php
​
<?php
​
namespace App;
​
use Uccello\Core\Database\Eloquent\Model;
...
​
class Customer extends Model
{
  public function documents()
    {
        return $this->belongsToMany(Document::class, 'rl_customers_documents')->withTimestamps();
    }
}
```

```php
// app/Document.php
​
<?php
​
namespace App;
​
use Uccello\Core\Database\Eloquent\Model;
...
​
class Document extends Model
{
  public function customers()
    {
        return $this->belongsToMany(Customer::class, 'rl_customers_documents')->withTimestamps();
    }
}
```

Now, if you visit a customer record, a new tab will display all the document related to it. You can select existant documents to link to the record or create new ones.

## Options

#### Display in a Tab or a Block?

By default, a Related List is displayed in a Tab. If you prefer, you can display it in an existant tab. The Related List will be displayed like a new block at the bottom of the page.

To do this, simply fill in `tab_id` with a valid tab's id from the current module.

```php
protected function createRelatedLists($module)
{
    $documentModule = Module::where('name', 'document')->first();
    Relatedlist::create([
      'module_id' => $module->id,
      'related_module_id' => $documentModule->id,
      'tab_id' => $module->tabs->first()->id, // The Related List will be displayed as a new block in the first tab
      'label' => 'relatedlist.documents', // Will be translated
      'type' => 'n-n',
      'method' => 'getRelatedList',
      'sequence' => $module->relatedlists()->count(),
      'data' => [ 'actions' => [ 'add', 'select' ] ]
    ]);
}
```

## Properties

| Attribute               |  Type  | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | Default |
| ----------------------- | :----: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-----: |
| **module\_id**          |   int  | Id of the source module in with display the related list.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |         |
| **related\_module\_id** |   int  | Id of the target module to which the related list points.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |         |
| **related\_field\_id**  |   int  | Only for a `n-1` related list. Id of the [entity](https://uccello.gitbook.io/doc/uitypes-displaytypes/default-uitypes#entity) field related to the source module.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |  `null` |
| **tab\_id**             |   int  | Id of the tab in which display the related list. If it is null, Uccello displays the related list in a new tab of the Detail View.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |  `null` |
| **label**               | string | Related list's name. It can be translated if you add the translation in the module localization file.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |         |
| **type**                | string | <p>Type of the related list.</p><p><code>n-1</code> or <code>n-n</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |         |
| **method**              | string | <p>Method to use for retrieving the related records.</p><p>By default, set <code>getDependentList</code> for a <code>n-1</code> related list and <code>getRelatedList</code> for a <code>n-n</code> one.</p><p>Theses methods are defined in the <a href="https://github.com/uccellolabs/uccello/blob/master/app/Support/Traits/RelatedlistTrait.php">RelatedlistTrait</a>.</p><p>To use your own method please refer to the example below.</p>                                                                                                                                                                                                                                                                                                                                                                            |         |
| **sequence**            |   int  | The display sequence for ordering related lists.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |         |
| **data**                |  array | <p>Useful to pass some settings params.</p><p></p><p>By default you can use the following structure:</p><p>\[</p><p>  'actions' => \[</p><p>    'add',</p><p>    'select'</p><p>  ]</p><p>]</p><p></p><p>This parameter allows to configure the buttons you want to display in the related list.</p><p></p><p><strong>select:</strong> The user can select a record if he has the <code>retrieve</code> capability on the related module.</p><p><strong>add:</strong> The user can create a new related record if he has the <code>create</code> capability on the related module.</p><p></p><p>You can adapt the contains of <code>actions</code> to use 0, 1 or 2 buttons (e.g. <code>\[ 'actions' => \[ 'add'] ]</code>).</p><p>If you don't want to display action buttons, simply let <code>actions</code> empty.</p> |  `null` |

{% hint style="info" %}
You can create your own method for retrieving the related records. To do this you have to create 2 functions in the model in which add the related list.

* `myOwnMethod`: You can use the name of you want
* `myOwnMethodCount`: The same name as the method above, suffixed by `Count`
  {% endhint %}

#### Example

```php
<?php

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Uccello\Core\Models\Relatedlist;
use Uccello\Core\Support\Traits\UccelloModule;

class Person extends Model
{
    use UccelloModule;

    ...

    /**
     * Retrieves related records for n-n relations
     *
     * @param Relatedlist $relatedList
     * @param integer $recordId
     * @param Builder|null $query
     * @param int $start
     * @return Collection
     */
    public function myOwnMethod(Relatedlist $relatedList, int $recordId, ?Builder $query = null)
    {
        $modelClass = $relatedList->module->model_class;
        $relationName = $relatedList->relationName;
    
        $record = $modelClass::find($recordId);
        $filter = ['order' => request('order')];
    
        $query = $record->$relationName()
                        ->filterBy($filter);
    
        return $query;
    }
    
    /**
     * Counts related records for n-n relations
     *
     * @param Relatedlist $relatedList
     * @param integer $recordId
     * @return int
     */
    public function myOwnMethodCount(Relatedlist $relatedList, int $recordId) : int
    {
        return $this->myOwnMethod($relatedList, $recordId)->count();
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://uccello.gitbook.io/doc/the-basics/related-list.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
