Hello,
I was wondering if someone might have a solution to this problem. I've been plugging away at this for hours trying to figure out how to make this work.
I have a scenario where i have created two profile types, and each user will have two profiles. One profile stores contact information (address, city, etc) and this information through the permissions is able to be edited by the user. The second profile is information that is related to a user's membership, so things like membership ID, year joined, etc. This information is such that it can be viewed by the user, but not edited. I have created a role called 'membership admin' and they can go in and see and edit this information.
So far so good.. Profiles work as expected.
however, when trying to use views to create a profile table view and to look at the information from both profiles - per user - i cant seem to get it to show just one line containing info from both profiles. What i get is two lines per user, one with the fields from each individual profile.
So for example, id like the table to show:
Bob - 123 anystreet - anytown - 2005 - #4344 (so you see, info on the same line, but from two different profiles)
I tried creating a user view and using relationships to profiles, and creating a profiles view and create a relationship to users.
Any way i try it, i cant get around the two line output.
Maybe this is an issue in Views? Entity?
Thank you kindly.
Tom
Comments
Comment #1
joachim CreditAttribution: joachim commented> I tried creating a user view and using relationships to profiles, and creating a profiles view and create a relationship to users.
I didn't think both those relationships were available!
Anyway, the problem is that you need the user -> profile relationship to be able to restrict by profile type. Which requires some work in our views support, which is here #986430: Improve the views integration.
Comment #2
u8915055 CreditAttribution: u8915055 commentedHi there joachim,
Thank you for your response. Yes, it seems the relationships part works. So far, i've tried the following:
user view with relationships to both profile and profile-type
profiles view with relationship to both profile-type and users
profile-type view with relationship to profile (no user relationship available in this one)
They all seem to work. I can grab all variables and include them in the view as necessary.
The big problem is that when it comes to users and profiles, each line is displayed per unique profile entry, not per user. So for example, if i've defined the following:
Profile1
- field : nickname
Profile2
- field : age
Then i fill out both of these profiles for a given user, say UID=3
Then when i try to create a view for users and show one line with both details, i get two lines, one per profile per user.
Effectively things need to be sort of grouped per UID and merged. I dont think there would be an opportunity for duplicate fields across multiple profiles by the way the fields are actually stored in the database (naming wise).
Anyway, just curious is to maybe it something im not doing right, or is it a views issue, or maybe entity issue.
Thank you very much for your response.
Tom
Comment #3
joachim CreditAttribution: joachim commentedYes, I understand the problem -- the solution is what I described in my earlier comment.
Comment #4
joachim CreditAttribution: joachim commented... actually, let's work on that here as the other issue needs splitting up.
Comment #5
joachim CreditAttribution: joachim commentedHere's a patch that gets us most of the way -- the only thing that needs doing is the querying part (and writing a few bits of doxygen...)
Don't know when I'll have more time in the next week or two, so perhaps someone else can take this forward?
Comment #6
joachim CreditAttribution: joachim commentedI did a bit more on this; we're blocked by this bug in Views: #1118100: JOIN 'extra' fails with multiple value.
Comment #7
joachim CreditAttribution: joachim commentedHere's the patch; though the patch from the Views issue needs applying too.
Comment #8
u8915055 CreditAttribution: u8915055 commentedHello joachim,
Thank you very much for the update on this. I really appreciate the work. If my coding skills were more up to date, i would help you write some of this.. Im just learning the Drupal system with hopes of being able to contribute code in future at some point.
I looked at the views patch, at least .3 of the patch and your .2 of the profile2 and ill give these a try and see where we get to.
THank you again joachim,
Tom
Comment #9
BazzeFTW CreditAttribution: BazzeFTW commentedjoachim, I tried your patch but when trying to add a relationship I get the following error:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AND _users.type IN 'teacher', '0' INNER JOIN drupal_users_roles users_roles ON u' at line 1
And in the list of relationships it says "User: Error: missing title".
Comment #10
joachim CreditAttribution: joachim commentedThanks for giving it a spin -- you need to also patch Views; see link above.
Comment #11
BazzeFTW CreditAttribution: BazzeFTW commentedHmm... After applying that patch as well i get additional error messages (well, notices actually):
Comment #12
joachim CreditAttribution: joachim commentedDid you clear your Views cache?
Comment #13
BazzeFTW CreditAttribution: BazzeFTW commentedYes I did! When trying to access the view you get the "drupal has encountered an error"-screen and the following errors occur:
Comment #14
joachim CreditAttribution: joachim commentedDid you edit your view to select a profile type in the relationship?
Comment #15
BazzeFTW CreditAttribution: BazzeFTW commentedYes I did. I've created a view based on Users and added the relationship, and as I mentioned earlier when adding the relationship it is named "User: Error: missing title".
Comment #16
joachim CreditAttribution: joachim commentedWeird. I had this working perfectly on my setup.
I'm on holiday from this Saturday so I won't have any more time to look at this for a while -- over to anyone else who wants to work on this :)
> LEFT JOIN {} _users
That looks very suspicious. Have you got the very latest versions (ie git pulled) of Entity, Profile, and Views?
Comment #17
Jerome F CreditAttribution: Jerome F commentedI tried creating a user view and using relationships to profiles
Configure Relationship: Broken/missing handler
I use last git of views and profiles 2 and applied both patches.
EDIT : this is not true anymore with the patches applied I can create an User: Profile relationship
Comment #18
Jerome F CreditAttribution: Jerome F commentedI tried the other way around : creating a profiles view and create a relationship to users
Here the handler exists and I can retreive user data. First problem I see with this is the one described by u8915055 the duplicate entries due to the multiple user profiles :
1) So I added the profile type relation Profile: Type
2) and then I have new filter criterias available like (Profile type) Profile type: Machine-readable name
This way I can get rid of duplicates based on profile type.
It leaves me with the struggle to pull some fields from profile type A and some fields from profile type B together in the same view for each user.
Maybe something I can do with views field view if I can't do it an other way, I'm going to play that.
Comment #19
Jerome F CreditAttribution: Jerome F commentedI just want to share that in a profile view once you've added the Profile: User relationship, using this relationship, you can add an other relationship : User: Profile in which you can select which profile type you want to use.
EDIT: now that User: Profile relationships work it's useless. I can go for the user view solution, thanks to joachim's comment there I went some steps further:
http://drupal.org/node/1119130#comment-4351078
Comment #20
joachim CreditAttribution: joachim commented@Jerome F: I don't understand where you're going wrong with these patches. They remove the need for the filter. To make what you want, you would create:
- a user view
- add a relationship to profile, limited to profile type A
- add some fields on this relationship (so fields from type A)
- repeat for other profile types
Comment #21
Jerome F CreditAttribution: Jerome F commented@joachim: sorry I forgot to update in this issue the problems in #17 to #19 are solved, just the way you described it in #20.
So I'm changing the status of the present issue to reviewed and tested by the community, as the relationships work fine.
The problems I still had in views belong to other issues, when I wrote #17 to #19 I was still confused by these issues: I had duplicate entries for users, but that's an other issue I described in: http://drupal.org/node/1135744 I had duplicate entries in the profile table in the database.
I also had problems with views taxonomy term fields exposed filters widgets, and it turns out it's a i18n_taxonomy issue http://drupal.org/node/1135798 - not related to Profile2 in any way.
Comment #22
joachim CreditAttribution: joachim commentedThanks for the review!
We're still blocked by #1118100: JOIN 'extra' fails with multiple value, as soon as that goes into Views we can commit this.
Comment #23
joachim CreditAttribution: joachim commentedIn light of fago's comment here -- http://drupal.org/node/1111936#comment-4416486 -- I'm wondering whether the implementation of this needs to be rethought.
@fago: what do you think?
Comment #24
fagohm, I don't think we need profile2 specific views integration for this. You can already add the relationship + a filter on the profile type machine-name then, no?
We might want to
* add an options-list for that
* allow using the filter directly on the profile2-type db column
But this are things we should be able to improve in the entity API generically, so let's do so. If this doesn't work out, we can still go this way.
Comment #25
joachim CreditAttribution: joachim commented> You can already add the relationship + a filter on the profile type machine-name then, no?
Will that let you have several relationships, each to a different profile type?
Comment #26
fagoyep, that's possible. I just gave it a test and you can already configure it now. See my attached view.
But I agree, that the relationship-option makes sense too. I guess we can do that generically in the entity API views integration too though.
Comment #27
Jerome F CreditAttribution: Jerome F commentedSo why is this still won't fis if the relationship-option makes sense, I don't get it? The patch here did work with the views patch in #1118100 and the result was good.
I guess the answer is in:
but this is beyond the scope of my knowledge in Drupal.
For the moment, I keep my views running with these patches and I'm prepared to change these views when your alternative will be ready.
Comment #28
fagoI've created #1175662: improve auto-provided views generation based on #24
Comment #29
Jerome F CreditAttribution: Jerome F commented#1118100: JOIN 'extra' fails with multiple value has been commited
Comment #30
bochen87 CreditAttribution: bochen87 commentedThe patch in #7 works very well and should be commited to the latest dev version. The reson why to use this patch instead of the workaround with Profile relationship + filter is:
If you have certain profile types, that are optional, then all the users that did not fill out the optional profile, will be filtered out by the where clause. But if you do this in the Join, then you can leave them in the result by doing the regular filter and making an or with the profile to be empty. This way, you could also add optional profiles.
Comment #31
fagoThat's an argument.
Let's do it in the entity API for all relations to entities having a bundle though.
Comment #32
geshido CreditAttribution: geshido commentedsubscribe
Comment #33
joachim CreditAttribution: joachim commentedI don't think we can do all of this in EntityAPI:
We can't do this part in EntityAPI -- only each entity knows how it relates to others.
What's the EntityAPI equivalent of this bit?
I reckon we can move the relationship handler to EntityAPI, but it's have to be each entity's hook_views_data_alter() that makes use of that to define relationships to other entities.
Comment #34
fago>We can't do this part in EntityAPI -- only each entity knows how it relates to others.
Well, the entity API knows about the bundle relationship and this is exactly what we need here. If the entity for which we are adding a relationship has a known bundle entity, provide the option.
>What's the EntityAPI equivalent of this bit?
Using entity_label(). Also, there is already EntityDefaultMetadataController::bundleOptionsList() which handles the same case by getting it from entity-info.
Comment #35
dalanz CreditAttribution: dalanz commentedsubscribe
Comment #36
kthullIt looks like some people in the thread consider this resolved. I don't see how. Specifically regarding #18 and #20 and #26, I am still getting a separate result per profile type, so in my case I get two rows per user. I've read through this several times last night and even a fresh look today trying various views from either a user, profile or profile type base table and I'm getting nowhere.
Even importing the view from #26, I still get two rows of results per user.
Is there any way combine fields from profileA and profileB into one views row?
EDIT: Applied patch from #7 and still get a separate result per profile type and I'm running the latest (as of two days ago) devs for both views and profile2.
Comment #37
joachim CreditAttribution: joachim commentedHmm actually, just spotted another problem doing this in entityAPI.
We want a user->profile relationship. That means we define a field on the users base table. Which means we need to do it in hook_views_data_alter().
Obviously, the controller class we create in entity_views_data() can figure out what it needs to say about the users table, but how do we hang on to that information until hook_views_data_alter() is invoked?
(@kthull: nope, this isn't resolved. More work is needed, but it's quite a complex issue.)
Comment #38
joachim CreditAttribution: joachim commentedMoving to Entity API. And I guess it's a feature request here -- even though this missing functionality is a bug in Profile2 ;)
Here's a patch. Try creating a relationship from users to profile2 to see how it works :)
The logic for when we use the type-limiting handler is:
- going to a single-bundled entity, eg user: use regular relationship
- going to a bundled entity, BUT coming from the entity that is the bundle, eg profile type -> profile: use a regular relationship, as limiting by type here is meaningless
- anything else that has a multi-bundled entity on the right: use the new type-limiting relationship
For this, I've had to add a property 'single-bundled' to the entity info.
Comment #39
crifi CreditAttribution: crifi commentedIs this issue a duplicate of #1066398: Reverse entity relationships for Views integration?
Comment #40
joachim CreditAttribution: joachim commentedNope. It adds a better relationship handler to both forward and reverse relationships.
Comment #41
crifi CreditAttribution: crifi commentedOkay, thanks joachim for the clarification.
Comment #42
fagooh, great - thanks for working on that. I've done a first review:
There is an easy way to derive that information already: check whether there is a bundle key given under entity keys ( just check whether it's not empty).
You should be able to read this out of the base-table already?
E.g. see the views_handler_field_entity in Views.
I guess this comment should be moved to the else part.
It limits the join to a specific bundle of an entity type. (Yes, in our case that are entities too, but using bundle here should make clearer of what we are talking here.)
The same way, I think we should call this bundle/bundles instead of entity-type(s).
Comment #43
joachim CreditAttribution: joachim commented> You should be able to read this out of the base-table already?
E.g. see the views_handler_field_entity in Views.
I didn't think so -- eg with profile2, we have profile / profile2. I looked in the data the view handler has at that point, and it's not there.
> The same way, I think we should call this bundle/bundles instead of entity-type(s).
That's UI text -- in the UI we say 'types' surely?
Comment #44
fagoIt must be there, see EntityDefaultViewsController::views_data():
Makes sense. So what about using the bundle-entity-type-label in the UI + "bundle" as options key?
Comment #45
joachim CreditAttribution: joachim commentedBut when you're adding a relationship, your relationship handler doesn't have the data for the base table you're joining to. I suppose I could go pull it out of the whole big views data stuff...
Comment #46
fagoit recently got fixed in Views to be located at the table not on the base table level. We'll have to adapt to that location in the entity api too - see #1270982: only base-tables can be assigned to entity types
Comment #47
joachim CreditAttribution: joachim commented> single-bundled
Yup, that's a much easier test. I've used it directly, though on second thoughts I think the 'single-bundled' flag on entities could prove useful to other modules for developers who don't manage to figure out the sniffing technique... what do you think?
> You should be able to read this out of the base-table already?
Yup, done.
> I guess this comment should be moved to the else part.
Moved the comments. Though I'm never entirely sure where makes more sense for if/else comments. I like a comment above to if() to explain what is being tested.
> So what about using the bundle-entity-type-label in the UI + "bundle" as options key?
Not sure what you mean there. Is there callback that given 'node' says 'type' and given 'term' says 'vocabulary'?
Do you want the string 'type' replaced with 'bundle' in the name of the class & other parts of the code?
Comment #48
rlmumfordWas going review this but it didn't apply - entity api dev version as of today.
entity.views.inc patch does not apply
Comment #49
joachim CreditAttribution: joachim commentedHere's a patch rerolled against latest from git, with the changes mentioned in #47. Still needs some work based on fago's comment, but a review of functionality would be great.
Comment #50
rlmumfordFunctionality seems to be good.
If this is now a standard thing for entities it would be good for the Add field dialogue to show Entity:Bundle:Field rather than just Entity:Bundle
Comment #51
joachim CreditAttribution: joachim commented@fago: Could you take a look at my comments in 47 please? I've addressed everything in your review except points I'm not clear on.
Comment #52
fagoYep, but the information is still there and defined by core- so we should not add another duplicating key. Making the existing information simpler should be a core issue.
Imho the comment should be at the place of the code that is commented. When reading your patch, I was confuse because it says it is using another handler but goes with the views default handler.
It's fine to just have a comment before the else block.
Yes, in case of enttiy.module bundles yep. We have a key which says 'bundle of' in entity-info, thus profile-type is the 'bundle-of' profile.
Comment #53
joachim CreditAttribution: joachim commented> Yes, in case of enttiy.module bundles yep. We have a key which says 'bundle of' in entity-info, thus profile-type is the 'bundle-of' profile.
But that is not the way round we need here.
Given 'profile2', how do I get 'profile-type'? Or rather, how do I get a nice user-facing string that says 'type'?
What I need is this mapping from entity machine name to human label for the bundle name:
'term' => 'vocabulary'
'node' => 'type',
'profile2' => 'type'
In the meantime, here is a reroll to account for recent changes in the module.
Comment #54
fagoYou'll have to loop over all entity-types to find the right one. Still, it won't work that way for terms <-> vocabularies as those don't use that key. It's an entity.module specific one, but that should be fine as the generated views integration is for entities provided with the entity.module too.
Comment #55
joachim CreditAttribution: joachim commented> You'll have to loop over all entity-types to find the right one.
Isn't that a bit expensive?
Is this something entity API could add to the info it has cached?
Comment #56
fagoNope, that's not a big deal. It's more ugly than expensive. Also, it's done during UI configuration only.
>Is this something entity API could add to the info it has cached?
I don't like duplicating the info in hook-entity-info as it would confuse people which one they have to provide.
Comment #57
joachim CreditAttribution: joachim commentedThe string I get is 'Profile type'. I need to make that plural for the UI -- we seem to be missing 'plural label' on profile module's entity info?
Also, in the case where there is no entity type with a 'bundle of' key, we need a fallback. That should be 'Foobar type' IMO, as 'bundle' is a term that is unseen in the Drupal UI -- it's only in code.
In which case, we need a string that's either:
- Restrict this relationship to one or more @entity_type_label
- Restrict this relationship to one or more @entity types
which is getting really messy.
Comment #58
fagoOh, yes we need to add that. I'd default to just appending a 's'.
If we don't have that, we don't know the database table, do we? I guess we should restrict the handler only to entity types that have that relation/key.
Comment #59
joachim CreditAttribution: joachim commented> Oh, yes we need to add that. I'd default to just appending a 's'.
That's not going to allow translations...
Comment #60
joachim CreditAttribution: joachim commentedI think this will work.
I'll file a patch to add the missing plural label to profile 2, but that won't hold this up as it has a fallback to use 'type'.
Comment #61
fagoThanks, I took a stab on that and re-worked it.
* Restricted it to 'bundle of' relations only. Others might won't work correctly anyway as the bundle-key might not have a respective query column, as for term-vocabs. We want it for 'bundle of' relations, let's do it for them.
* Use 'bundle types' as views settings key and simplified the form generation code.
* Simplified class-detection logic.
* Renamed handler and file to fit the "entity_views" namespace. we'll fix the other views integration too.
Patch works for me. -> attached.
Comment #62
joachim CreditAttribution: joachim commentedYou're the maintainer so it's down to how you find code easier to understand, but I can't follow complex if statements like this one at all, not even when I read the comments.
Also I don't understand the return inside the foreach loop.
You're the maintainer so it's down to how you find code easier to read. But even reading the comment, this sort of complex if statement is greek to me :(
Translators will really not like this.
This really will have translators up in arms.
Comment #63
fagoYep, it's just the default value in case nothing else is provided. If modules provide the plural label everything is fine. We could just show the single label in that case too though. What do you think is the better option?
What's wrong with the return in the foreach loop? It's like break, but just returning immediately.
@if: hm, the comment should explain it. a) we are looking for bundle of == $entity type and b) it may not equal the left-type: "Exception: If joined from the bundle entity we do not need to filter by bundle entity any more"
Maybe you could suggest an improved if statement? Or we just split it up in two nested ifs with two separate comments?
Comment #64
joachim CreditAttribution: joachim commented> What's wrong with the return in the foreach loop? It's like break, but just returning immediately.
Yeah but for the first thing that's found in entity_get_info(). Won't that always be 'comment'?
Comment #65
fago>Yeah but for the first thing that's found in entity_get_info(). Won't that always be 'comment'?
Nope - it's looking for the entity which is the bundle of the passed entity.
Is it clearer that way?
Comment #66
fagoincluding the include...
Comment #67
fagoI hope so - if not let's fix it in a follow-up. Committed.
Comment #68
joachim CreditAttribution: joachim commented@Fago: I think it's down to personal preference. You have a code style which I tend to find fairly dense, with complex expressions and statements. I prefer to lay things out in smaller chunks. You're the maintainer here, it's your choice :)
Comment #69
mh86 CreditAttribution: mh86 commentedThe relationship handler doesn't work if no bundle type is selected (then '0' is used as bundle type). Furthermore, 'type' is used as field for the bundle key, which definitely isn't true for all entity types.
Attached patch fixes both issues.
Comment #70
fagothanks, committed.
Comment #71
ltiong CreditAttribution: ltiong commentedStill unable to solve the issue in the original post: getting duplicate Users in View when using Profile2.
I've just done a clean install with (modules available as of 11/11/2011):
drupal-7.9
ctools-7.x-1.0-rc1
entity-7.x-1.0-rc1
profile2-7.x-1.1
views-7.x-3.0-rc1
1. clean install of D7 & modules;
2. created (2) Profile2 types: Main & Education;
3. created Fields for Profile2 types;
4. created (2) Users and added Profile2 data;
5. created View (Show:User) and added User:Profile as relationship (checked boxes corresponding w/ Profile2 types);
6. i get duplicate user entries -- one corresponding to each Profile2 type.
What am I doing wrong?
Comment #72
ltiong CreditAttribution: ltiong commentedNvm..got it working. While creating the View (step 5 above):
5.1 create View (Show:User)
5.2 add relationship, (User:Profile); give the Identifier a unique name ie 'MainProfile'; select a single checkbox for 'Profile type', in my case 'Main profile';
5.3 add another relationship, (User:Profile); give the Identifier a unique name ie 'EducationProfile'; select the other checkbox for 'Profile type', in my case 'Education profile';
5.4 add Fields to view; select Profile2 field items; use Relationship dropdown in 'Configure field' to associate w/ correct relationship;
Comment #73
joachim CreditAttribution: joachim commentedBingo -- you need one relationship per profile type you want in the view :)
Might be a good idea to add this to a docs section on using Views with Profile2?
Comment #75
sreekanth1201 CreditAttribution: sreekanth1201 commentedHi am adding a module entity relationship..am getting an error like below
Describe arbitrary relationships between entities
Required by: Entity Relationships UI (disabled), Entity Relationships Views (disabled)
even i enabled them.I want to giv a relation between the content types.can any one suggest a good tutorial using this module..
Thanks
Comment #76
crifi CreditAttribution: crifi commentedPlease do not hijack closed issues. You can open a new support issue instead.
Comment #77
rhlb91 CreditAttribution: rhlb91 commentedthank u guys ,it really worked for me what i want ...
thanks a lot
Comment #78
kristiaanvandeneyndeThe latest commit in this issue incorrectly uses "bundle keys" instead of "entity keys".
I've attached a patch that fixes this.
Long version:
So for instance for the Group project, a Group entity references its Group Type through the 'type' property. A Group Type, however, stores its machine name in its 'name' property. So for a Group entity, the relevant entity info would look like this:
Seeing as a Group entity does not have a 'name' property, the handler created in this issue throws an error until fixed with the attached patch.
Comment #79
joachim CreditAttribution: joachim commentedFor an issue that's been closed for this long, it's really better to file a new issue...
(Good catch though!)
Comment #80
klausiIndeed a good catch. You will only encounter this with entity types that use a different name for the type on the type object. For example node and profile2 use "type" on the entity and on the entity type class, so they are not affected. Message and I assume OG use "type" on the entity and "name" on the entity type, and that's where it breaks.
Example symptom in message module: #2275091: Unknown column 'message_users.name'.
So this looks RTBC to me.
Comment #81
kristiaanvandeneyndeThe new issue for this one is here: #2309697: Fix variable mistake in entity_views_handler_relationship_by_bundle
Forgot to mark this one as "Closed (fixed)" again (added a child issue).
Comment #82
nehapandya55 CreditAttribution: nehapandya55 commentedThanks ltiong #72 worked for me.