Quick overview of the entity attribute system
Since the early days, Magento has offered an extensible entity attribute system based on the Entity-Attribute-Value (EAV) model.
Through this system, it’s straightforward to extend a Magento entity, with some limits:
- only EAV entities can be extended with attributes; not all entities in a default Magento installation are EAV entities, just products, categories, customers, and customer addresses.
- attributes can only contain scalar values, that is,
The extension attributes system, introduced in Magento 2, overcomes the above limits, making it easy to:
- extend non-EAV entities to a condition: the entity should implement the
- use objects to have more complex types.
Unluckily, some Magento core entities don’t implement the
thus they are not extensible with native extension attributes. Anyway, let’s focus on the half-full glass to explore some advantages of the extension attributes system.
What are custom attributes?
With the introduction of the extension attributes system, some new terminology comes in.
EAV attributes belong to one of the following sets:
- system attributes - created by any default Magento installation;
- custom attributes - created in the Admin Panel or through data patches.
So, simply put, a custom attribute is an EAV attribute created by someone else
What are extension attributes?
We have already given a definition but let’s refresh it: an extension attribute is an attribute that extends a non-EAV entity.
But obviously, there is more.
First, the good news: an extension attribute allows us to overcome the limitations of scalar values. With an extension attribute, we can extend both EAV and non-EAV with complex objects.
For example, the
gift_message extension attribute added to the order
) is of the following type:
The price we pay for such flexibility is that extension attribute values persistency needs to be populated programmatically, whereas custom attribute values are loaded and saved automatically.
Refer to the official documentation for more details on how to add extension attributes to entity.
Let’s note that
doesn’t declare the methods to access extension attributes. Here is its declaration:
By convention, the methods are named
but we can’t give for granted that a class implementing
provides those methods, so my advice is to double check it.
It’s worth mentioning that to prevent performance degradation while fetching extension attributes in collections, Magento provides a native join functionality (documented here), but this feature is limited to scalar extension attributes.
To find an example, we can look at the declaration of the
is_subscribed attribute added to a customer in the
? Let’s pay attention: for the join to work, it’s not enough to declare the above join; we also have to pass the collection to the
method to have it populated with correct data. We can see an example in the
getList() method of
Another relevant feature is that we can restrict access to the values of an entity’s extension attribute by declaring an ACL resource, as shown in the official documentation.
Where to store extension attributes?
Usually, extension attributes are non-EAV attributes, meaning that we should decide where to persist their values.
If the extension attribute is a complex object, the default choice would be to use a separate custom table.
But if the extension attribute is a scalar, extending core tables with a non-ambiguous custom column is acceptable. This way, persisting values will require less code and will be more performant because it avoids additional join conditions.
There isn’t a golden rule, though; we need to properly analyze every case before making the right decision.
Custom attributes are nothing new in the Magento world: just a new name given to EAV-entity attributes that Magento installation does not create.
Extension attributes, instead, are a new way to extend non-EAV entities.
With extension attributes also comes the possibility to define complex attributes, overcoming the limit of scalar types.
All this comes at a bit of cost: we have to carefully handle persistence to ensure that data is retrieved and saved the way we expect.