I have some documents in database. They come in different types, so I have several models representing documents. Now, what if I need to list them all by column, let's say user_id?
My initial database design had each type of the document reside in its own table, like invoices, proofs etc. I also had separate documents table with user_id, document_id and type, using polymorphic relations.
This is a little troublesome though, because I need to use user_id very often for each document type and fetching it through morphing each time is a little much.
@d9705996 the question is, if I add user_id column to documents table, can I fetch particular type by user? Something like this:
$invoices = User::find(3)->invoices;
The only reason I use polymorphic relation here is to be able to fetch all user's documents. But I will also need to fetch particular document type. Would be great if I could avoid duplicating user_id, which would be the case if I added user_id to both documents and invoices, proofs etc.
I'm not sure how to define this relationship to be able to do the following:
Get all user's documents of cetain type (like Invoice)
Get all user's documents ordered by a column (for example oldest to newest)
Get particular document (for example Invoice #37) with its user and all data.
@ROBOROBOK - You could invert you logic and do something like
Invoices::forUser(auth()->user());
Rather than implement forUser on each document type create an abstract document type class with a local scope method and extend this class in all your sub types.
Something like this assuming your polymorphic relation is called document (not tested so ymmv)
public function scopeForUser($query, User $user)
{
return $query->where('document.user_id, $user->id);
}
You will need to tinker to fit your setup but the general approach should work
When I said „grouped” I didn’t mean to use groupBy xD I meant all together, with being able to do things like „taking 10 newest documents of this user”. That’s not possible that way, because I would need to fetch all and trim the result, which will be super slow.