Reputation: 348
Using Laravel Nova, I want to show a computed field in a BelongsToMany subview. In the intermediate model I have setup a virtual attribute field which computes a value using connected tables. However this field is not getting shown probably because Nova checks the withPivot fields (to which it cannot be added as it's not a real field). Is there an alternative method to get this to work?
The database model behind this is:
[GameVariation] has BelongsToMany using [GameVariationMatch] with [GameMatch]
[GameMatch] HasOne [Match]
In the GameVariation resource I've setup a BelongsToMany field which should display the computed field:
BelongsToMany::make( 'Game Matches', 'game_matches', GameMatch::class )
->fields( function () {
return [
Text::make( 'Match Data' )->displayUsing(function() {
return $this->match_data;
})
];
} ),
In the GameVariation model the tables are connected with BelongsToMany:
final public function game_matches(): BelongsToMany {
return $this->belongsToMany(
GameMatch::class
)
->using( GameVariationMatch::class );
}
In the pivot tabel model GameVariationMatch the computed field is setup like this:
final public function getMatchDataAttribute(): string {
return $this
->game_match
->match
->match_data;
}
Upvotes: 1
Views: 3478
Reputation: 348
As it turns out, on the GameVariation resource the index view of the BelongsToMany to GameMatch is served from the GameMatch resource. When only setting up ->fields() on the GameVariation BelongsToMany field, it won't show up. The recommended way is to set up ->fields() using a field class like this:
<?php
namespace App\Nova\Fields;
use App\Models\GameVariationMatch;
use Illuminate\Http\Request;
use Laravel\Nova\Fields\Text;
class GameVariationMatchFields {
/**
* Get the pivot fields for the relationship.
*
* @param Request $request
*
* @return array
*/
final public function __invoke( Request $request ): array {
return [
Text::make( 'Match Data', function ( GameVariationMatch $GameVariationMatch ) {
return $GameVariationMatch->match_data;
} ),
];
}
}
In the above, the computed Text field receives the intermediate pivot model and can therefore access all computed attributes.
The field class is used in the GameVariation resource as:
BelongsToMany::make( 'Game Matches', 'game_matches', GameMatch::class )
->fields( new RoundMatchVariationFields ),
And in the GameMatch resource as:
BelongsToMany::make( 'Game Variations', 'game_variations', GameVariation::class )
->fields( new GameVariationMatchFields ),
As described in official Nova docs on pivot fields https://nova.laravel.com/docs/2.0/resources/relationships.html#belongstomany
Upvotes: 3