Filter users with many roles Laravel - php

I have 3 tables: User, Role and the pivot table RoleUser with role_id and user_id.
For the relations in my models i did that :
Role Model :
public function users() {
return $this->belongsToMany('App\Models\User')->using(RoleUser::class);
}
User Model:
public function roles() {
return $this->hasMany('App\Models\Role')->using(RoleUser::class);
}
I did that for filter by one role and it works well :
$roles = Role::find($request->get('role_id'))->first();
return $roles->users;
But now i need to filter my users by many roles.
I ll send an array from my front-end with id's of the roles.
Actually i'm able to get the roles like below
$roles = Role::whereIn('id', $request->get('role_id'))->get();
$roles = [{"id":2,"name":"Admin","description":"blabla","created_at":"2018-12-04 09:48:56","updated_at":"2021-04-23 14:53:15"},{"id":3,"name":"developper","description":"blabla","created_at":"2018-12-04 09:51:31","updated_at":"2021-04-23 14:53:15"}]
But i dont know how can i get the users with this roles.

You need to go through the collection and get each role's users and return them in one array as shown below:
$roles = Role::whereIn('id', $request->get('role_id'))->get();
return $roles->map->users->flatten();
Or you do it the other way round:
return User::whereHas('roles', function($q) use($request) {
$q->whereIn('id', $request->get('role_id'));
})->get();

Related

Null is given when trying to find data from pivot table

I have a Many To Many relationship between User & Wallet Models:
Wallet.php:
public function users()
{
return $this->belongsToMany(User::class,'user_wallet','wallet_id','user_id')->withPivot('balance');
}
User.php:
public function wallets()
{
return $this->belongsToMany(Wallet::class,'user_wallet','user_id','wallet_id')->withPivot('balance');
}
And the pivot table user_wallet goes like this:
Then at the Controller, I need to access the balance field:
public function chargeWallet(Request $request, $wallet, $user)
{
// $wallet is wallet_id (2) & $user is user_id (373)
$bal = Wallet::with("users")
->whereHas('users', function ($query) use ($user) {
$query->where('id',$user);
})->where('id', $wallet)->first();
dd($bal->balance);
}
But now I get null as the result of dd($bal->balance) !!
So what is wrong here? How can I properly get the balance ?
Since it is a Many to Many relationships, you have Users attached to many Wallets, and Wallets attach to many Users. For each relation between a single Wallet and a single User: you have a pivot value (pivot relation). From your query, you'll retrieve Wallet with Users, each user's having the pivot relation value attached. So to retrieve the pivot table data (for each relation) you have to use a loop (added a with callback to make sure that only Users with matching user_id are eager loaded with the Wallets):
$bal = Wallet::with(["users"=>function ($query) use ($user) {
$query->where('user_id',$user);
}])
->whereHas('users', function ($query) use ($user) {
$query->where('user_id',$user);
})->find($wallet);
To avoid repeating same callback (where user_id =) you can assign it to variable:
$callback = function ($query) use ($user) {
$query->where('user_id',$user);
};
then use it in your query:
$bal = Wallet::with(['users' => $callback])
->whereHas('users', $callback)->find($wallet);
and then use a foreach loop:
foreach ($bal->users as $value){
dd($value->pivot->balance);
}
or
if you only want to return the pivot value for the first User of the first Wallet of your query, then:
$user = $bal->users->first();
dd($user->pivot->balance);

Laravel eloquent pagination call in relational database

I have an user. User create many ads.I want to see users details with ads where ads shown by paginate. For this, i make two model(User & Ads)
public function user(){
return $this->hasOne(User::class, 'id', 'user_id');
}
public function ads(){
return $this->hasMany(Ads::class, 'user_id', 'id');
}
In controller i call like this:
$users = Ads::with(['user'=> function ($q) use ($id){
$q->where('id',$id);
}])->paginate(2);
But here user's details are shown when forelse loop are called. But i don't want this.
So, How can i get user's details with ads's pagination?
I think you're overcomplicating.
You has two models.
In User, you can put this relationship:
public function ads(){
return $this->hasMany(App\Ad, 'user_id', 'id');
}
In Ads model, you put this relationship:
public function user(){
return $this->belongsTo(App\User, 'id', 'user_id');
}
In your controller, you simple call like this:
//If you want a list of User's Ads
$user = User::find(1);
$userAds = $user->ads()->paginate(2); //you paginate because can be many
//If you want the details from a user who made the Ad #1
$ad = Ad::find(1);
$user = $ad->user; //Don't need paginate because is only one.

Laravel querying multiple related models

For example: I have these models in my application.
User, Profile, Interest.
I linked the users table with the profiles table by adding the user_id column in the profiles table. And I linked profiles and interests by using a pivot table (interest_profile), Which is (as obvious) will have two columns (profile_id, interest_id).
However, I want to query the users who are associated with a profile, too see who is associated with a particular interest, In other words: "select all users who are having (in their profiles) that particular interest".
I know that I can do this with raw SQL by joining the four tables and then use (where clause).. But I want to do it the Laravel way.
Thanks in advance.
First make sure you have your relationships setup correctly on your models like:
class User extends Model
{
public function profile()
{
return $this->hasOne(Profile::class);
}
}
class Profile extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
public function interests()
{
return $this->belongsToMany(Interest::class, 'interest_profile');
}
}
class Interest extends Model
{
public function profiles()
{
return $this->belongsToMany(Profile::class, 'interest_profile');
}
}
Then you can use whereHas() to constrain a query by a related model and dot notation for nested relations. So your query would be:
User::whereHas('profile.interests', function($query) use ($interestName) {
return $query->where('name', $interestName);
})->get();
That would just return a collection of users. If you wanted to return their profiles and interests as well you would use with():
User::whereHas('profile.interests', function($query) use ($interestName) {
return $query->where('name', $interestName);
})
->with('profile.interests')
->get();
Assuming the User model has a relationship profile and the Profile model has a relationship interests, you can do this.
$interest_id = 1;
$users = User::whereHas('profile', function ($query) use ($interest_id) {
$query->whereHas('interests', function ($query) use ($interest_id) {
$query->where('id', $interest_id);
});
})->get();

How to get all posts from the User's subscriptions

In my application, I have setup a User model that can have subscribers and subscriptions through a pivot table called subscriptions.
public function subscribers()
{
return $this->belongsToMany('Forum\User', 'subscriptions', 'subscription_id', 'subscriber_id');
}
public function subscriptions()
{
return $this->belongsToMany('Forum\User', 'subscriptions', 'subscriber_id', 'subscription_id');
}
My question is, what relationship should I use to get a list of paginated Post models (belong to a User) from the User's subscriptions?
You can use the whereHas method to filter based on relationships. Assuming your Post model has a user relationship defined, your code would look something like:
// target user
$user = \App\User::first();
$userId = $user->id;
// get all of the posts that belong to users that have your target user as a subscriber
\App\Post::whereHas('user.subscribers', function ($query) use ($userId) {
return $query->where('id', $userId);
})->paginate(10);
You can read more about querying relationship existence in the documentation.
You can do something like this
\App\Post::with(['subscriptions' => function ($query) {
$query->where('date', 'like', '%date%');
}])->paginate(15);
Or without any conditions
\App\Post::with('subscriptions')->paginate(15);

Displaying posts of users the user follows through Laravel relationships

I would like to display the posts of everyone the current user follows, ordered by date desc.
I have a many to many relationship supplying all the people the user is following.
$users = User::find(Auth::user()->id)->follow()->get();
I have a one to many relationship displaying the posts for any user.
$updates = App\User::find(?????)->updates()->orderBy('created_at', 'desc')->get();
The question mark's shows where the followers ID's need to be placed.
I can put the above query inside the for each loop but that obviously works its way through each follower rather than all posts in date order.
I suspect I may need to set a new relationship and work from the beginning. Can anyone advise.
User Model
public function updates()
{
return $this->hasMany('App\update');
}
/**
* User following relationship
*/
// Get all users we are following
public function follow()
{
return $this->belongsToMany('App\User', 'user_follows', 'user_id', 'follow_id')->withTimestamps()->withPivot('id');;;
}
// This function allows us to get a list of users following us
public function followers()
{
return $this->belongsToMany('App\User', 'user_follows', 'follow_id', 'user_id')->withTimestamps();;
}
}
Update Model
public function user_update()
{
return $this->belongsTo('App\User');
}
Thank you.
Since you want the posts, it is probably going to be easier starting a query on the Post model, and then filter the posts based on their relationships.
Assuming your Post model has an author relationship to the User that created the post, and the User has a follower relationship to all the Users that are following it, you could do:
$userId = Auth::user()->id;
$posts = \App\Post::whereHas('author.follower', function ($q) use ($userId) {
return $q->where('id', $userId);
})
->latest() // built in helper method for orderBy('created_at', 'desc')
->get();
Now, $posts will be a collection of your Post models that were authored by a user that is being followed by your authenticated user.

Categories