Is there no api or 'best practice' method for loading all the referenced entities of an entityreference field (aside from manually looping through the array)? I've spent quite a lot of time googling this and searching the entity and entityreference code and keep coming up empty.
I have created two custom entities related by a single entityreference field (it's a shame this can't easily be done with a property rather than a field) and I'm trying to create a loader function that loads the parent entity as well as all the children referenced in the field and can't find any api functions to simplify this. Which I find odd considering it must be a very common need when using entityreference fields.
Or am I missing something so incredibly obvious, it's not googleable, lol.
Comments
What is the context of what
What is the context of what you are trying to do? For example, if you visit the page for a node (node/{nid}, the node and referenced entities can be displayed (You may need the display suite module to display the actual referenced entity).
_
Thanks for the reply nevets.
These are completely custom non-content (strictly speaking) entities that will eventually be displayed on an admin page. But for right now, I need to pass the fully loaded entity, along with all it's fully loaded children, as an array or object to another function. panels/display suite/views/etc don't apply-- this is all programmatically for now.
I can figure out the raw sql required, but it strikes me there must be an 'entity' or 'entityreference' method for this...
As for as I know you can use
As for as I know you can use entity_load() to load the parent, but the entity reference fields by default simply load the target id and not the entity so you would need to loop through the fields. You could either load the referenced entities one by one, or gather them up and can entity_load() with the array of entity ids to load.
I've never found anything for
I've never found anything for this myself. I just end up manually loading the entities. It would be nice if there were some API for it.
Contact me to contract me for D7 -> D10/11 migrations.
_
Ok, so at least I know I'm not crazy.
I did find this: https://www.drupal.org/node/1021556
Which led me to the following:
The original ER field data is still there at $my_entity->field_my_entity_reference_field but there's now also an array of the entities specified in the field with their complete properties at $my_entity->children.
The child entity isn't fieldable so that works for me. Not sure if it would include all the fields as well for entities that do have them.
Thanks for this! I took a cue
Thanks for this! I took a cue from your code to hack (yes, sorry, hack) the services module's
_node_resource_retrievefunction (found in /sites/all/modules/services/resources/node_resource.inc) to render paragraphs. The changed code is as follows - just in case someone wants to use this:Now you'll find a
<children>field in your XML - with the paragraphs data showing in it like it should be. Just grab it and use it in your app.Of course,
field_paragraphsis the name of my paragraphs field. Change it to yours to make it work.You shouldn't hack modules.
You shouldn't hack modules. In this case, you can implement hook_services_resource_alter(), and change the callback to a custom callback. Use your code in the custom callback, rather than altering the services module.
Contact me to contract me for D7 -> D10/11 migrations.
Yes sir. :-)
Yes sir. :-)
Hey, seriously, I couldn't
Hey, seriously, I couldn't figure out how to implement this. I found that the hook is hook_services_resources_alter (resources, not resource), but I'm not an expert at this hook stuff. Still beats me. Any quick pointers?
Dump the $resources variable
Dump the $resources variable in that hook like this:
This will show you the definition of all resources on your system that have been added by any modules, including the services module.
Search for the function name you want to replace.
Then replace it.
For example:
Then you can define my_resource_callback() and do whatever it is you need to.
Contact me to contract me for D7 -> D10/11 migrations.
Thanks a lot. I will do this.
Thanks a lot. I will do this.
Done! https://www.drupal.org
Done! https://www.drupal.org/node/2808401#comment-11679111
The correct way to do this
The correct way to do this today would be to add a function to your custom entity, like this:
public function getFoobars() {return $this->get('foobars')->referencedEntities();
}
and simply call it from the entity. This can be iterated with a simple
foreach. This is just fine for regular use. If you need heavy processing or you don't want to load your entities just to follow the references, you can always use anentityQuery.a quite dynamic solution (a
a quite dynamic solution (a bit dirty too but I needed it quickly) so you do not need to hard code the name fo the referencing field and it is automatically handled with new referencing field you will add in the future :
in your custom module :
where you need to get the parent nodes given the child node :