Save MM relationship with single select
Hi,
I have a condition in my form that checks if a user has only permission to one "location" and if so, the select multiple should render as single select where the single location value is already selected. This is easy by just querying for one location and set it as default. But because the data structure expects a many to many relation I need to modify the save method to attach one single location to the MM table.
I tried it like this, but that doesn't work:
How should the code look like?
Thank you!
19 Replies
I somehow need to access the value of locations, but $data isn't available in the closure
I think $state should be available
hm... $state returns null actually
I think it's because at this point the record has already been created, but without the relationship
I'm not that familiar with this use case sadly, where i use it i have $state available. Hopefully someone with better understanding of it can help 🙂
@prodex Haven't tested but I think
$get
might work in this context:
even
get('locations')
returns null 🙈Is the
locations
field a relationship on the resource model?yes, it's a mm relation on the model, but I can't use relationship() because it cannot create the relation correctly as it expects a m to 1 relation.
I see! Had the same problem recently. You need a pivot model. Have a look at this thread, maybe it can give you an idea :
https://discord.com/channels/883083792112300104/1116402597335674950/1116412576067240099
hm... it seems like filament expects a belongsToMany method, but if I'm using it like so I'm getting "Call to undefined method Illuminate\Database\Eloquent\Relations\BelongsToMany::getOwnerKeyName()"
it works with ->multiple() though
If your relationship is a BelongsToMany, Filament will try to create the end model (not what you want). If you instead rewrite your relationship as 2 HasMany with a pivot model (e.g. Thing -> ThingLocation <- Location), the repeater will correctly attach to the ThingLocation, instead of trying to create a Location.
Hope that makes sense 😄
yes I read that, but using hasMany throws another exception where it says "belongsToMany" is expected instead of "hasMany"
so it's already the correct expected method. I'm just not sure what the "getOwnerKeyName()" exception wants to tell me.
Did you update the relationship on your resource model? (i.e. point to ThingLocation instead of Location)
yes I added this method to the model and tried using it:
But that results in the exception where it says "belongsToMany" is expected instead of "hasMany"
If you introduce a pivot model, your relationship should look like
->hasMany(IncidentLocation::class)
and the repeater should write to incidentLocations
instead of locations
Maybe I'm missing something? Sorry if I'm confusion you more than helping you 🥴okay, but if it already breaks because of the wrong method name (hasMany), then it shouldn't matter whats inside the method params.
Forms\Components\Select::make('incident_locations')
hm okay, it still throws the same exception. Isn't there a way to hook into the relation process and attach that single relation? It seems a bit weird right now.
it's all I want 😂
my solution now: call the select field "location" (singular), save the id to the create class as attribute (if it exists) and then attach the relation manually within the afterCreate() hook.
Yeah, that's a more manual approach but it works fine, that's what I was using at the start of my little experiment. There's surely a way to make it work for your use-case without the custom code but it's hard to debug remotely.