XF 2.1 Trying to understand hydrateRelation - Am I looking at the right thing or should I be taking a different approach?

Kevin

Well-known member
First, what I'm trying to do...

I'm working on an add-on that uses a side-table that is related to attachments. It'll be a one-to-one relationship between the new side-table and the attachment table using attachment_id as the foreign key relationship. I've created an entity definition for my new side-table and have it defined in content types. I've created a class extension to add the new entity as a relation to xf_attachment in the getStructure function. I believe that is all working as expected since if I dump the value of $structure in my class extension I can see the new relation entry in the array (by default 'Data' is relation in Attachment so the end result is that I see both 'Data' in the relations array and my new entry).

My problem, or at least my stumbling block I'm running into, is how to get the relation actually included in the Attachment entity when it is retrieved.

Using the demo portal as an example, it uses this bit to retrieve an array of Posts entities and then to associate the attachments to each post in the array.
Code:
$threads = $featuredThreads->pluckNamed('Thread'); 
$posts = $threads->pluckNamed('FirstPost', 'first_post_id'); 
/** @var \XF\Repository\Attachment $attachRepo */ $attachRepo = $this->repository('XF:Attachment'); 
$attachRepo->addAttachmentsToContent($posts, 'post');
Taking a look at the addAttachmentsToContent function in XF\Repository\Attachment I see it looping through the passed in array then finding the associated attachments based on the 'post' content_type and content_id matching the passed in post_id. When the attachment entities collection is then added to the relations array they include the 'Data' relation entity.

They don't include my new relation. And that is the part I'm trying to figure out. From poking around I think I need the hydrateRelation but am not totally sure about that or how I'd go about implementing to retrieve the new relation of the attachment entity that itself is in the relation array of the post entity.

So can anybody please give some input on this one... did I miss something and I'm over complicating matters? Is hydrateRelation what I'm after or I'm looking in the wrong spot? If it is what I'm after where would be the spot where I'd need to inject it to retrieve the data for my new relation entity to the attachment when, for example, the attachment is retrieved as part of a post entity? I've been searching the forums and I'm seeing examples of people adding attachment entities to their new custom entity types but nothing about adding a new custom entity relation to the attachment entity.

Thanks :)
 
As per resource standards rule # 20 you should use a code event listener on entity_structure rathen then extending the entitiy class to add a new relation
For rule #20, while there is a use case where using a class would come in handy (I came across that thread while poking around trying to figure this one out) you're right, for what I'm doing I should be doing an event listener.
I think you are looking for defaultWith
Aaaarrggghh! Why, yes, yes I am, thank you. :D I strongly suspected I was missing the obvious and overly complicating things. On the good side though it did cause me to dig way deep into entity relationships. 👍
 
You need to be careful when quoting the standards since some overlap. Such as #20 and #22. There are scenarios where a class extension is needed.
There is no overlap between # 20 and # 22.

# 22 basically says that, unless there is a specific reason not to do so, extension classes must call parent methods, see https://xenforo.com/community/threads/resource-standards-overriding-methods.152035/

Furthermore, @Chris D made it pretty clear that even if an entity class is being extended (by adding or overriding methods, etc.), using the event listener is preferred over overriding getStructure.


So I think my quote is correct.
 
Last edited:
I wasn't arguing with you or saying you were wrong. I just cautioned about quoting them.

As in a case where you have extended a class, such as the entity class, and you do override a few functions but also add to the parent structure. It would make no sense to have both a listener and a class extension in that case.
 
It’s important to note that there’s a distinct difference between “should” and “must”. If you believe you might want to add new methods to the entity rather than just modifying the structure, a class extension is fine.

Furthermore, a class extension allows you to add new type hints for your custom properties, which can come in handy if you are using phpStorm or some other IDE with autocomplete and code inspections.

More on topic: hydrateRelation is useful if you are, say, creating a new Post entity within a specific thread. Rather than make any postSave actions fetch the thread all over again, you can hydrate the Thread relation to save a query :)
 
Furthermore, a class extension allows you to add new type hints for your custom properties, which can come in handy if you are using phpStorm or some other IDE with autocomplete and code inspections.
Using hinted entities with custom properties is a massive boost to reliably handling types. phpStorm's type handling and refactoring support is a massive boon to productivity and reliability.
 
Top Bottom