I have Doctrine setup with all my tables in my database, and working properly.
I have those three entities: Users, Groups and News
There is a many-to-many relationship between Users and Groups. (I put my users in groups)
There is also a many-to-many relationship between News and Groups. (I give access to a News item to a few Groups)
Database Schema:
I want to get the News that a given User has access to.
Is there an efficient way to do this in Doctrine?
EDIT: I should add that I already had the solution nailed down with a straight SQL query before I started to use Doctrine, I want to know the Doctrine way to do this.
This thread explain the issues about many to many relationships in doctrine.
many-to-many relationship in doctrine
This blog post explain how to handle such events.
http://melikedev.com/2009/12/09/symfony-w-doctrine-saving-many-to-many-mm-relationships/
Related
Say I have four tables:
users
groups
activities
group_activities
Where a group can have any number of activities and an activity can belong to any number of groups through their intermediate table group_activities, and a user belongs to one group via users.group_id. I want to correctly model a relationship between users and activities so that a user can have any one activity, but only if the group that user belongs to has a relation to that activity.
HasOneThrough doesn't seem to work here, since the group the user is related through has multiple activities. HasManyThrough doesn't work since the user can only have one.
I want to properly model this relationship so that it can be picked up for selection automatically via a Nova relationship field, but I'm struggling to figure out exactly how I would do so. My first thought is a HasOneThrough relation with some set of subqueries, but I can't quite piece together where to start.
How would I do this, or conversely, is it possible via Eloquent's automatic relationship system at all?
To ensure we are on the same idea of your relationships:
The relationship between Groups and Activities is a Many To Many relationship (Many To Many - Larvel Documentation).
The group_activities table is the pivot table.
The relationship between users and groups is a One To Many relationship One To Many - Larvel Documentation and the inverse of it One To Many (Inverse) - Larvel Documentation.
To actually answer your question:
If you want to use a shortcut from users to their activities, the Has Many Through is the correct way. If a group can have arbitrary many activities, and a user belongs to one group, the user will be associated to these arbitrary many activities through the group -hence Has Many Through. Note that this is not really a separate relationship though, it's just a convient shortcut.
If you wan't to associate a user with a single Activity directly, you need to to this via a separate One to Many relationship between Users and Activities.
I'm not entirely sure if I interpret your question correctly, so the following is just an assumption, but do you want to ensure a user can only be associated to an activity thats also associated with the user group? So to restrict possible activites by group? If that is the case, you'd simply need to check if the selected activity is in the activities associated with the users group:
With your relationships set up like this:
class User {
public function activity(){
return $this->belongsTo('App\Activity');
}
public function possibleActivities(){
return $this->hasManyThrough('App\Activity','App\Group');
}
}
you can check and associate activities like this:
if( $user->possibleActivities()->contains( $activity ) ){
$user->activity()->associate($activity);
}
I have users, meetings and comments tables and I want users to be able to post comments on users profile and meetings.
I know how to make one to many relationships for users and comments tables, but I want all comments to be saved in one table and show comments on users profile and meetings.
This is my table structure:
users
id
name
comment_id
meetings
id
name
comments
id
user_id
comment
TL;DR The solution is to use polymorphic relationships which Laravel makes really easy.
IMHO I don't think that a many-to-many relationship will do the job. It would mean that:
a user can post multiple comments. Okay
a comment can belong to multiple user. Weird
a meeting can have multiple comments. Okay
a comment can belong to multiple meetings. Weird
Plus you would likely need two comments tables to achieve that. For instance a comment_user table and a comment_meeting.
The kind of relationship that would fit the most your situation is the polymorphic one. The name can be scary because it comes from ancient greek. But the concept behind the name is very simple. And Laravel makes polymorphic relationships very easy. You will certainly recognize your situation in the example given in the Laravel documentation ;)
While saving comment, also keep a field named model (or anyone you like) to identify users profile and meetings
HTH
Tables:
tbl_user(id, name)
tbl_group(id, name);
tbl_user_group(user_id, group_id);
If there were all three classes generated User,Group,UserGroup. How should i setup the relations in User or Group so that they are mapped through the user_group table?
I'm using Doctrine 1.2
It's up to you to define their associations, purely because only you will know how you want your application to work. Can a user have more than one group? Only one? If a group is deleted, will all associated users be deleted? These are the questions you need to ask yourself.
If you follow the example on Doctrine's documentation for Many-to-Many relationships (which coincidentally covers exactly what you need), you'll get there.
I'm creating a project management system which projects are assigned to users
What's the difference between creating a Model ProjectsUser and defining 2 $belongsTo relationship and defining HABTM relationships in both Project and User models? What would be the most correct way, though? And how do I save the data in the projects_users table?
From my experience, if you want to be able to save or delete rows only from the join table (the one with 2 IDs), then it is much more simple using three models associated through both a hasMany and a belongsTo association.
You can also retrieve data from the join table directly and do the queries you want much more easily
This is what CakePHP documentation says refering to HABTM and saving data:
However, in most cases it’s easier to make a model for the join table and setup hasMany, belongsTo associations as shown in example above instead of using HABTM association.
Here you can find more the full text:
http://book.cakephp.org/2.0/en/models/saving-your-data.html#what-to-do-when-habtm-becomes-complicated
I have used this method for a "reads" table (with post_id and user_id) as well as for subscriptions and similar kind of relationships.
The first way is called "hasAndBelongsToMany" [details here].
The second is called "hasMany through" [details here].
The second link relating to "hasMany through" has details and a lengthy explanation about when and why you would want to use it.
Not sure about the specifics of cakephp, but in general defining the relation model explicitly gives you more control over it, for instance if you wanted to do some validation or add callbacks on creation of this relationship.
Assuming I have three entities: Article, Tag & User. Articles and Tags are many-to-many related.
What I'd like to do is add User information to the many-to-many relationship - so I can tell which user added which tag to an article. Basically, the result in SQL should be a third column 'user_id' in article_tags (the many-to-many relationship table containing article_id and tag_id keys) that I can query for.
Right now I'm only aware of one solution: Creating a fourth entity 'ArticleTags' that has three relationship fields article, tag and user. Showing all tags in an article then becomes...
<?php
foreach($article->getArticleTags() AS $articleTag) {
echo $articleTag->getTag()->getName()
}
...which is much less straight-forward than $article->getTags() already, plus it requires all kinds of repository trickery for querying, sorting and so forth.
Is there a more ideal solution for this kind of thing? I'm using Doctrine 2.1.0-DEV right now. Thanks.
IMO, I think the ArticleTags entity is a good approach.
Alternatively, if the User entity has associations with Articles and Tags, you should be able to map out from the User entity which tags belong to which post for that specific user.