I'm using the Yii framework and have come across an issue whilst building a Friend/Connection style system. I have a standard users table and to store friends I have a friends table with the following layout (the appropriate FKs etc have been set up):
id | userId | friendId | and some other fields...
As the "friend" is mutual - so, if user A is a friend with user B, then user B is a friend with user A - therefore there is only ever one entry per "friendship".
What I'm trying to do is use Yii's relational query to eventually return items which belong to friends. Currently I have the following relation in the User model...
'friends' => array(self::HAS_MANY, 'UserFriend', 'userId'),
However that only returns 'friends' if the user's ID is present in the userId field. If the user's ID is in the friendId field then the "friendship" won't be recognised.
Is there a way to query using "OR" - for example: if user's ID == userId OR user's ID == friendId then return that entry?
In addition, is there a way to get Yii to return the other ID, so if user's ID == userId it will return friendId, else if user's ID == friendId it will return userId?
I'm eventually trying to do something like:
$userModel = User::model()->findByPk(Yii::app()->user->id); // user's model
$userFriends = $userModel->with(items)->friends; // return friends with their items
Hopefully I haven't confused too many! Sorry for the poor explanation
Thanks :)
Follow the instructions here on creating a database command object, and then you can query with an OR condition as follows:
$command->where(array('OR', 'userID = :userID', 'userID = :friendID'), array(':userID' => $userID, ':friendID' => $friendID));
Do you want get all friends of current user of your app?
You can use CDbCriteria and method find(). Something like this:
$criteria = new CDbCriteria;
$criteria->addCondition('id = :userid');
$criteria->addCondition('friendid = :userid', 'OR'); // OR - the operator to join different conditions. Defaults to 'AND'.
$criteria->params = array(':userid' => Yii::app()->user->id);
$userFriends = UserFriend::model()->find($criteria);
But I'm not sure in your User and UserFriend models structure and mutual relations. Have you some relation from UserFriend to User? If so, than you can use something like $userFriends->user0 after code above.
CDbCriteria details
find() method details
Related
I have a 'users' table like bellow. When a new user sign in, he has to use one 'sponsor_id' from previous user. Previous user's 'user_name' being used as 'sponsor_id' for a new user. Now, I want to show some 'sponsor_id' details when a new user signed in like, sponsor_id's first_name, last_name, phone etc. All data are saved in 'users' table. What should be the query,Please anyone help me. I am using Laravel5.4.
I am trying something like-
$sponsor_info = DB::table('users')
->select('first_name','last_name','phone')
->where('user_name', '=', '$sponsor_id')
->first();
I dont know laravel but Im giving the solution plz convert it to laravel.
select m.*,
s.first_name,
s.last_name,
s.phone
from user m
left join user s
on m.sponsorid=s.userid
SELECT
user.id,
user.user_name,
user.sponsor_id,
sponsoredUser.user_name
FROM user
INNER JOIN user AS sponsoredUser ON user.sponsor_id = sponsoredUser.id
WHERE user.id = $id
Here I am using user table 2 times . First is using for that user and the second is using for the getting information of that sponsored user. That's why I given the second user table name an alias name called sponsoredUser .
Hope you will transfer this query into laravel.
Add this function to your user model:
public function sponsor()
{
$this->belongsTo(App\User::class,'sponsor_id','user_name');
}
Now you can make this query:
$users = App\User::with('sponsor')->get();
All users will have a "sponsor" relation loaded.
Foreach ($users as $user){
$user->sponsor->first_name;
// Etc
}
I have 2 tables that i want to join & show the name of user's role. here's the situation
My 2 tables are users_mlh & user_roles_mlh
on the role column of users_mlh table i'm storing the ID of user role, user_roles_mlh contains the name & id of user role. what i want to do is show the name of the user role in my view.
my tables as follows.
i have tried this in my model
$this->db->select('*');
$this->db->from('user_roles_mlh');
$this->db->join('users_mlh', 'users_mlh.role = user_roles_mlh.id');
$this->db->where('users_mlh.role = user_roles_mlh.id');
$query = $this->db->get();
return $query->result_array();
but from above i get something like this
at the moment it lists all user level not the role of each individual user
Case 1 : If you Directly want to Access all data without using where condition
$this->db->select( "*" );
$this->db->from( 'users_mlh' );
$this->db->join('user_roles_mlh', 'user_roles_mlh.id = users_mlh.role');
Case 2: With Where Condition and specific column data
$this->db->select( 'user_roles_mlh.role_type,users_mlh.name' );
$this->db->from( 'users_mlh' );
$this->db->join('user_roles_mlh', 'user_roles_mlh.id = users_mlh.role');
$this->db->where('users_mlh.id =',1);
And finally get the results by
$query = $this->db->get();
return $query->result();
No need to write separate query for getting role name. Join Roles table when you fetching users data..
$this->db->select('users_mlh.*,user_roles_mlh.role_type');
$this->db->from('users_mlh');
$this->db->join('user_roles_mlh', 'user_roles_mlh.id = users_mlh.role');
$query = $this->db->get();
return $query->result_array();
Try this.
If I use your tables, you should have the following request:
SELECT users_mlh.*, JOIN user_roles_mlh.role_type
FROM users_mlh -- list all users
LEFT JOIN user_roles_mlh -- and joind by roles
ON users_mlh.role = user_roles_mlh.id -- condition for joining
With this request, you will have all your users, with the role text associated.
So, if this request works, use the same logic on your ORM
I have two tables in the database, namely "user" and "user_user" which links users to users (many to many)
in user_user there are two columns "user_id_0" and "user_id_1"
I need to get all users where the current logged in user id is equal to either
user_id_0 OR user_id_1.
I can achieve this simply with sql:
select * from user u
inner join user_user uu
on uu. user_id_0 = u.id
or uu.user_id_1 = u.id
[where u.id = 1]
In Yii2 I'm stuck with something like this:
($this would be of type User)
$this->hasMany(User::className(), ['id' => 'user_id_0'])
->viaTable('user_user', ['user_id_0' => 'id'],
function($query) {
$query->orOnCondition(['user_id_1' => 'id']);
});
Now this can't work as hasMany() links to only one foreign key. How do I do something like the SQL above? To join two foreign keys with 'or'.
I this possible or would you suggest a different database design? The goal here is really to enable users have "friends" or "connections" to other users like you would in a social network.
I'm not sure if this works as you expect. I didn't try it out.
IMO the query should look like this (assuming MySQL):
SET #id = 1; // or whatever
SELECT user.*
FROM user
INNER JOIN user_user
ON user.id = user_user.id1 OR user.id = user_user.id2
WHERE user.id != #id AND (user_user.id1 = #id OR user_user.id2 = #id)
GROUP BY user.id;
This could be realized in class User like this:
public function getConnectedPersons() {
return self::find()
->select('user.*')
->innerJoin('user_user', ['or',
'user.id=user_user.user_id_0',
'user.id=user_user.user_id_1'
]
)->where(['and',
['user.id' => $this->id],
['or',
['user_user.user_id_0' => $this->id],
['user_user.user_id_1' => $this->id]
]
]
)->groupBy('user.id');
}
This returns an ActiveQuery object. Append ->all() if you want to get the user array directly.
I hope this works. It is untested. But you may get the idea and give me feedback if anything is wrong.
This might not be the best solution. It doesn't use viaTable() which should also work somehow.
I have Users and Courses.
I have a users table, and a courses table.
I also have a course_memberships table with id |
course_id | user_id
I have the appropriate hasmany relationship
for courses and users to relate to CourseMembership
But I have no idea how to create that relationship using a button on the front end. Something like a public function register() on the Courses controller that would put the Auth User ID in the user_id field, and the course id in the course_id field to form the relationship.
I know it was a wall of text, but I figured a description of the issue may be more helpful than an endless scroll of code.
Can anyone help?
You should create a method to save to the CourseMembership model within the Courses Controller. Something like this would work.
public function register($course_id){
$user_id = $this->Auth->user('id');
$data = array(
course_id => $course_id,
user_id => $user_id;
);
if($this->Courses->CourseMembership->save($data)){
$this->Session->setFlash('Registered');
$this->redirect($this->referer());
}
else{
$this->Session->setFlash('Could not register');
$this->redirect($this->referer());
}
}
This way, when people go to /Courses/register/1, it would register them for the course with the ID of 1.
Then when you do a find on the User, the data would be in $user['CourseMembership']
I'm using Yii framework and have trouble with a query as i'm new to it.
I have two tables in my database:
users:
id, username, password, fullname
friends
id, user_id, friend_id
I declared the relationships and get the user's friends by using:
$userFriends = $user->userfriend();
My problem is that I want to get the list of friends ordered by the "fullname" column in the users table.
How can I achieve that?
Thank you
When declaring your relation, you can specify additional options http://www.yiiframework.com/doc/guide/1.1/en/database.arr#relational-query-options
public function relations()
{
return array(
'friends'=>array(self::MANY_MANY, 'User', 'friends(user_id,friend_id)',
'order'=>'fullname ASC')
);
}