advanced-nova-media-library
advanced-nova-media-library copied to clipboard
Use within BelongsToMany pivot field
I have a Many to Many relationship between Markets & Categories using a custom pivot model. I have the Spatie media conversions/collections, etc defined there.
class MarketCategory extends Pivot implements HasMedia
{
use HasMediaTrait;
public function registerMediaCollections()
{
$this->addMediaCollection('slider')
->registerMediaConversions(function (Media $media) {
$this->addMediaConversion('full')->withResponsiveImages();
});
}
}
This is working as expected attaching the Media objects to the pivot model in a non-Nova environment.
When I try to attach Media to the pivot model in Nova using a BelongsToMany pivot field, I get the following exception: Call to undefined method Illuminate\Database\Eloquent\Relations\Pivot::getMedia()
Here is my pivot field:
BelongsToMany::make('Categories')
->fields(function () {
return [
Text::make('Title')->rules('required', 'max:255'),
Trix::make('Body'),
Images::make('Slider Images', 'slider')
->conversion('full')
->multiple()
->fullSize()
->hideFromIndex(),
];
}),
Any ideas what I am doing wrong? Is the Images field not meant to work within a BelongsToMany? Any sort of direction would be much appreciated.
Laravel v5.8.30 Nova v2.0.6
Same here. @SunnyDayGuide did you solve this by chance?
I'll write down how I solved it if anyone in the future might need it: my solution was to pass the 'id' field to the pivot fields. I inspected the resource variable passed to the resolve function and somehow the resource had the id field missing so i guess the media library was not able to find the related objects.
In my model: return $this->belongsToMany(Acme::class, 'pivot_table_class_name')->using(CustomModelPivot::class)->withPivot('id', ... );
The id is what you need to pass to make it work.
Cheers
I'm getting the same issue (Nova 3.9.2, Laravel 7.28.1). I've tired the above suggestion but still hit issues.
I've done a bit of debugging, I think it's down to a validation call from Nova:
Laravel\Nova\Http\Controllers\AttachedResourceUpdateController -> validate
which eventually calls:
Ebess\AdvancedNovaMediaLibrary\Fields\Media -> resolve
The problem is resolve
is passed a standard Pivot
model, instead of the custom intermediate model table.
This is down to the AttachedResourceUpdateController
calling $model->setRelation
AFTER validation completes.
You can fix this issue by wrapping resolve
in a try catch block:
/**
* @param HasMedia|HasMediaTrait $resource
* @param null $attribute
*/
public function resolve($resource, $attribute = null)
{
$collectionName = $attribute ?? $this->attribute;
if ($collectionName === 'ComputedField') {
$collectionName = call_user_func($this->computedCallback, $resource);
}
try {
$this->value = $resource->getMedia($collectionName)
->map(function (\Spatie\MediaLibrary\MediaCollections\Models\Media $media) {
return array_merge($this->serializeMedia($media), ['__media_urls__' => $this->getConversionUrls($media)]);
});
if ($collectionName) {
$this->checkCollectionIsMultiple($resource, $collectionName);
}
} catch (\Exception $ex) {
}
}
This seems to allow the validation call to complete, then the subsequent save call to this method works perfectly.
I don't think this is the best solution, but I hope this helps you find a solution.
Same problem here with MorphPivot:
Call to undefined method Illuminate\Database\Eloquent\Relations\Pivot::getMedia()