 All right, so we are, my name is Klaus, Elin Svedd, Latharion, Twitter, and DO. And my name is Dick Olsson, I'm at Dick Olsson on Twitter and on Dickson underscore on d.o. Developer at Algesera, down in Qatar, originally coming from Sweden and Node 1, so that's where I'm from. I am CHX in real life, Twitter and Drupal.org. We are going to talk about relationship module. Relationships were thrown at my side since 2005 when we tried to run a reverse bound for a module implementing a generic relationship API. But it didn't go anywhere until last year when at Drupal, San Francisco, bank founder and myself had a most fruitful denerman. We have figured out how could we build symmetric relations and everything else just follow it from that. That was pretty much the history and I am going to let the other guys speak because something marvelous happened as well. This is a counter project that actually has a lot of contributors. Usually counter projects are one-man mission. These excellent gentlemen are maintainers and we have more. We have five or six people actively contributing to relation. I see even more people have showed up. I am just going to say once again that there is overflow space out in the hall with screens and speakers. If you get tired of standing you can go out in the hall. I hope there is a seat left there. There are screens and audio. The relation module, if you want to be really harsh you could say that what we are going to present today is absolutely nothing new at all. But hopefully you will find some use for it as well. There is a traditional solution which many of you probably know about as the reference module. It consists of two submodules. You can relate things to nodes or users. The fundamental problem that is solved by this traditional solution is that they need to link from one object to another. And while this has served very well and is a good solution for that specific problem it is not quite enough for what we want to accomplish. So first of all you can't relate to any other entities than those two that are hard coded into the modules. Users and nodes and if you want to relate to comments to products from the commerce project or to taxonomy to a term or any other entity that is custom made for some purpose then you would have to copy the entire module and rewrite it to suit that purpose. Also it is strictly directional and binary. So you can only relate from one thing to another. Even though you can have multiple field values it is still always from A to B. You can never go back and you can never have a symmetric relationship between several different entities. The storage module is also somewhat limited. We will talk more about that later. It is also complicated to add additional information to the relationship if you want to emulate something like Facebook friends or something that you would need to have an extra text field on for example the user to describe the type of relationship and all the metadata would have to go on either of the source or the target which doesn't really make sense and would clutter the interface. So on the first problem the solution is that we have a more generalized framework so that you can relate to any entity at all. All of the previously mentioned comments and commerce products and all that and if you write a custom entity for a new reason that should work without any problems as well just fine. For the second problem where since you attach a field to the source you would have to have a similar field on the target if you wanted to relate backwards as well and the solution to this that we have is that we add an intermediate entity the relation module defines an entity called relation and then you relate everything to this relation entity instead of directly relating the entities to each other. We have for the storage module the storage model that's used by the references system becomes fairly limited again because it's a field so it's difficult to expand that and in theory do everything with the reference module that we can do with the relation module but since we approach the problem from two very different viewpoints the solution looks very different. So we have a completely different way of storing this data which is consistent no matter how the relation looks and as you can see it's also a very performance. The first example is the way that many of you probably have done this before. You have node A and you link to node B. This could be for example an article node linking to a some sort of kind of fact box it could be a blurb for an article linking to the article and this goes as the arrow shows just one way. Now if you have a binary relation the relationship is going to look like this instead. You have the relation entity at the top and then this relates in turn to both node A and node B and then afterwards you can set if you want this to be a directional relationship or if you want it to be symmetric. An example of a symmetric relationship would be a group of siblings where the relationship between three siblings isn't going in any particular direction they just have this relationship and they are all equals within it. Like we mentioned before the storage model for this is consistent so that if you want to link up more for example if you have three siblings or seven or even more of a completely different kind of object you can just link as many of them as you want into this relation. And then if you look at this one if we say that you have four nodes that you want to link together you need one relationship object and then you link all of them to it. If you would do a symmetric relation with the normal node reference that would look something like this and there is no less than 12 fields involved in connecting all of these if all of them are going to be symmetric so that it becomes a mess if you want to extend it beyond what it is currently doing. Yeah, it basically doesn't work. It becomes a complete mess. So what's really good about this storage model then we have no change in the API to support all these different storage models binary, nr, how many want, directional, biorelection, whatever you want. So no change in the API. It's a very consistent API. No change in the storage as I just mentioned and we can also have a very consistent UI for dealing with all these different sorts of relations. We'll talk a little bit more about the UI. We're going to have a demo here later. And the fourth problem that Letharian mentioned here is that the old way of doing references you can't have any additional information on the relation itself. And the solution for this is obviously now the relation is an entity so now we can have whatever fields we want on the relation itself. He mentioned a very, very good use case about Facebook friends. You can have the type of relationship, friend, family, etc. Another example could be you have user entity, you have a party entity and then you have a donation relation in between them. A field on that relation could be amount that you donate for instance. So it becomes a really nice and consistent way of doing things. And some additional niceties that just happened basically. This was not the intention to solve but that comes very natural with the whole thing is that integrates very well with D7. You couldn't really do this in D6 too. It just plays very nice with the entity model of doing things. So that's a good thing. We also have integration with Contrib. We have views integration and we also have good basic rules integration that I'm gonna show you. It's very, very API driven at this point which is the intention with this module for very heavy custom stuff. There's some UI too that I'm gonna show. Also another problem that I'm personally dealing with since I'm maintaining the deploy module is that it makes content staging much easier. Content staging is something that Dries mentioned in his keynote that is something that's gonna be emphasized in Drupal 8, a problem to solve. And why does it make the content staging much easier? Think about the scenario if you have the old reference model where you have two nodes and sometimes you want them to reference to each other. There are many cases you might want that. What that creates basically is a circular dependency because what we have to do when we stage content is that we first move all the dependencies. So all the references needs to be deployed first before the main node can be deployed. So here we have a very circular dependency. You can't move any of the nodes. Exposing an API could be tricky, etc. Here we have one relation entity in the middle. You can deploy all the nodes and then just deploy the relation entity after that. So it makes content staging much easier. And also it performs very well. The views performance, chicks can talk a little bit about that. So this is just more or less a footnote but some of the things of the storage model it looks fairly scary. The query views generates for this. But we have actually timed it. And despite the query looks pretty scary it's actually not a performance killer. The only cost difference between using references and relation that you need to deal with one more join. But it doesn't change the type of query you are dealing with. If you only join to have information on both endpoints it's gonna be equally performant. If you are filtering on both endpoints then it's again going to be equally performant which of course with SQL means that it is not going to perform at all. Because that's the fundamental problem, right? That if you join things together and filter both then you cannot really index those. I think this was all that I wanted to mention about views performance. We have nice views and rules demo. Yes, and I'm gonna do that here. Just need to arrange the mic a little bit. Yeah, I am very fast. I hope you got all of that. No, I just need to clone the screen instead of doing the presentation mode. Fis like I'm gonna have some play piano or something. Okay, so what I'm gonna demonstrate here is three different things. First I'm gonna show the interface of how to create different relation types. Basically how you create the different bundles. Similar to how you create different content types of nodes. So that's the first thing I'm gonna demonstrate here. Under structure we have relation types. Right now we have three different types of relations here. We have donation and a few test relation types here. We can start by adding a new relation type here. Let's say we call that enlarge, okay? Turn off the overlay margin. To use some more. Where do you have the scroll? There you go. Is that better? A little bit? Okay, so adding a new relation type here. First we just want a label of the relation type. Let us say that we wanna create a transaction. It could be a bank transaction or it could be anything. We have a machine name automatically created here. We can make it directional if we want to. And we have a reverse label here too. So we could say this could be a transaction to bank. And if it's directional, that's a transaction from user, for instance. We have a few different options here. Maybe you wanna describe in detail chicks very, very quick here. No, okay. These are not that important. Okay, okay. Here we can choose the artery of the relation. We're gonna keep it simple for now. But here we also have the source bundles. Basically what bundles can be the source bundle. And what bundles that will be the target bundles, okay. So in the transaction here we probably want user, for instance. To a donated. Yeah, I'm just gonna do a generic demonstration. And then we're gonna show the donation relation. So just to demonstrate here. We actually don't have a no type for, for instance bank here. That's right. So what you could do actually here because if you go down to the bundles. You can see a very interesting thing that the relation types are also listed as possibilities to relate to. You can create such things because relation is an entity in itself. You can actually relate to that relation. Which actually here is a good use case. Because if you have a user which donates to a party. Then that donation can be linked to a bank. Saying that this was a bank transaction. And that's best described by actually relating to the donation entity itself. So this is another nice thing of relation that you can exploit very nicely. That relation is just an entity as any other. Okay, so just to step back a little bit here. I'm just gonna demonstrate how the donation relation is set up here. Label as I covered, it's directional for this one. And the source bundle, the donation is coming from user. And we for simplicity just choose all node bundles. Probably you wanna choose the party bundle here actually. I'm not gonna change that at this point. So that's the very basic settings you have to set up. So you need to figure out what kinds of relations you have on a site. Usually you just have fields for this. But here you need to think a little bit more about what kinds or what types of relations you have. Okay. And to demonstrate the views integration here. I'm gonna show how we set up a few things first. So here we have a party node. Have a view here yet. Stack on. View. Ah, okay, it's under donations. So here we have a very basic demonstration of the views integration. We have admin has donated twice to two parties. The Drupalcom party and another Drupal party. As you see here. And you see here, the interesting thing here, we have amount. So the donation here, the relation itself has amount. And to see how that works. We go here relation types. And for the donation relation type here, we can manage fields. And as you see here now, we have a field on this one. Okay. And it's just a basic text integer field at this point. Works as any other integer field. So you're probably very familiar with this one here. The settings here. So that's the view. We can go in and look at the settings here. So there's one thing you need to take in mind here when you create views with these kind of relations to it. You need to add. Depends on your use case obviously. But here we have two relationships added to this view. One from as we see here. From the user to the node itself. And then from the user to the relation. So we have the fields too. So we can show the amount for the donation. So this one is very new. I only commented the user to relation a few days ago. And this one is probably going to change in the future. We are working together with the views maintainers. Figuring this one out. Because it's a tricky problem to solve actually. Because sometimes you just want to go from the user who donates to the party who have donated to. On the other hand, other times you want to stop on the relation entity meanwhile. So you actually want to add user to relation. And then relation to party. But the problem is going to be that if we do the latter. Then everybody will be forced to always the two relationships. That's how voting API works. It's not the end of the word after all. I am just a little bit reluctant to force everybody to always use the relationships. So this is still in a little bit of a flux. Ok, so that's basically it for the views relation integration here. Most of you here are probably very familiar with the views interface. And how you play around with the different relationships. So I'm not going to cover that in detail. But that's essentially what you need to do for now. To be able to extract the field information and such from a relation. So we're working on that as Chicks mentioned. Another thing I'm going to demonstrate here is the rules integration. I'm going to show you how to set that up. And we go into population. Ok, there you go. We have workflow rules here. So this is a little bit of a tricky one. So I'm assuming here now that you're familiar somewhat with how rules works. I'm not going to go in very detail on everything. So I hope you will follow me here. And unfortunately I don't have a practical use case. I'm going to demonstrate how to set up the configuration and such. Because that can be a little bit tricky. So we have a rule here. User donated something. I'm going to edit that. Use case here is now continuous being viewed. We're triggering on that. So as soon as someone looks at a party. That user automatically donates something. Which is a pretty neat thing, isn't it? Yeah. We could set up conditions here. Only party node. You probably want to do that. They are even donating even if they are looking on pages here. Even better. So the setup here. It's a little bit tricky. Here we have some debug code. We don't need to check on that. Ok. Anyway, so first thing we need to do. Is that we need to create our array of endpoints. Ok. So I'm talking a little bit in PHP or programming lingo here. But it will make sense here. So first thing we need to do is to add a variable. And basically you have an action. Can show you how to add action. And it's basically the first thing you have here. Add a variable. And the type of variable should be List of entity items. So that's the kind of variable you want to add first. So create the array basically. Add this one here. So this is how it looks. The array at this point is empty. Ok. The next step is to add an item to this array. So the first thing we do here. Is that we add the current user to that array. So the user that is logged in right now Is first added to that array of What will be the endpoints of this relation. The next thing you want to do Is to add another item to your list of endpoints. And in this case it's the node that we are viewing. And at this point you have two entities in your endpoints array. You could add different even more nodes here. You could take in nodes from different relations. You can play around here pretty much with the whole rules API. And I'm assuming that you're somewhat familiar with it at this point. So what we got now is that we have an array of endpoints. Basically two of them. I'm going to skip our debug here. And then we have an action called create a new entity. And this action here is provided by the entity API module. And so we're adding creating a generic entity Which happens to be a relation at this point. A relation type. A donated to. And it also picks up our field API field here. That we have for endpoints. Which is the list of entities that we have here. So what this configuration now does Is that it will save this relation With the provided endpoints that we have here. The use case I'm demonstrating here Is might not something that you do on a production site or anything. But that's the basic How you're approaching the rules configuration with it. And it's exactly the same if you would do it in code. Array of entities. You pass that into the same variable. We have a question in the back. And I think we can take that now. So to repeat the question is that Do I have to add the source of the relation As the first item in the array. Or the endpoint array. Yes that's true. That needs to be the first. When it's directional of course. Just then that's when it only makes sense. So that's true. So that's the basic rules integration. Claes is going to demonstrate The relation block that we have To create relations in a different way. So this is one way you can do programmatically And Claes is now going to demonstrate Another way of creating relations. Okej. She's going to answer that. I'm not surprised at that question Because this is probably The most popular issue in our issue queue. First the question is wrong. I didn't repeat the question which was Can you add the relation from the node that it forms. The answer is that This is being worked on. But this is more often than not Is the wrong way to think about things Because relations are not part Of the endpoint. They are separate entity. And so if you are creating it from the Endpoint entity creation screen Then that's probably the wrong approach. I know that this is As I say, very popular. So this is being worked on. There's actually a code that I could say works somewhat. It's not tested yet. I mean it doesn't have automated testing. It works enough. But there are several technological challenges In this. Namely in rule 7 The entity API Just not enough time to do everything. And for example There's not really a way To provide a generic autocomplete. There is just no way Because the way the entity API works There is absolutely no guarantee That the label of the entity Is going to be a column In any database So you cannot really Find an entity Based on a label In case for example Relations The relation entities Do not have any label defined For example User model For user What we do is We basically step outside of the entity API Because user module already provides a user Autocomplete But the user entity's label If you look into the user entity definition Is created by theme username So you cannot really Have a generic way There is just no generic API for that Basically It just wasn't It's just not done. So we are going to provide an autocomplete It is going to work for some entities Not going to work for every entity Because that's impossible to do It is going to cover about 80% of the cases And of course there is also the problem Where you want to create an entity With several endpoints We came up with a very different UI Which solves all these problems Which I am going to let a class to Demonstrate that one Maybe I will say a few words Before he demonstrates So basically what we do here Is that we realize that The entities that you want to relate to You probably have some way Of finding them already We do not care how But we presume that your site has a navigation Or just the admin knows how to get there And we are reusing this A class is going to show how All right so We have on the left side here A block Called the entity collector And if we look at the list here We will see Drupal party And Drupalcon party Which as was just mentioned We have them here I have navigated to in this case Just the front page which lists these two entities So I could now pick I will have to do this in the reverse order Actually if we are going to create a new relation We will go to user one Also an entity So I have here user admin And I will add that to donated to I add user first Because this is a directional relation So user will be the source Pick And then I have In my picked entities list here User admin Now if I Go back to the front page I still sort of carry around This picked object This entity from before I can add Say the Drupalcon party Now I have these two here And then I could if I wanted If I wanted to add further As many Endpoints as I wanted And then I click create relation And then I get a new relation So Nice I wonder if that's our rules integration Or if it's a other rules bug We'll have to look at that So here we are viewing the actual relation And here we have the amounts field Which we can add a value to Do you want to say anything else? As you have seen The relation entity edit screen Bring that back please The edit screen You cannot actually edit The relation itself This is something that we Debate heavily right now How do we continue with this But traditionally There is not really Any point Is editing an entity Anything relation Because if you need to edit it That is actually going to be A different relation At most what you want is delete the old one For example If two people are married They divorce and remarry That's definitely Not gonna be the same entity Right? Oh yeah, those one can The fields can be edited The fields absolutely can be That's a very valid point Yes That's a different thing It's the end points that you cannot edit Yes That's one of the problems that does Mistakes are hard to correct If you don't allow editing But allowing editing Gets really really tricky To be honest Because Due to the problem With entity selection It's untrivial basically What we could do UiWise Probably maybe Two things One That we after all Are going to have A field Edit widget on the Where you can create A relation after all So there we might Want to allow editing The other one that we could do Is that you pick an entity Go to the relation entity view screen And there you can say Replace this one With the one that you have picked The other thing that I was Considering Is to create relation types To add another flag To the relation type Which is editable The relation type itself Would be editable or not Because I believe That it's good to actually lock down Most of the cases You don't really want to edit Before we can take any more questions I just want to mention Some quick things here Chicks are already covered here We're looking into creating a widget for it For Doing relations We have even more view support coming So that's almost done Another project That we want to look into is also replacing Because in core We have all sorts of different Types of relations And everything Is implemented in its own way Everything works differently So have a very consistent relation Model in core would be Something that we probably want to have So we Are probably going to look into that Another thing that We've been thinking of is also Entity hierarchy Module Imagine having Hierarchists as entities And you can provide more information To that entity too Well, sorry But in here the entity hierarchy The problem is that In core, for example You have taxonomies Where the taxonomy terms Have their own way To provide hierarchy between entities You have comments doing it A different way, you have books doing it A shared way So there's no doubt that it would be great To come up with a consistent way To handle hierarchies But that's a different problem space And because relations create entities If somebody comes up Entity hierarchy module Which I'm not saying that it's not going to be us Then relation is going to slot Into that one really nicely But that's not a problem That relation wants or needs to Solve It's a really, really hard To solve issue On the other hand Relation was also something that seemed impossible For a very long time Until we came up with this A weird idea Of adding an intermediary entity So it is possible That we will be able to come up with something But I can tell you that Entity hierarchy in general Is extremely hard And if you Go with the textbook Ways It's not really doable With the databases that we work with And it's literally the textbook Vadim Tropasco has A chapter on Storing trees In a sequel In his book But neither of these are going to work With my sequel, the guy works for Oracle So you can guess what those solutions work with But there are no other solutions really So Questions about relation Not hierarchy questions I'm not taking hierarchy questions You were the first There's UI The storage could handle it So the question was Why you cannot edit relations It's UI And it's concept There is nothing in the storage model That would stop it The end points Are just a field on the relation entity So Field API Perfectly supports Updating fields And so That's absolutely possible I'm just I'm just reluctant to do it But I guess that people are going to come with me Because they have to provide a widget On the note of the screen To create a relation Which I was absolutely unwilling to do for a long time Yes Okay, so Vad Claes said is that Please take the story It's extremely important for future DROPA cons Whether if we were If we really stuck here Let us Ruin another DROPA con So please take the story You can already do this with rules by the way Don't even ask We So the question was What about permissions This is an extremely gnarla issue Because That's another thing That entities do not really solve At this moment And It's just Insanely hard You have A relation With Even just two endpoints What is the module Supposed to do If you do not have access to one of the endpoints Is this going to Immediately deny access To the relation I would suspect that's not what people want Because it is possible For example You could subscribe You could login And suddenly the other end point would become Visible so people probably want To be able to reach The relation and the screen And say you need to do this or that To be able to reach the other end point So that probably shouldn't deny Access to the relation On the other hand For other use cases it is definitely Possible that if one of the endpoints Are access denied Then you do need to deny access to the relation So that's one problem too Aside from concepts There is absolutely no entity access system There is no consistent entity access system At all Which would make this And they were very hard Dominant Dominant especially Is planning to fix some of this On friday at the code sprint Because this can be viewed As a security issue against Drupal 7 That you just don't have A consistent entity access way So the question is very real And what can I say Not much So you only have one array of endpoints Yeah repeat the question You want to ask if It was required to have two arrays Is that correct Why not two arrays Well we only have one The thing here is that we want symmetry It should be symmetric The relation should be symmetric So we only have one array of endpoints So that's the fundamental problem That we're trying to solve With the module The relation itself should be symmetric And if you If you had a different We want to avoid having a different way Of creating directional relationships We want it to be as consistent as possible So that's why we only want one array And then in the Special case of a directional one The first element is the source Okay Yes so the question was Do we plan to do anything Where you have a graph The answer is a very definite yes Common tolerance has a graph API module Has relation integration already Awesome so you can actually draw those graphs already And there is an open issue To provide an API for this So the question is most definitely yes Half of it already works So it's Yes very much yes Johan again No this one Is using As I said endpoints Are fields So whatever field storage engine Or if you want to use Be it MongoDB Elastic search PBS I don't care I'm storing endpoints as fields Exactly for the reason you have mentioned So that we can use any database That you want with this No more questions Okay So are the F exposure There is an open issue for that as well Patches are welcome You are most welcome Oh It seems that we ran out of time So thanks for attending Please fire in the survey