Skip to content

Recipe: an Eloquent model in a UI5 table

This recipe is built on LaravelUi5 Core. Core takes care of the plumbing (the OData route, the model in the app's manifest, the CSRF handshake), so the recipe can go straight to the table. Core is free to use; installing it needs a free account.

It starts where the quickstart ends: the Showcase app is assembled, registered and running. It takes two steps: bind the model on the server, bind the table on the client.

1. Bind the model in configure()

Every UI5 app in Core is also an OData v4 service. Let the app class extend AbstractUi5App and bind the Eloquent model in configure():

php
use LaravelUi5\Core\Ui5\AbstractUi5App;
use LaravelUi5\OData\Service\Contracts\EdmBuilderInterface;

class ShowcaseApp extends AbstractUi5App
{
    // … NAMESPACE, VERSION and the rest, unchanged …

    protected function configure(EdmBuilderInterface $builder): EdmBuilderInterface
    {
        $this->discoverModel(\App\Models\User::class);

        return $builder->namespace($this->namespace());
    }
}

That is the whole server side. The service now answers at /odata/com/example/[email protected]/, its $metadata describes a Users entity set, and Core writes the matching data source and default model into the manifest the app is served with. Check it:

bash
curl 'http://localhost:8000/odata/com/example/[email protected]/Users?$top=2&$count=true'

discoverModel() reads the types from the model's casts. How it maps an Eloquent model is on model discovery.

2. Bind the table in the view

The view binds the table's items to the entity set. Nothing else is needed, not even a controller:

xml
<mvc:View
    displayBlock="true"
    xmlns="sap.m"
    xmlns:mvc="sap.ui.core.mvc"
>
    <Page id="UserPage" title="Users">
        <Table
            id="UserTable"
            growing="true"
            growingThreshold="20"
            growingScrollToLoad="true"
            items="{
                path: '/Users',
                sorter: { path: 'name' },
                parameters: { $count: true }
            }"
        >
            <columns>
                <Column><Text text="Name" /></Column>
                <Column><Text text="Email" /></Column>
            </columns>
            <items>
                <ColumnListItem>
                    <cells>
                        <Text text="{name}" />
                        <Text text="{email}" />
                    </cells>
                </ColumnListItem>
            </items>
        </Table>
    </Page>
</mvc:View>

items="{/Users}" alone already shows the rows. The three extras each become part of the request the table sends, and the engine answers them on the server:

In the viewIn the requestDocumented on
growing, growingThreshold="20"$skip and $top, twenty rows at a timePagination
sorter: { path: 'name' }$orderby=name$orderby
parameters: { $count: true }$count=true, the total for the growing trigger$count

Route the view in the app's manifest.json (a route users with a target of the same name, as in the course) and open http://localhost:8000/ui5/app/com/example/[email protected]/index.html#/users.

The Showcase app is a demo

The Showcase app is built without authentication, as the course builds it. Before you serve real data, put the app in a module that requires a login; see modules.

Where to go next

The video course builds the same service step by step and goes further:

  • Episode 4 makes Laravel speak OData, with the master/detail floorplan ui5:wire generates.
  • Episode 5 binds the master list.
  • Episode 6 adds a live search that filters on the server.
  • Episode 7 binds the detail page.

The engine is read-only by design; writes go through a Ui5Action.