AlanSmith
AlanSmith

Reputation: 71

ListEntries in table for relationship on show page - backpack for laravel

Just new with backpack. I search on official site and googled it, but dit not found an answer

In laravel 7, using Backpack 4.1

My data model is : Customer has many addresses

Relationship is configured in the Customer model :

public function addresses()
{
    return $this->hasMany(\App\Models\Address::class, 'user_id');
}

Relationship is configured in the Address model :

public function customer()
{
    return $this->belongsTo(\App\Models\Customer::class);
}

public function country()
{
    return $this->belongsTo(\App\Models\Country::class);
}

public function address_type()
{
    return $this->belongsTo(\App\Models\AddressType::class);
}

In my customer show page, I would like to show all customer addresses in a table, just under the customer details. So in my CustomerCrudController, I have implemented this method :

protected function setupShowOperation()
{ 
    $this->crud->set('show.setFromDb', false);

    $this->crud->addColumn(['name' => 'name', 'type' => 'text', 'label' => __('models/customers.fields.name'), ]);
    $this->crud->addColumn(['name' => 'email', 'type' => 'email', 'label' => __('models/customers.fields.email'), ]);

    $this->crud->addColumn([
        'name' => 'addresses',
        'label' =>  __('models/addresses.plural'),
        'type' => 'table',
        'columns' => [
            'address_type_id'  =>  __('models/addresses.fields.address_type'), 
            'address_type.name'  =>  __('models/addresses.fields.address_type'), 
            'address1'  => __('models/addresses.fields.address1'),
            'address2'  => __('models/addresses.fields.address2'),
            'city'  => __('models/addresses.fields.address2'),
            'postal_code'  => __('models/addresses.fields.address2'),
            'country.name'  => __('models/countries.singular'),
        ],
    ]);
}

When I go on my page : /admin/customer/3/show, In my debugbar, I saw the query how load addresses

select * from `addresses` where `addresses`.`user_id` = 3 and `addresses`.`user_id` is not null

I have the table rendered with the corresponding number of lines from data in DB, but rows are blank. Is this the correct way to do that ? What are the correct parameters ? Is there a way to show a table with action buttons (show entry, edit) - same as in List view ?

Should it be implemented in another way ?

Hope I'm clear. Thanks

Upvotes: 3

Views: 2172

Answers (2)

Bonn
Bonn

Reputation: 63

I use Laravel 8,

In addition for the answer above, and based on this answer https://stackoverflow.com/a/65072393 and https://stackoverflow.com/a/43011286/1315632 regarding PHP function property_exists vs Laravel magic methods to create dynamic properties and methods

After creating the overwrite column php artisan backpack:publish crud/columns/table

I change line 40 in file:\resources\views\vendor\backpack\crud\columns\table.blade.php into

@elseif( is_object($tableRow) && ( property_exists($tableRow, $tableColumnKey) || property_exists((object)$tableRow->toArray(), $tableColumnKey) ) )

adding OR checking from answer https://stackoverflow.com/a/65072393

Upvotes: 0

AlanSmith
AlanSmith

Reputation: 71

Don't know if it is a laravel bug, but my solution was to create my own table blade, base on the file :

\vendor\backpack\crud\src\resources\views\crud\columns\table.blade.php

and have created my own : \resources\views\vendor\backpack\crud\columns\address_table.blade.php

I have juste changed the file:40

@elseif( is_object($tableRow) && property_exists($tableRow, $tableColumnKey) ) 

to

@elseif( is_object($tableRow) && isset($tableRow->{$tableColumnKey}) )

now, in my CustomerCrudController.php :

protected function setupShowOperation()
{
    $this->crud->set('show.setFromDb', false);

    $this->crud->addColumn(['name' => 'name', 'type' => 'text', 'label' => __('models/customers.fields.name'),]);
    $this->crud->addColumn(['name' => 'email', 'type' => 'email', 'label' => __('models/customers.fields.email'),]);

    $this->crud->addColumn([
        'name' => 'addresses',
        'label' => __('models/addresses.plural'),
        'type' => 'address_table', // my custom type
        'model' => \App\Models\Address::class,
        'entity' => 'addresses', 

        'columns' => [
            'address_type_name'  => __('models/addresses.fields.address_type'),
            'postal_code'  => __('models/addresses.fields.postal_code'),
            'city'  => __('models/addresses.fields.city'),
            'address1'  => __('models/addresses.fields.address1'),
            'address2'  => __('models/addresses.fields.address1'),
        ],
    ]);
}

And I've added an accessor in my model (Address.php)

public function getAddressTypeNameAttribute()
{
    return "{$this->address_type->name}";
}

Don't know if there is a better way ... Hope this will help others.

Upvotes: 4

Related Questions