

The new Relation module

Submitted by nk on Mon, 2011-05-02 17:02

I plan to create a screencast as well but meanwhile, here is a useful guide to the new Relation 1.0 alpha 2. We have relation entities which describe the relation between two or more endpoint entities. Endpoints entities are described by an entity_id, entity_type pair which is stored in a special field called endpoints. This a relation_endpoint type field, you can't create more of this type in the UI nor you can delete the single field of this type from the UI. Once a relation is created, you can't change the endpoints. That'd be a different relation.

Before you can create a relation you need to create a relation type. This is done at admin/structure/relation. Here, you will find some interesting new concepts:

Describes what sort of relation this is. For example, this could be sibling, parent, donation etc.
is best explained by an example: the sibling relation describing Chico, Harpo, Groucho, Gummo and Zeppo would be five. This way we do not need to create some ten relations stating "Harpo - brother - Groucho" instead we have just one relation. This is less common but quite useful.
While the "sibling" relation is not directional, the "parent" relation is. Only binary relations (min and max arity both 2 is called a binary relation) can be directional at this moment as we can't figure out any relation that would be directional and non-binary. You can only pick different bundles for the two endpoints if directional is ticket. This makes a lot of sense: if two endpoints have different bundle restrictions then that fact in itself gives it a direction.

If you want to create a relation from the UI, enable the relation_dropzone module. Go to a page where entities are loaded, one or many it does not matter. In core, the home page, user/1 are some examples. Pick an entity. Now you can go to another page or stay on the same page and pick more as necessary: picked entities stay in the dropzone until you press create relation or clear. When you create an entity, a message will be shown to you which links to the new relation entity page (and lists the endpoints in the relation). While this creation method is not the usual edit form there was no other way as there is no generic way to choose an entity. This way, you can use whatever navigation is already built for the site to find your entities.

The relation entity page shows the endpoints and any fields on the relation entity. Yes, the relation entity is a fieldable entity. That's why we have an edit page here -- while the endpoints are not editable the other fields on the relation entity are likely to be.

If you want to see the related entities on an endpoint relation then enable the dummy field module. This defines the relation field type which can be attached to any entity. It's called a dummy field because it does not support editing or anything, it only provides a formatter. The formatter provides a list for each relation this entity participates in. The list links to the other endpoints in the relation and the header links to the relation entity.

There is Views support as well: under add a relationship you will see your binary relation types as they bridge one entity type to the other. That's all the Views integration we provide right now but that's enough for most purposes.

Finally, it's a common question how do we compare to user and node references? Those modules have restrictions we don't: a reference by the virtue of the storage that module employs is directional and one endpoint has a pre-set entity type (node or user). This allows these modules to have a more traditional edit model as there are ways to choose a node or to choose a user. However, a reference is just a field and you can't easily field it. there are various ways to group together various fields but I feel the relation entity model to be cleaner. Not just code wise -- conceptually, the relation is a separate thing, not part of any of the entities. In the future I would hope the reference modules become integrated with the relation module after some rather interesting discussions.

Commenting on this Story is closed.

Submitted by Anonymous on Mon, 2011-05-02 21:26.

Sounds awesome. Having fieldable relations means that we can do stuff that used to be very difficult. For example, creating a 'team member' relation between a user and a 'project' node, and tagging it with the role the user has (eg. 'project manager') in that project. I will give it a try asap - thanks everyone who has worked on this.

Submitted by Anonymous on Tue, 2011-05-03 08:21.

Subuser 7.x-2.x is making use of relation. Very nice stuff.

Submitted by Anonymous on Tue, 2011-05-03 13:05.

I've been watching / waiting for this module. It sounds incredibly exciting and powerful. I too hope that references can somehow mold/fold into relation api. I can also see the User Relationships module great utilizing the relation api.

Submitted by Anonymous on Tue, 2011-05-03 18:34.

Great. After being a heavy user of Relationships in D6, I really look forward to this.

Submitted by Anonymous on Wed, 2011-05-04 13:15.

I'm wondering how will this be useful to possibly rethink translation relation storage (if not management given the all too generic UI you explain). The core translation module is just relations between nodes. Unfortunately, ideally the relation model would support non-entity stuff as well. So you can make a translation relation between blocks, or a translation relation between menu trees (or menu items). The i18n module for Drupal 7 has some provisions to form those relationships with a fieldable entity holding the relations, and it supports relating non-entities. What do you think about the possible common things here?

Submitted by nk on Wed, 2011-05-04 16:38.

exposing menu links as entities has been thrown around a couple times already. Blocks might be a little trickier but ... why not?