How to manage ManyToMany relation in TableBuilder and FormBuilder?
I have the following models
Product
- id
- name
Pricelist
- id
- name
ProductPrice
- id
- product_id
- pricelist_id
- price
I want to create a dynamic table on product listing page, where all the Pricelist are listed as columns (e.g. Retail, Reseller, Discount) and respectively the belonging product prices.
I defined these functions in Product model:
Furthermore I tried this code in the ProductRelationsManager table columns function:
So it creates all the pricelist columns, but I have no clue what should I add to the TextColumn::make() parameter in order to reach the given price belonging to the actual pricelist.
Also have no clues how to define the form, what should I add to the TextInput::make() as parameter.
31 Replies
I add the following function to the Product model
Tinker sais:
But if I add this to the TextColumn::make('price_2"), it does not show.
If I add debug($key) to the magic __get() function, it even not print the price_2, all the other getter (eg: name, sku, category_id) are listed in the debugbar
I’m not following exactly what you are trying to do, but this sounds more like a polymorphic many to many to me. Not a many to many. Dynamic relationship doesn’t make sense to me though.
Hello Awcodes,
I think this is a pure many to many relation:
Product -> ProductPrice (Pivot) <- PriceList
I modified the Product model, and added:
also the Pricelist model:
Question still open: how can I implement The following table:
Table columns support dot syntax and will eager load the relationships as long as the relationship is setup correctly on the model.
So TextColumn::make(‘products.price_2’) should work as expected for the relationship.
I’m just not sure if the ‘2’ is trying to by dynamic or not in your use case.
It should be dynamic.
I tried, pricelist_2.price but does not work.
I want to display somehow the following result in data table:
Isn’t polymorphism the use case for dynamic relationships though?
No, because the pivot table connects only these two tables. I can't see any polymorphic behaviour what is described here:
https://laravel.com/docs/11.x/eloquent-relationships#many-to-many-polymorphic-relations
Laravel - The PHP Framework For Web Artisans
Laravel is a PHP web application framework with expressive, elegant syntax. We’ve already laid the foundation — freeing you to create without sweating the small things.
Can you share the code of your table columns?
Sure:
Ok. It seems like you’re looking for columns on a table that may or may not exist. The db doesn’t have the concept of dynamic column / field names unless you explicitly define them.
Ie, pricelists.price_2 may not exist for any given relationship.
It’s just not how relationships work. The table column either exists or it doesn’t.
I could be entirely missing the use case though. Sorry.
Sorry, just sounds like something is off in the relationship to me.
Ok, but none of these show any actual column being defined for product_2 for instance, so laravel can’t infer the relationship.
This is why dynamic relationships don’t work.
Maybe you need an explicit join vs a relationship.
yeah, thats the problem. I can query the price if I iterate through the pricelists. My first idea was using the formatStateUsing() but if in case I add a non-existing or empty attribute to the TextColumn::make('xxxx') it shows nothing, and even the formatStateUsing is not called
Maybe hasManyThrough is what you are looking for.
Honestly, that’s a relationship type I have almost no experience with because it make my brain explode, but possible.
yeah, it's okay.
But yea, dynamic relationships just don’t make sense at the db level to me. But I could be completely wrong.
LOL, I found a workaround to solve this issue:
The default() just inject the $record to the callback function. Of course the 'price_1' still not exists therefore it cannot display anything, but in the default() function I can query the necessary data
Hey, if it works. 😆
I think you might have an n+1 issue though.
Anyway, awcodes, thank you so much to try to help me. You're great!
I gonna debug it, but I gonna figure out some caching these data in a Redis server
But as long as your table isn’t ahowing too many records at one time the n+1 might not matter.
yeah, use case is expecting here ~20 product/service per vendor
Should be ok then.
Just make it work first, then make it better.
the form won't be a problem, I create some fancy component for it
Glad you got something working.
actually I use this data model for ages in my legacy e-commerce projects (even not laravel projects)
thanks again for your support!
No worries. Just hope the back and forth helped.
actually the ->default() will show any data in the cell, even if the referenced attribute does not exists
Default will show what you tell it to.
I think there also a getStateUsing() or something like that which could be used instead of default.