Hello,

I've a relationship, where users can "follow" nodes. I'm going to create a view that shows all nodes, the user follows. Very simple so far.

I just added a relationship "Relation: user -> endpoints[User <> *]) " to be able to filter my result by the user id.

To filter the result by the user id I added an contextual filter for my relationship and I told the filter to use the user id, when no other values are provided.

This is the generated SQL by the view:

SELECT node.title AS node_title, node.nid AS nid
FROM 
{node} node
LEFT JOIN {field_data_endpoints} field_data_endpoints ON node.nid = field_data_endpoints.endpoints_entity_id
LEFT JOIN {field_data_endpoints} field_data_endpoints_field_data_endpoints ON field_data_endpoints_field_data_endpoints.entity_id = field_data_endpoints.entity_id AND field_data_endpoints_field_data_endpoints.endpoints_r_index != field_data_endpoints.endpoints_r_index AND field_data_endpoints_field_data_endpoints.endpoints_entity_type = 'node' AND field_data_endpoints_field_data_endpoints.bundle = 'user_follows'
WHERE (( (field_data_endpoints_field_data_endpoints.endpoints_entity_id = '1' ) ))
LIMIT 10 OFFSET 0

This is very very close to the solution. There's just one problem in there: As I'm going to show only nodes in this view, it ensures the entity_type is 'node' (AND field_data_endpoints_field_data_endpoints.endpoints_entity_type = 'node'). If I remove this exclusion manually I got the expected results. I can't remove this in the view ui, because this is set in the first view creation step.

So it would be great to select every endpoints_entity_type in there (get rid of the previous mentioned exclusion) and use a manual filter through the view ui to filter the results myself, based on the entity_type. It seems this is not possible so far, so I've marked this as a bug. If it's possible I would be very thankful for any hints.

Comments

hevr’s picture

I temporary got it working by hacking the module:

relation/views/relation_handler_relationship.inc:
77c77
<     $conditions .= " AND $r.$entity_type_field_name = '$entity_type_right' AND $r.bundle = '$relation_type'";
---
>     $conditions .= " AND $r.bundle = '$relation_type'";

I'm not sure under which conditions the entity_type must be ensured but it would be great to be able to deactivate this using some kind of View UI setting. Please merge this somehow into your module.

With this hack I'm able to show nodes based on the currently logged in user and of course a node <> user ("follow" or "likes") relationship. That's an awesome feature!

chx’s picture

Status: Active » Fixed

I just rewrote the whole of Views integration: reverted to the original version but made it nice.

hevr’s picture

Hello,
I see the difference but at the moment it's not possible to choose a node <> user relationship, it's only possible to choose node <> node relationships.

With the previous version (and the hack) I could apply a contextual filter to show only nodes based on a user <> node relationship.

hevr’s picture

Status: Fixed » Needs work
acrazyanimal’s picture

@hever: I've been playing around with this too. I'm using the latest dev that picks up chx's new and improved views integration. I can confirm that you cannot come at the relation from the reverse end. So if you have a directional relation such as user > node (haven't checked out symmetrical yet) you cannot create a content base view and select the relationship for the reverse of the relation: node > user.

However, if you create a user based node then you can use the relationship user <> node or user <> relation. By doing so it reveals the fields you need from the node or relation respectively. You should be able to create your view of nodes that a user "follows".

In addition to this I will mention that it is probably important that you select the relationship base to be the source, indicating that the user is the base of the relation and make the relationship required so that you don't get duplicate rows.

You can also create a view that included fields from the user, the relation, and the node by using the user <> relation relationship (base = source, required = checked) and then the relation <> node relationship (base = target, required = checked, relationship = follow) ... no duplicate rows, amazing chx!

chx’s picture

Title: Show nodes based on a node<>user relationship using views » Reverse doesn't work
Component: Miscellaneous » Views
Status: Needs work » Active

Bug report: If you have a directional relation such as user > node (haven't checked out symmetrical yet) you cannot create a content base view and select the relationship for the reverse of the relation: node > user.

hevr’s picture

Yes, if I change my relations from being directional to non-directional I'm able to add the relation between users and nodes. I can also add a contextual filter and show only nodes that a user "follows".

But I'm not able to show also nodes, that are related to the node the user follows, as described here: https://drupal.org/node/1410522. (But that's perhaps just because I don't know how and not a bug.)

I really need to set up bi-directional relationships, so I hope you're able to fix this issue to get the views/relations also working with bi-directional relationships.

I'm also wondering about the directional / non-directional relationship naming because I have to use directional relationships to solve "bi-directional" relations like if A relates to B, B automatically relates back to A. From the description of the user interface I'm doing the opposite of what I should do, but if I choose non-directional relations I don't get the auto-bi-directional relations. Perhaps you can clear this up a bit too.

mustanggb’s picture

Status: Active » Needs review
StatusFileSize
new1.89 KB

I would image this is a pretty standard use case

Is this patch the right approach?

chx’s picture

That does look wonderful. Do you think you could write a test for it?

Edit: but also, you want to check whether this is different from the forward relation and only provide it if it is. If you have a node <-> node then providing it twice is not helpful.

mustanggb’s picture

StatusFileSize
new19.94 KB

I apologise in advanced for the kittens killed during the making of this patch but this is the first test I've ever looked at so please have mercy on my soul
Entity type check added as chx requested
Also pretty sure it breaks RelationAPITestCase and I couldn't figure out how to fix it

Status: Needs review » Needs work

The last submitted patch, 1410124-add-reverse-relationships.patch, failed testing.

franz’s picture

I'm looking into this, but seems like relationSave() test tries to save one of the new relations with node endpoints (should be user-node)

franz’s picture

StatusFileSize
new21.07 KB

Yes, it was. I had to quirk it here and there, making it short:

relationSave() test got all relation types, create relations with them and arbitrary endpoints and saved. The newly added relation type, however, had a "user" endpoint, and so the whole logic was borked. This patch fixes that and compares the entity_types of the created relation with the original.

chx’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 1410124-add-reverse-relationships.patch, failed testing.

franz’s picture

Funny, 2 other tests failed now. Something else now. Because new relations are using same nodes, relation_get_related_entity() become ambiguous.

franz’s picture

Status: Needs work » Needs review
StatusFileSize
new21.84 KB

Still don't get why those tests didn't fail on #10. They are passing on local now

franz’s picture

StatusFileSize
new21.75 KB

Damn, left a print_r in a verbose...

chx’s picture

Status: Needs review » Fixed

Thanks a ton.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

mustanggb’s picture

Brilliant franz, thanks for picking this up

sonictruth’s picture

Did this ever get committed? Reverse relationships really are a big use case for Relation module.

i.e. I'm building a view of courses that a user can register for—a registration being a relation between a course and a user—and I want to output a list of courses that user hasn't yet registered for. This seems impossible with the current set up.