For starters, I'm going to suggest you redesign your data model. Your User model is your Authenticator, and this is all it should be concerned with. It should not also be a shop or a supplier, or anything else. Supplier and Shop should be distinct models on their own which 'have' a User.

What you're doing at the moment violates S.O.L.I.D. as do most of the answers to your question here. Specifically O or Open for extension, closed for modification. For example, what if a user is a shop AND a supplier? What if later down the line you add a Distributer type as well? You have to go back to that model and add more if/else statements, more types of relations etc etc...

Instead, I would consider having roles of 'shop' and 'supplier' as well as distinct Shop and Supplier Models that have a User, which one or both of can be assigned to a user. You will likely already have the User object once authentication has been done, so after this point you can use a service retrieve Shop and Supplier information based on that users assigned roles.

Some quick sudo code of a basic implementation:

class ShopService { public function listOrders(User $user) { if ($user->hasRole('shop')) { return Shop::with('orders')->where('user_id', $user->id)->get() } return null; } } class SupplierService { public function listOrders(User $user) { if ($user->hasRole('supplier')) { return Supplier::with('orders')->where('user_id', $user->id)->get() } return null; } }

This means you can very easily extend this by adding a 'distributer' Role and a DistributerService

However, If you are still determined to go down this route, at the very least I would suggest that you still have distinct Shop and Supplier models, that each extend the base User model, and then apply the relevant relations within each.

For example: