Closed vHeemstra closed 1 year ago
This was implemented in the last release (3.3.0). Thanks for the report.
API is:
Image::joinRelationship('imageable', morphable: Post::class);
Is the multi-variant also implemented?
Like so:
OrderItem::joinRelationship('orderable', [Product::class, Course::class])
EDIT: Nevermind, just read this:
Yeah, querying both with joins is actually interesting. Can you explain your use case here? Each order item will have only a product or a course, right? You want to grab the data independently of which one it is?
Right, so as I said in my initial description, since it is a morphable relationship, it is open to any other model type. So when you want to get all OrderItem
s that only belong certain 'orderable' models and load/get those orderables too, you could use a statement like:
OrderItem::joinRelationship('orderable', [Product::class, Course::class])
This would only load these types of model (in addition to the OrderItem
).
And maybe it is even possible to do something like:
OrderItem::powerJoinHas('orderable', [Product::class, Course::class])
?
Anyway, the main point of this issue was to be able to use MySQL's JOIN
with the morphTo
relationship on models to (hopefully) have a better performance running one query instead of multiple. Although this might not be the case in the end with the MySQL inner workings, computation and memory performance.
Some testing should be done to see if this actually speeds things up or just creates way too big of a workload to the MySQL server.
So when you want to get all OrderItems that only belong certain 'orderable' models and load/get those orderables too, you could use a statement like
You would have to use left joins in this case, but that's reasonable. Regular inner joins would try to basically fetch an OrderItem where it has a Product AND a Course, which will never be true in this case
What you may be looking for seems actually the powerJoinHas
instead, indeed, at least from your description. I need to find some time, but will try to add this.
Yes, my search was for multiple functionalities that your package has, but it just would not work (yet) with the 'reverse' morphTo
relationship. So that's the reason to start this issue.
I tried going through the code to add it myself and send in a PR, but I got a bit stuck in the code 😄 I will have another look
I just added the ability to use powerJoinHas
using the morphable attribute in the latest release.
Related: #129
Context
Intro
OrderItem
s are line items of a placed order. It can be (linked to) either aProduct
or aCourse
(maybe others later). So this is a One-to-Many polymorphic relationship, where theOrderItem
has one related model andProduct
/Course
has many relatedOrderItem
s.OrderItem
Model
DB table
order_items
App\Models\Product
Product / Course
Model
DB table
products
/courses
Problem
OrderItem::joinRelationship('orderable')->toSql()
produces a very strange SQL with anINNER JOIN
to itself using an unknown/empty column (like it was joining the other way around):Suggested solution
For these inverse cases, the query builder needs to know the other table name of course. Following Laravels way to handle this with
whereHasMorph
, I would suggest something like:OrderItem::joinRelationship('orderable', Product::class)
Which would produce:
(Maybe not feasible) To join multiple types, something like:
OrderItem::joinRelationship('orderable', [Product::class, Course::class])
Would produce: