Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

yunior's avatar

Polymorphic relationships advice

Hi guys, I am fairly new with Laravel and would need some advice. I've got Eshop model that can be of different type (woocommerce, magento, prestashop etc.). For each Eshop there are associated data specific for each type like eshop domain, access token etc. Based on this data I am able to communicate with eshop API. What would be your approach in this situation? Polymorphic relationships? Thanks in advance.

0 likes
4 replies
Punksolid's avatar

Hi @yunior as I understand you want to have different structure for connection for each type of eshop.

I think that the easiest way to acomplish that is to use a json field. You put a json field called for example connection in your database in the same table of your eshop. And then set

array $cast = [
'connection' => 'array'
]

and then whenever you are going to use you can ask for

if($shop->type ==='magento') {
$shop->connection->key
//logic for magento connection
}

Something like that

yunior's avatar

Hi @punksolid, thanks for the answer. I was hoping to separate connection logic for each type to different class. That way I could avoid lengthy conditional statements and I would be easier to extend with new types. Ideally I would like to have $shop->api relation that would be populated with proper API class/model based on selected type. Maybe smth like this

$shop->api->getLatestProducts()
Punksolid's avatar
Level 25

Cool, I've been around that kind of architecture you're looking for. Check this laracast video after the minute 5 https://laracasts.com/series/simple-rules-for-simpler-code/episodes/2

You could combine the past comment that I said. And make a class for every type of connection. So in the constructor for each class you just inject the model where the configs are saved and prepare the things you need to do.

So for example

class Magento implements EshopInterface {
    public function __construct(Eshop $shop_model) {
        $this->token_private = $shop_model->data->token_private;
        //you can put the specific configurations for connection here or in another method
    }

    public function getLatestProducts(): array
    {
        //You put the action logic for retrieving the elements
        //Always return the same type for this method that will be in each class
    }
}
class Woocomerce implements EshopInterface {
    public function __construct(Eshop $shop_model) {
        $this->key = $shop_model->connection->key;
        //you can put the specific configurations for connection here or in another method
    }

    public function getLatestProducts(): array
    {
    }
}

// It is not explicitly needed but will help you keep your app consistent to have an interface
interface EshopInterface
{
    public function getLatestProducts(Request $request): array;
}

And after all is set, in your controller or wherever you instantiate the proper object

public function index()
{
    // These ifs you could put it in a method in a class or the model itself here are for explanation
    if(config('services.eshop') == 'magento'){
        $eshop = new Magento($eshop_model);
    } else if (config('services.eshop') == 'woocomerce'){
        $eshop = new Woocommerce($eshop_model);
    } else {
        $eshop = new NullShop();
    }
    
    $eshop->getLatestProducts(); //Here you will not need to care about how to handle the connection
}

After all this I bet I didn't say anything more than the video LOL. But I hope it will also help non subscriptors.

yunior's avatar

Great man, that's exactly what I was looking for. Thanks a lot

Please or to participate in this conversation.