How to use table builder to manage many-to-many relationship
Does anyone have any experience using the table builder package to create a table to manage a many-to-many relationship?
I have a simple many-to-many relationship with one of my models,
Profile
, and another one, Attributes
. I set up the table component to list the profile's attributes.
I set up getTableQuery()
to return `Profile::attributes()->getQuery().
This works great....
Then, I add the AttachAction to the table's header actions, and this is where things begin to fall apart:
Trying to attach an attribute starts out fine: button, modal, dropdown...and when you type something, the generated query works and correctly returns the right data, but then it displays the same (wrong) value for each attribute: 'attribute'.
Does anyone have any experience/examples...? Any suggestions/guidance...? 🤔15 Replies
Would help to use a pivot model...? Then, I could switch to the create action and it would create pivot models, I suppose.... 🤔
A pivot model would make it easier, but shouldn’t relationship() be a string instead of the actual relationship data.?
I don’t have a lot of experience with the attach action, but it seems off to me that the relationship and the inverse are both based on profile.
i dont think ->relationship() on the AttachAction is required at all
you just need to implement HasRelationshipTable alongside HasTable
then define getInverseRelationshipName() and getRelationship()
you can then remove getTableQuery()
and we will do the rest
for an example, check out the RelationManager class in the admin panel
When I supplied the name of the relationship method as a string, I got an error....it required I pass a variable of a certain type. I can't remember at the moment, but it was basically an Illuminate "relation" contract.
Thx...I'll try those things....
OK. I implemented
HasRelationshipTable
(defining getInverseRelationshipName()
and getRelationship()
), dropped getTableQuery()
, and simplified AttachAction::make()
.
It still works like before. It appears to select the expected attributes for the profile, but then it shows the same string, attribute
, for each one that's listed.are the pivot attributes in the withPivot() of the relationship definition
No. Here's the Profile class (trimmed a bit):
And here's the Attribute class (also trimmed a bit):
There are no additional fields (at the moment) on the pivot table.
And, just to be clear, the table displays fine. It's when I click attach, enter some letters, and view the dropdown results that I see the right number of options, but all with the same label, 'attribute'. (I've managed to debug to see that it's performing the right query and getting the right results.
It seems to be in
AttachAction::getRecordSelect()
in the call to mapWithKeys()
that things fall apart.try
AttachAction::make()->recordTitleAttribute('attribute')
if there is an attribute column on the attributes tableThe attributes table consists of id, name, created_at, and updated_at...at the moment.
ok so
->recordTitleAttribute('name')
That's what I had initially. Let me give it another try. It may take a minute as I'm trying all sorts of things that I need to undo/unwind....
OK. I can't get it back to a working state now. It's trying to select
name
in the pivot table just to show the table for some reason. 😕
It's super simple. That is, there's hardly any "extra" code...but I'm missing something, so I will try to figure it out, getting it to work again.please send the entire livewire component in its most simplest form that doesnt work
dont include anything that is not strictly related to this issue
Oh....I tried to add
->withPivot(['name'])
to the relation definition from earlier and left it there.... 🤦♂️
OK. Let me rewind....see where I am, and then I'll share the livewire component like you said...if still needed.
The Profile model has an attributes relation (belongs-to-many).
The Attribute model has a profiles relation (belongs-to-many).
The pivot table is a named attribute_profile and has an ID, a profile ID, an attribute ID, and timestamp fields.
The Attribute has a name
field.
The table is to list a profile's attributes and allow for attaching/detaching (and maybe creating/deleting)....getInverseRelationshipName()
should be profiles
not sure if that is what is causing it or notIt was
profile
and I changed it to profiles
shortly after copy/pasting the code. It's since been corrected and I still get the same thing.
It seems like it's somewhere in AttachAction::getRecordSelect()
in the mapWithKeys()
call. At this point, it has the correct/expected set of attributes, each with the correct ID and name.
But, when Action::getRecordTitle()
is called, it returns nothing when calling $this->getCustomRecordTitle()
and so it returns the value from $this->getTableRecordTitle()
, which is attribute
in this case....for all attributes.
But, I think I solved it....by adding ->recordTitle()
to the attach action creation:
I would think this wouldn't/shouldn't be necessary. It works, but why wasn't calling recordTitleAttribute('name')
enough...? 🤔i dont know why that would be the case, weird