Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
EAV with ORM
  • I want to have in my catalog:
    Categories, might have a set of custom attributes
    Products, will have attribute set of their category I've read something about eav and cannot simply do this with plain SQL but maybe you could help me to figure it out. So by the theory we should have at least 4 tables:
    Categories:
    -category_id
    -category Products:
    -product_id
    -category_id
    -product etc. Attributes:
    -attribute_id
    -attribute Category_attributes
    -category_id
    -attribute_id Values
    -attribute_id
    -value Products_values
    -product_id
    -attribute_id
    -value_id Or something like that, it may depends. The question is next: is it rational and possible to make that with orm? And what kind of relationships I will need? I've never made this before but I want to. Firstly I want try with orm and then with plain SQL or query builder because I think with orm it will be easier to start. Any suggestions?
    Or advice me any book that may cover it:)
  • A structure like this is normal normalized database design, and not a problem defining this in ORM models, it's just a collection of one-to-many's. An EAV on the other hand is a variable data collection. You could see it as a 'virtual table' with a variable number of columns, one for each of the related attributes. In terms of implementation this means that for each record in the result you need to query the attributes/values tables, and then have some logic to convert the resulting attribute-value combinations into objectproperty-value for the record retrieved. As of 1.4/develop the ORM model supports non-column properties, so that part is covered. But you also need to extend the Query class to 'flatten' the related results, and the current ORM model has hardcoded calls to Query::forge(). So although I think it's technically possible to make this, it's going to be difficult when you want to do this using class extensions. If you want to try, perhaps the best option is to make a new package. Copy the ORM package, change the namespace in all classes to match your new package name, and change what's needed. If you don't feel up to it, you can always create a feature request on http://github.com/fuel/orm and see if one of the dev's is interested in picking it up.
  • Thinking about this a little bit more: it might be possible to virtually flatten it. Since the model uses getters and setters for model properties, maybe it's an option to:
    - add a new "relation type EAV", which defines which relation to use, and the attribute and value column names
    - set the relationship in the "EAV" definition hardcoded to cascaded-save/delete is true
    - fetch the relation records the normal way, so accessable through $modelobject->eavrelation->property You can then modify the model's property getter/setter so when you request an unknown property, it checks if the property is a property of a defined "EAV" relation. So when you request $modelobject->attribute, you get $modelobject->eavrelation->attribute returned, and when you set a value to $modelobject->attribute, actually $modelobject->eavrelation->attribute is set. If no "EAV" related table contains the requested property, the model returns to default behaviour, and assume it's a custom object property. Might actually be an intresting feature for the ORM package, not a lot of ORM's have a working EAV implementation.
  • Found the idea so cool I just went and implemented it in 1.4/develop. Haven't documented it yet, and you have to manually do the cascade config, but other then that it works fine.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion