6. Nova® Magic - adaptdk/developer-meeting-nova GitHub Wiki

Nova resources

Creating Nova resources are pretty easy. Just use artisan for it:

artisan nova:resource Brand

This will create a file with the Brand resource as /app/Nova/Brand.php with a lot of boilerplate code. If you have setup your domain, so you can access the site using your browser go to : http://yourdomain.test/nova

Log in to Nova with your user and you will in the sidebar menu see the Brand menu item.

Registering resources

Brand resource

If you leave the files in the /app/Nova/-folder they will automatically be registered.

Adding fields

In the Brand.php find the following fields() function that should look like this:

/**
 * Get the fields displayed by the resource.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return array
 */
public function fields(Request $request)
{
    return [
        ID::make()->sortable(),
    ];
} 

We want to Add the name as a field, so we add the class in the use-statements:

use Laravel\Nova\Http\Requests\NovaRequest;

And in the fields-function, below the ID::make()->sortable(), add a new line with the following statement:

Text::make('Brand name', 'name')->sortable()

The first parameter of the make-function defines the name (or the DB-column if the second parameter is not used) and the second parameter defines the column name in the DB-table.

Your function should look like this:

public function fields(Request $request)
{
    return [
        ID::make()->sortable()->hideFromIndex(),
        Text::make('Brand name', 'name')->sortable(),
    ];
}

You will now have the possibility to make all CRUD operations through the Nova-interface with that column. Laravel Nova has quite a lot of field types already built in to it: Laravel Nova field types

Note - Caching occurs

Nova uses caches and sometimes it can take a moment before you can actually see your changes in the browser.

Create the rest of Nova resources

artisan nova:resource Color
artisan nova:resource Car
artisan nova:resource Customer
artisan nova:resource Dealership
artisan nova:resource Order
artisan nova:resource Seller

Color resource

Color resource is a copy of what we just did on the Brand.

Set the name

public static $title = 'name';

Add the fields.

public function fields(Request $request)
{
    return [
        ID::make()->sortable()->hideFromIndex(),
        Text::make('Color', 'name')->sortable(),
    ];
}

Remember the use:

use Laravel\Nova\Fields\Text;

Car resource

On the car we have Brand, Color and a Dealership as a one-to-many relation. So we add those using BelongsTo-field. Your fields-function should look like this.

public function fields(Request $request)
{
    return [
        ID::make()->sortable(),
        Text::make('Model', 'model_type'),
        BelongsTo::make('Brand'),
        BelongsTo::make('Color'),
        BelongsTo::make('Dealership'),
        Textarea::make('Description'),
        Boolean::make('Sold')
    ];
}

Remember to add the Nova fields in your use-statements:

use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Fields\Boolean;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Fields\Textarea;

If you try to click on the Create Car button or use the url (nova/resources/cars/new?viaResource=&viaResourceId=&viaRelationship=) there will be dropdowns for Brand, Color and Dealership now.

But I am only seeing IDs ?

You have not told Nova what the title should be, so it is born with the ID-column as the title. But you can change this.

In the Nova folder open Brand.php, Color.php and Dealership.php files. Find the following code in the top part of the file:

public static $title = 'id';

In Brand.php and Color.php change to :

public static $title = 'name';

In the Dealership.php file we change it to :

public static $title = 'internal_name';

If you reload the create page the dropdowns should have the correct names.

Dealership resource

Add the internal name, street and city to the fields-function:

public function fields(Request $request)
{
    return [
        ID::make()->hideFromIndex(),
        Text::make('Dept. name', 'internal_name')->sortable(),
        Text::make('Street', 'street_name')->sortable(),
        Text::make('City')->sortable(),
        BelongsToMany::make('Sellers')
    ];
}

The BelongsToMany creates a many-to-many relationship. This does not show up on the index page, but you need to go into the detail view for a Dealership. You can attach and detach Sellers in the bottom of the page.

Remember to add

use Laravel\Nova\Fields\BelongsToMany;
use Laravel\Nova\Fields\Text;

Seller resource

Change the title to use the name :

public static $title = 'name';

Add use and the field in the field-function:

use Laravel\Nova\Fields\BelongsToMany;
use Laravel\Nova\Fields\Text;
public function fields(Request $request)
    {
        return [
            ID::make()->sortable(),
            Text::make('Name'),
            BelongsToMany::make('Dealerships'),
        ];
    }

The BelongsToMany creates a many-to-many relationship. This does not show up on the index page, but if you click on a Seller you will see a container with Dealerships where you can attach one or more Dealerships to a seller.

Two-way relationship

Now that both the Dealership and Seller are mutually setup to show relations with each other, you can add a Seller on a Dealership and you will be able to see that Dealership on the Seller detail page.

Customer resource

Change the title to use the name :

public static $title = 'name';

Add use and the field in the field-function:

use Laravel\Nova\Fields\Text;

public function fields(Request $request)
{
    return [
        ID::make()->sortable(),
        Text::make('Name'),
    ];
}

Order resource

The order tells us who bought the car, who sold it and where it was sold and when the warranty expires. We add the relationships and a Date selector field.

public function fields(Request $request)
{
    return [
        ID::make()->sortable(),
        BelongsTo::make('Customer'),
        BelongsTo::make('Car'),
        BelongsTo::make('Seller'),
        BelongsTo::make('Dealership'),
        Date::make('Problem gone', 'warranty_expires')
    ];
}

Remember to add use

use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Fields\Date;

public static $title = 'name';

Add the fields.

public function fields(Request $request)
{
    return [
        ID::make()->sortable()->hideFromIndex(),
        Text::make('Color', 'name')->sortable(),
    ];
}

Remember the use:

use Laravel\Nova\Fields\Text;

Car resource

On the car we have Brand, Color and a Dealership as a one-to-many relation. So we add those using BelongsTo-field. Your fields-function should look like this.

public function fields(Request $request)
{
    return [
        ID::make()->sortable(),
        Text::make('Model', 'model_type'),
        BelongsTo::make('Brand'),
        BelongsTo::make('Color'),
        BelongsTo::make('Dealership'),
        Textarea::make('Description'),
        Boolean::make('Sold')
    ];
}

Remember to add the Nova fields in your use-statements:

use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Fields\Boolean;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Fields\Textarea;

If you try to click on the Create Car button or use the url (nova/resources/cars/new?viaResource=&viaResourceId=&viaRelationship=) there will be dropdowns for Brand, Color and Dealership now.

But I am only seeing IDs ?

You have not told Nova what the title should be, so it is born with the ID-column as the title. But you can change this.

In the Nova folder open Brand.php, Color.php and Dealership.php files. Find the following code in the top part of the file:

public static $title = 'id';

In Brand.php and Color.php change to :

public static $title = 'name';

In the Dealership.php file we change it to :

public static $title = 'internal_name';

If you reload the create page the dropdowns should have the correct names.

Dealership resource

Add the internal name, street and city to the fields-function:

public function fields(Request $request)
{
    return [
        ID::make()->hideFromIndex(),
        Text::make('Dept. name', 'internal_name')->sortable(),
        Text::make('Street', 'street_name')->sortable(),
        Text::make('City')->sortable(),
        BelongsToMany::make('Sellers')
    ];
}

The BelongsToMany creates a many-to-many relationship. This does not show up on the index page, but you need to go into the detail view for a Dealership. You can attach and detach Sellers in the bottom of the page.

Remember to add

use Laravel\Nova\Fields\BelongsToMany;
use Laravel\Nova\Fields\Text;

Seller resource

Change the title to use the name :

public static $title = 'name';

Add use and the field in the field-function:

use Laravel\Nova\Fields\BelongsToMany;
use Laravel\Nova\Fields\Text;
public function fields(Request $request)
    {
        return [
            ID::make()->sortable(),
            Text::make('Name'),
            BelongsToMany::make('Dealerships'),
        ];
    }

The BelongsToMany creates a many-to-many relationship. This does not show up on the index page, but if you click on a Seller you will see a container with Dealerships where you can attach one or more Dealerships to a seller.

Two-way relationship

Now that both the Dealership and Seller are mutually setup to show relations with each other, you can add a Seller on a Dealership and you will be able to see that Dealership on the Seller detail page.

Customer resource

Change the title to use the name :

public static $title = 'name';

Add use and the field in the field-function:

use Laravel\Nova\Fields\Text;

public function fields(Request $request)
{
    return [
        ID::make()->sortable(),
        Text::make('Name'),
    ];
}

Order resource

The order tells us who bought the car, who sold it and where it was sold and when the warranty expires. We add the relationships and a Date selector field.

public function fields(Request $request)
{
    return [
        ID::make()->sortable(),
        BelongsTo::make('Customer'),
        BelongsTo::make('Car'),
        BelongsTo::make('Seller'),
        BelongsTo::make('Dealership'),
        Date::make('Problem gone', 'warranty_expires')
    ];
}

Remember to add use

use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Fields\Date;