# MVC with one to many relationship

**URL:** <https://discourse.laminas.dev/t/mvc-with-one-to-many-relationship/3132>\
**Category:** Components & MVC\
**Tags:** laminas-form, laminas-mvc\
**Created:** [December 11, 2022, 7:16pm UTC](https://discourse.laminas.dev/t/mvc-with-one-to-many-relationship/3132 "2022-12-11T19:16:23Z")\
**Posts on this page:** 1\
**Showing post:** 6

<div class="post-metadata">

**Author:** ![froschdesign](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/froschdesign/32/38_2.png) [@froschdesign](https://discourse.laminas.dev/u/froschdesign)\
**Post date:** [December 13, 2022, 9:56am UTC](https://discourse.laminas.dev/t/mvc-with-one-to-many-relationship/3132/6 "2022-12-13T09:56:44Z")

</div>

> [@codexknight7](#):
>
> …but I cannot understand how to implement a more advanced thing, like to add Genre to the music database and have one to many relationship.

The [Getting Started tutorial](https://docs.laminas.dev/tutorials/getting-started/overview/) uses laminas-db but it can be replaced with any other packages you like or with which you have experience.  
Like @ALTAMASH80, I do not use laminas-db because it does not support relationships out of the box.

> [@codexknight7](#):
>
> Do you have an example, please on how to add Genre to this music database, so I could also have in my Add/Edit form a dropdown list with Genre to choose from?

The dropdown list can be handled with a custom element based on `Laminas\Form\Select`.

```php
namespace ExampleModule\Form;

class ExampleSelectElement extends Laminas\Form\Element\Select
    implements Laminas\Db\Adapter\AdapterAwareInterface
{
    use Laminas\Db\Adapter\AdapterAwareTrait;

    public function init(): void
    {
        if (! $this->adapter) {
            return;
        }

        /** @var Laminas\Db\Adapter\Driver\StatementInterface $statement */
        $statement = $this->adapter->query('SELECT `id`, `name` FROM `artist`');
        $result = $statement->execute();

        $options = [];
        /** @var array{id: int, name: string} $row */
        foreach ($result as $row) {
            $options[$row['id']] = $row['name'];
        }

        $this->setValueOptions($options);
    }
}

```

Add a [delegator](https://docs.laminas.dev/laminas-servicemanager/delegators/) which adds the database adapter to the custom form element:

`module/ExampleModule/config/module.config.php`:

```php
return [
    'form_elements' => [
        'delegators' => [
            ExampleModule\Form\ExampleSelectElement::class => [
                Laminas\Db\Adapter\AdapterServiceDelegator::class
            ],
        ],
    ],
    // …
];

```

Use the element in a form:

```php
namespace ExampleModule\Form;

final class ExampleForm extends Laminas\Form\Form
{
    public function init(){
        $this->add([
            'name' => 'artist',
            'type' => ExampleModule\Form\ExampleSelectElement:class,
        ]);
    }
}

```

In your controller:

```php
namespace ExampleModule\Controller;

use ExampleModule\Form\ExampleForm;
use Laminas\Form\FormElementManager;
use Laminas\Mvc\Controller\AbstractActionController;

final class HelloController extends AbstractActionController
{
    private FormElementManager $formElementManager;

    public function __construct(FormElementManager $formElementManager)
    {
        $this->formElementManager = $formElementManager;
    }

    public function worldAction()
    {
        $form = $this->formElementManager->get(ExampleForm::class);

        // …
    }
}

```

Register the controller in the configuration:

```auto
return [
    'controllers' => [
        'factories' => [
            ExampleModule\Controller\HelloController::class => 
                Laminas\ServiceManager\AbstractFactory\ReflectionBasedAbstractFactory::class,
        ],
    ],
    // …
];

```

This solution allows an easy reuse of the element, keeps the controller clean and makes it easier to test the form element.  
_Try to avoid assembling anything in the controller._

More on this topic can be found in the documentation:

- [Usage in a laminas-mvc application - laminas-form - Laminas Docs](https://docs.laminas.dev/laminas-form/v3/application-integration/usage-in-a-laminas-mvc-application/)
- [AdapterAwareTrait - laminas-db - Laminas Docs](https://docs.laminas.dev/laminas-db/adapters/adapter-aware-trait/)
- [Delegators - laminas-servicemanager - Laminas Docs](https://docs.laminas.dev/laminas-servicemanager/delegators/)

---

_[View the full topic](https://discourse.laminas.dev/t/mvc-with-one-to-many-relationship/3132)._
