ORM Doctrine on EAV Tables

I planned to create my application and use ORM for models, but the fact is that there is a part of the database that uses attribute-attribute tables.

I really liked Doctrine ORM, but I don’t know whether it is possible to create classes that will look like regular doctrine objects when the table is actually connected to the EAV type.

Can Doctrine be used for this, and if so, how?

+8
php orm doctrine entity-attribute-value
source share
2 answers

definitely possible:

Have such a relationship: Object (one for many) β†’ AttributeValue β†’ Many to One β†’ Attribute Type

+4
source share

In the light of EAV, it seems obvious how to build a relationship between entity and attribute using doctrine. In the most difficult case, we are dealing with the Many to Many relationship.

So, let's say we want to map the Name attribute to the User entity. Assuming that the user has exactly one name, and each name belongs to only one user, this link can be archived using From one to relationship

But how to model the relationship between attribute and value ? The problem is that the values ​​can be of different types or even need a different number of fields in order to preserve their information.

Consider the Name and phone_number . Although the name can be represented as a string, a phone number may require an integer. Or even you need not only a number, but also the area code in a separate file.

Since EAV requires a very flexible representation of values, it is impossible to save all of them in one field in the database table (ignore drops, data serialization is similar). Therefore, most EAV implementations use different tables representing different types of values.

To achieve such flexibility, doctrine functions display inheritance . This basically allows you to expand doctrinal entities. In this case, you specify discriminator for each subtype of your object:

 /** * @Entity * @InheritanceType("JOINED") * @DiscriminatorColumn(name="value_type", type="string") * @DiscriminatorMap({"name" = "Name", "phone" = "PhoneNumber"}) */ class Value { // ... } /** @Entity */ class Name extends Value { // ... } /** @Entity */ class PhoneNumber extends Value { // ... } 

The value class provides a common implementation for all values, that is, an identifier. Each subclass (i.e. Name and PhoneNumber ) extends these common values ​​to their specific ones, for example, additional fields.

  • @DiscriminatorColumn defines the column of the parent relationship in which the value type is stored.
  • @DiscriminatorMap used by the doctrine to map the type from @DiscriminatorColumn to one of these classes.

The relationship between attribute and value can be specified by the parent class. Calling values ​​from an attribute will then retrieve all types of values ​​that can be filtered (and processed) at runtime using, for example, instanceof .

0
source share

All Articles