AttributeBundle icon indicating copy to clipboard operation
AttributeBundle copied to clipboard

need more helper methods

Open Hanmac opened this issue 8 years ago • 6 comments

i tried to implement this into my bundles but i got problems with adding getter and setter methods to access the stored Attribute objects (or namely their values)

(now with only one attribute for a definition at ones)

what i did was a get value from attribute object for a given definition (using a definition attribute as key) and setting a value for a given definition

the problem now as that i don't want to store the definition objects into the ORM (because they are static)

because i use Schema, i can do "get definition from Schema" but i still have the problem to get the schema object even, if i have the class name (because my entity doesn't have access to the Doctrine entity manager)

such methods might be added to AttributedEntityTrait

Hanmac avatar Oct 13 '15 09:10 Hanmac

Hi Hans,

`the problem now as that i don't want to store the definition objects into the ORM (because they are static)

I really do not understand this. If your definitions are static (i.e. not modifiable by the user / admin) you do not need this bundle. The definitions are stored in the database to allow user modification.

because i use Schema, i can do "get definition from Schema" but i still have the problem to get the schema object even, if i have the class name (because my entity doesn't have access to the Doctrine entity manager) such methods might be added to AttributedEntityTrait

There is no need to access the schema from your EAV entity. The attributes are kept in sync with your schema, and I do not see any use case for accessing the schema directly.

Padam87 avatar Oct 13 '15 10:10 Padam87

what I wanted to do is:

  • A Entity with attributes
  • B does inherit from/extends A and does have many properties/attributes

B does have a abc attribute and getAbc and setAbc methods, but they should be stored in the EAV table of A. means:

  • getAbc does check the attributes() Collection for the right Attribute for the given "abc" definition and returns the value of that attribute
  • setAbc is a bit more tricky ... it does search the collection for the right attribute but then removes it, then it does search the attributes of the given definition for the right attribute value and then does add the attribute value to the list. (for that part I might need the definition object I want to have static for the B class)

A and B does have to many attributes/properties that i want to store them as own table columns, that why I wanted to use EAV for that.

also why I want to use definition to get the list of possible attributes is because i want them to be fixed, so that one definition only have a list of possible attribute values. (like for example in the attribute abc there should be only X, Y, Z as possible values for that)

you might have a better idea for my problem, but i thought that using your EAV system would help me to use less tables/columns in my project

Hanmac avatar Oct 13 '15 11:10 Hanmac

I'm sorry, but what you are trying to do defeats the purpose of this bundle. As soon as you create a getter / setter for an attribute, you make your schema immutable. The user should not be allowed to modify it, because removing of the abc attribute will result in deadcode, and possibly exceptions depending on your implementation. If the user is not allowed to modify it, you could just create the attributes as regular properties in your entity, mapped by doctrine the usual way.

As for the inheritance... I have never tried it with this bundle, but I tink the AttributeCreator listener would only work with the schema specified for B. (Dropping attributes of A). Again, this is just an assumption.

Attribute value types are available, you are looking to create a choice type. Please check the DefinitionType form type, and the $type and $options properties in the Definition entity.

Padam87 avatar Oct 13 '15 11:10 Padam87

there are way to many properties which have way to many similar table references to have it as own columns/tables, thats why a EAV (might) be better.

for the inheritance, i didn't try it much, i used @ORM\InheritanceType("JOINED") in the Entity.cache.php there is only the name of the parent class. i need to test it but i think it might already work, if not i might need to add the @EAV\Entity to the child class too.

for the enum values i think it should already work if i use $definition->getAttributes() to get the list of used attribute values. i dont think there need to be done much.


i think the only thing for my use-case missing would be:

  • i have a $entity with does use the Trait (and has the $attributes and the functions)
  • now i have the name of the definition as string ala "abc"
  • also i have the value of the attribute as string ala "X"

so that i can do $entity->addAttributeByString("abc", "X") I need to get the $definition object from the name "abc" over the Schema object from the name of the class (I would do $schema->getDefinitions() ), then I can do $definition->getAttributes() and search that Collection for the attribute with the value "X", now with the Attribute object i can use the addAttribute function that is already defined in the trait.


i think the best/clean way to do that, would be to NOT add the functionality in the Entity but in a service which does have access to the EntityManager so i have access to the Schema/Definition Repositories

Hanmac avatar Oct 13 '15 12:10 Hanmac

EAV is not, and never ever will be better than ... well, anything. EAV is the worst. If you have any other choice, go with that. EAV is inefficent, hard to understand, etc. BUT it is flexible enough to handle user interaction with definitions. Since you do not actually need that, I would strongly advise against using EAV.

If your mind is set on EAV, you do not have to do this. There is no need to add attributes to your entity, the listener already does that. You just have to set the value, there are form types for that, you just have to create a controller and a view.

This listener will add all attributes necessary, automatically: https://github.com/Padam87/AttributeBundle/blob/master/EventListener/AttributeCreatorListener.php

Padam87 avatar Oct 13 '15 12:10 Padam87

I'd highly recommend reading this article: https://mikesmithers.wordpress.com/2013/12/22/the-anti-pattern-eavil-database-design/

TL;DR: Don't use it unless you need it.

Padam87 avatar Oct 13 '15 12:10 Padam87