Apr
25
2012

References vs Entity Reference & Migrating

Using node, term, and user references has been a pivotal part of many moderate to advanced website architectures in Drupal 7. The References module used for this is being deprecated. It is now suggested to use an Entity Reference. But, is Entity Reference ready for your project, and if so, how hard is it to migrate?

Share
Email

As stated on the official References page

References will most probably be deprecated in the near future in favor of Entity Reference

I’ve had to figure out how to do a lot of old things in a new way to make this a suitable replacement for most of my projects. Initially diving in was overwhelming, hence all the notes I made which I’m now sharing with you. In my comparison, migration, and project development, I’ll describe all of the options I found designated by the feature heading.

Moving from References to Entity Reference

Why I switched to Entity Reference now: A lot of my Drupal projects have unique requirements in which References already provides a solution. However, migrating data later on (mainly for new projects) when Entity Reference already exists now is not necessarily the best option because of the extra development it could causes. It was vital to research the options I had thoroughly so that a good architecture was put in place for future functionality to be laid on top of in the case that Entity Reference provided most but not all of the ideal solution at the time. This being to the degree that it was tolerable in the short term and easily swapped for a full solution later. Most of the options here did give me my final solution, but for some things it seemed sub par in comparison to references and paired modules. To be fair, entity reference is already moving ahead in areas references left untouched (the use of almost any target type for example). Plus the places where it’s lacking are fewer each month. Some things to consider while you’re reading through this:

  • Some of the recommendations here are in dev or sandbox state. Use on production sites at your own risk!
  • A few of the features I mention here may not exists in References either but is something I now use.
  • ER == Entity Reference

Add Another & Sorting/Order VIA Drag And Drop

Entity References currently provides drag and drop ordering with the autocomplete widget for all bundles (nodes, terms, users etc.). I could never find a term references widget that offer this type of functionality. Particularly a drag and drop functionality WITH term selection on a hierarchical level. The latter feature is a feature that’s alluded my research into the subject.

  • Consider that you have a taxonomy in which you use the same term on multiple tier 2 or tier 3 levels within the tier 1 or tier 2 terms. This provides a tricky situation for the autocomplete widget to handle. Entity reference doesn’t solve this yet, but neither does the core term reference field. The closest thing I’ve found is Hierarchical Select which would be PERFECT if it offered Tree ordering when Displaying which was vetoed by the author long ago. However, if ordering doesn’t matter to you then you should check out “Hierarchical Select Entity Reference” widget (more on this later) and you can keep on using it with ER.

If the same term/tier scenario outlined above is not a problem you have, then by using ER with terms (and autocomplete widget) means you now have access to a delta value upon drag and drop ordering. Where you might have had to create multiple fields to define a particular stepping order in the past, it can now be done all in one field. That’s less tables in the database and an unlimited amount of ordering potential!

Creating Automatic Back References From Other Nodes/Terms After A hook_node_save

Entity Reference: Two-way reference (synchronize 2 fields or use one storage for two-way link) on drupal.org has a lot of leads on automating syncing between linked reference fields. From that thread, you’ll mainly want to check out:

Entityreference Backreference – This doesn’t seem to provide a real synchronizing solution and is still in sandbox (an empty one). You’ll need to fish it out of an older git commit if you want to use it, but its likely worth skipping.

(Entity)Reference Field Synchronization – This adds a synchronize select box option on the field add/edit pages. You’ll need to have at least one other ER field created elsewhere before it will give you the option to sync anything up with the current field you’re creating. If you delete a reference on one node, it also deletes the reference from the other as expected.

(Entity)Reference Field Synchronization (ref_field) features in detail:

  • Be careful about doing 1 to many relationships here. If a backreference is happening and the corresponding ER field is not setup to receive unlimited data, you will be overwriting current data.
  • Synchronizing ONLY works between two fields. Once a field is setup to sync with another field, if you try to reuse that field again (for a three way sync) it will drop the field it’s currently syncing with and use the new field you’re specifying in a two way sync. The way around this is just to create another field, which means you may have to edit something twice on the same “middle man” page. IE. the node that shares the commonality between the two other synced fields. Too tedious for me. I opted for fewer tables when this problem came up, so for now I’ll have to manually sync the odd man out. This is often doable if you choose the least updated field as the one you plan to manually sync.
  • If you want to use this within the same content type, you’ll need to create two separate fields. It relies on the fact that it has another field (even if it’s named the same but in another content type) to sync against. Another words, it can’t do self referencing syncs
  • If you haven’t been using this module from the start, then you’ll have to do the first sync update on your own. A button to re-sync all field’s current data would be nice. You could probably pull out chucks of code from this module and automate that if you had the burning desire to use this across too many nodes to do by hand.
  • If you reorder a reference list it will in no way effect the delta order of the field that it is referencing.
  • If you had unsynchronized references before you installed this module, simply saving the node or modifying the other references and then saving will not sync the unsynchronized reference. You need to manually remove, save, add, save.
  • Would be suburb if there was a way to find orphaned syncs. In some ways, these non-synced references might be desired, however once the module is active there is no way to add a reference and say “don’t sync”.
  • You can do a taxonomy and node sync but you must have a taxonomy term bundle ER field on a content type and a node bundle ER field on a vocabulary
  • Deleting one referenced entry deletes the reference of the current entity on the other entity

Create New Nodes/Terms Then Reference VIA URL/Link For Auto-filling Entity Reference Fields

Entityreference prepopulate -  Allow prepopulating any Entity reference widget via URL, though you’ll need to create the links and place them in your theme on the appropriate content type. Unless you use…

Prepopulate Create Node Links – An extension of Entity Reference Prepopulate that gives you your generated links. Then you can click and create a node of a different content type that will be referenced on the node that you clicked “create” on.

Another way to do this is stepped out in Add node links for entity reference fields by rwilson0429. It involves using Entity Reference, References dialog (more below on that) and Entity Views Attach modules.

ALL of the above can be a replacement method for what you might have been once using node reference URL for.

It’s worth a mention, that you could probably accomplish this solution with Contextual Administration. While References Dialog requires less setup, your options are not as finite if your needs are incredibly unique/customized. Support for Entity Reference module was recently added.

  • This is the node reference version of setting something like that up, but it loosely translates to what you can do with entity reference as well: http://www.youtube.com/watch?v=BZxoUzIE5M4
  • Also see: Add CTools relationship. CTools is a requirement of Contextual Administration because of the Page Manager use.

Create New Nodes/Terms Then Reference From Node Edit

Entity Connect adds “new” and “Edit” Icons next to each reference.

  • In References this was known as Node ConnectA request was made for version that worked with ER.
  • Entity Connect also works with terms.

Entity Reference Create is a port of Node Reference Create - As discussed on Corresponding Entity References and in this initial request. Unfortunately I could not get Entity Reference Create to work, but it seem like it would be the only option that would allow you to create nodes on the fly by filling in a title in your reference fields and saving your edit form. I’m guessing there is an incompatibility with newer versions of ER and that’s why it was broken for me. Things to think about when it does work:

  • Will it work with entity types other than nodes.
  • Does it cause problems with required fields on the node that it creates.
  • If it does work with terms it is a potential semi-replacement of the “Allow and insert new terms” feature of Content Taxonomy

Update :As of 6-5-12, another user (chertzog) created a proper port/projectCorresponding Entity References. Looks to be a solid option but I have not tested it as of yet (but will soon).

Programmatic Creation Of Data Into Entity Reference Fields

Programatically creating nodes is particularly important right now if you have a complex project that needs to be migrated from Drupal 5 or 6 to D7.

An initial thread for doing this was started here:  - Programmatically create nodes with Entity reference field Which will lead you to Programmatically create nodes which provides you a full example. That appears to be outdated after an update made to entity reference that removed the need for target_type (I bet that’s why Entity Reference Create is broken too):  target_type column was removed from entity reference. Here is an example of how it is used in a migration script .

 if (!empty($my_content_type_data->field_my_old_reference_field)) { //check to see if the field has a value, otherwise it throws errors on the empty ones
 $node->field_my_new_entity_reference_field[LANGUAGE_NONE][] = array('target_id' => $my_content_type_data->field_my_old_reference_field);
 }
 

Selection Widgets, Content Searching, And Creation

Entity Reference Tree – The most recent snapshot listed here seems to be empty. The snapshot that worked for me is here: Entity Reference Tree Snapshot. The git command to clone is below too:

  • git clone –branch 7.x-1.x http://git.drupal.org/sandbox/lahode/1325398.git entity_reference_tree
Entity Reference Tree features in detail:
  • This only works with target type: taxonomy
  • You can only use this in conjunction with an ER that has a single target bundle. If you do, it will choose to use just the first one.
  • Not compatible with references_dialog (More on that below)
  • Always starts with the tree fully expanded. You could probably fix this with a little JavaScript hack if you really needed to.

References dialog – Creates add/edit/search links via dialog box. This works on references, entity references and core term reference fields. It’s not that intuitive to setup. rwilson0429 documented Reference dialog instructions for that though. There is more documentation here that may help specifically in setting up the search dialog box functionality (you need to create your own view).

  • Note, References Dialog supports multiple bundle creation/editing:

Entity Reference View Widget provides a widget that uses the view for selecting entities for your ER field. The view can be paginated and have exposed filters. This method feels less elegant to me as it is a bit bulky, but I imagine it being the best method when presented with an abundance of multifaceted data.

Autocomplete Deluxe for References is an autocomplete tagging style widget for references which works with nodes and terms. This is based on the original Autocomplete Deluxe which allowed the widgets use on core term references. Compatibility with Entity Reference is underway, and has a patch available there on the Autocomplete Deluxe thread AND related patch for ER here: Compatibility with Autocomplete Deluxe for References. Remember to apply both if you need this right now.
  • This should work for nodes and terms but I have not tested it with other target types or multiple bundles of the same type
  • The combined use that the original Autocomplete Deluxe module had with Context Taxonomy is fortunately not possible yet.
Hierarchical Select Entity Reference gives you the same functionality that you had with the core term reference field type that you had with the original Hierarchical Select module. For use with the term target type only.

Using A View As Your List Criteria (rather than a bundle)

References has a feature that allows you to create a view (of nodes for example) and then use that list as the options that are used with your node reference in whatever widget chosen. This feature is being developed and discussed for ER as well: Add views support for providing a list of entities or bundles (views filtering, relationships, etc). If you need the feature now, there is a patch available on that thread.

  • I haven’t tried creating a view that contains two different target types. Consider a scenario where you need to reference terms and nodes for the sake of maintain the delta (order weighting) via drag/drop, which is only available via autocomplete widget. If that doesn’t work (I’m thinking it wouldn’t), an alternative way to solve this problem could be to use a Field Collection with two ER fields. One for each different target type, and then do the arranging on the Field Collection level. I don’t like that approach because it’s an extra field on each row that is left empty when it’s counterpart is being use. Plus you’d have to write a custom function which would have to check each field and return the one will filled data. On top of that you’re adding a couple extra tables to the database that you wouldn’t need if it was a single field. Though there might soon be another solution if the ER or UUID module adds support for a UUID reference field. Here, it’s noteworthy to call attention to the fact that this is the only way I’ve ever found to reference an item/link in a menu. With this you could take your site in an entirely new architectural route. Including making a menu which contains node and term paths in it which are then referenced by a single type of unique identifier. Hence, giving you another solution to the problem if the case stands that you’d never be able to combine target types in an ER field.

Entity Reference View Widget (mentioned above) might also meet a need for a customized selection process. A few things I haven’t tested yet:

  • Does the ER field still allow selections outside of what the view provides? This could be a good or bad thing depending on the application.
  • Since this is just a widget, you wouldn’t be able to mix terms and nodes together as ER fields has that constraint.
Conclusion: If your use case calls for the autocomplete list widget, use the patch. In other cases, the Entity Reference View Widget offers something that could be tailored for more complex scenarios.

Entity Reference Select Lists As An Exposed Filter On A View

Entity Reference does not offer select list as a views exposed filter, only text field for id number offers a patch and custom coded solution for using ER fields as a select list drop down in your exposed view forms. The custom coded approach mentioned in comment #11 would have you create your own module and query the options you desire (See Database API). Then alter the form with a hook_form_alter.

</pre>
</div>
function modulename_form_views_exposed_form_alter(&$form, &$form_state, $form_id) {
 if (isset($form['field_your_field_name_target_id'])) { //remember to prepend 'target_id' to your field name
 $form['field_your_field_name_target_id'] = array(
 '#type' => 'select',
 '#options' => modulename_get_your_field_name_options(), // returns an array of 'nid' => 'title'
 '#default_value' => $form['field_your_field_name_target_id']['#default_value'],
 );
 }
 }
<div>

Migrating From References To Entity Reference

A discussion about Migration from references module to Entity Reference was started a while back. This lead to the Reference to EntityReference Field Migration module which at the moment is still in sandbox status (though it works well!). A few things to node about this migration script:

  • It only migrates node and user references, not term references.
  • Make sure your Entity API and Entity Reference modules are fully up to date.
  • This will convert not only your fields (with the same name), but all the data appropriately.
  • If you have any code custom code in a module that references these fields you will need to update how they’re being called.

Conclusion

If you find anything that changes, disproves, or adds to anything above, feel free to note it in the comments and I’ll update this article accordingly. There was a lot to account for and I’m sure most topics covered here could be expanded further. Likewise, if you have a project with a feature/use case not mentioned here.

Respond: Leave A Comment | Trackback URL

Entrupeners, Subscribe for the lastest tools, tips, and tutorials.


2 Responses to References vs Entity Reference & Migrating

  1. pvdsteen

    Great post!
    You’ve created a splendid overview for people moving from references to entity references.

    The only functionality i’m missing is “Hierarchical term reference autocomplete” (http://drupal.org/project/term_ref_autocomplete)

    This module shows the term hierarchy in an autocomplete field.
    Though it does not work for “entity reference”.

    I’ve tried to copy/edit the existing module to make an “entity term reference autocomplete” module. Adding the correct field type to attach te autocomplete.

    I guess that because entity reference does not have individual term/node/user references defining a field type “entityreference” does not work out-of-the-box.

    I tested just to be sure.
    1. I can select the widget for an “entity reference” field
    2. when i add my test node i see the autocomplete.
    3. when enter a (part of a) term I get an ajax http error (500)

    any idea?

    • It looks like you posted an issue on the “Hierarchical Term Reference Autocomplete” already :)http://drupal.org/node/1744134

      I’ve not found anything close to what this module does in my research yet. It looks like it wasn’t around or fell under the radar when I was doing my research for this article. The best comparison right now might be “Hierarchical Select Entity Reference” http://drupal.org/project/hser.

      I’m not sure what you’re doing, but in some of my projects where there is not enough time to develop a custom module, I’ll use HSER or Autocomplete as a temporary solution. Widgets can be swapped out easily on fields without any repercussions on the data later on when something better becomes available. In my case, my biggest qualm with Entity Reference and the autocomplete widget is it wouldn’t show you hierarchy (if you used the same term twice but on different tiers of the vocabulary). But, to use that as a solution in the temporary isn’t horrible if that’s you’re only gripe too? Especially if you combine it with a tiny custom module that alters the ajax output to tell you what the parent tier is. Then you at least don’t have to do the whole guess and check deal.

      I suppose it also depends if it’s you or other users that you plan to use the field.

Leave a Reply

Custom Theme by Rob Malon | Content & Design © 2010 - RobMalon.Com - Chicago, Illinois