Skip to content

Why do some core repositories use a data model in the save function while others use a model?

I have a quick question and this could help me determine what is the good practice using the repositories.

To provide an example to the question I ask in the title of this subject, I can take as example the catalog rules and the sales rules.
As the structure of these two models are similar, I don’t get why these two entities do have a different way to work in their repositories.

  1. Catalog rules

The catalog rule repository implements the save function as :

save(MagentoCatalogRuleApiDataRuleInterface)

This interface is mapped to the rule model :

<preference for="MagentoCatalogRuleApiDataRuleInterface" type="MagentoCatalogRuleModelRule" />

That means that if we want to save an object, we can quickly do :

    public function __construct(
        MagentoCatalogRuleModelRuleFactory $ruleFactory,
        MagentoCatalogRuleModelCatalogRuleRepository $catalogRuleRepository
    )
    {
        ...
        $this->ruleFactory = $ruleFactory;
        ...
        $this->catalogRuleRepository = $catalogRuleRepository;
        ...
    }

    ...

    public function example() 
    {
        $catalogRule = $this->ruleFactory->create(); 
        ....
        $this->catalogRuleRepository->save($catalogRule); 
        ...
    }

The rule is saved, everybody’s happy.

  1. Sales rules

The sales rule repository implements the following :

save(MagentoSalesRuleApiDataRuleInterface $rule)

The interface is mapped as :

<preference for="MagentoSalesRuleApiDataRuleInterface"
            type="MagentoSalesRuleModelDataRule" />

So if we want to programatically create a rule, we can’t do like the catalog rule previously but we have to do something like :

    public function __construct(
        MagentoSalesRuleModelRuleFactory $ruleFactory,
        MagentoSalesRuleModelConverterToDataModel $ruleToDataModelConverter,
        MagentoSalesRuleModelConverterToModel $ruleToModelConverter,
        MagentoSalesRuleModelRuleRepository $salesRuleRepository,
    ) {
        $this->ruleFactory = $ruleFactory;
        $this->ruleToDataModelConverter = $ruleToDataModelConverter;
        $this->ruleToModelConverter = $ruleToModelConverter;
        $this->salesRuleRepository = $salesRuleRepository;
    }

    ...

    public function example() 
    {
        ...
        $rule = $this->ruleFactory->create(); 
        ....
        $ruleDataModel = $this->ruleToDataModelConverter($rule); 
        $this->salesRuleRepository->save($ruleDataModel); 
        ...
    }

As the two core extensions are similar (and more than that, the models structure are almost identicals), I don’t get why one of them uses a model while the other implements a data model during a repo save.

The same problem happens with other repositories at the save function level : customer repository uses data models while product repository use models.

I guess that one of the extension (probably catalog rules) has older code and it would need a refactoring work but imo I don’t think it is a good practice to maintain two ways of working with repositories.

As a magento developer, I find it annoying to have to convert models to data models as it makes the code longer (not so much but still) particularly with some entities like the customer that are regularly used and for which we always have to inject the converters in the constructors.

What is the best practice for the repository usage ?
Also, why, in the core modules, implementations of entity / model save is so different ?