Laravel get all related models for multiple models - laravel

I have a users table and a groups table.
I have set up a many to many users/groups relations.
When I run
$users = User::where("id",'=',6)->first()->groups;
,I get the right group.
But I will have cases where my queries will take in an array of users.
How do I get all the groups of all those users using laravel relationships ?

eMAD's suggestion does not work because Laravel only allows relationship functions to be execute on objects and not array of objects. What you want harvey is a concept called eager loading.
$users = User::whereIn('id', [6, 7, 8])->with('groups')->get();
By using this code, you will be able to access $user->groups->someInfo in your code. Happy coding

Related

How to Get Order Details per a single User in Laravel 7

I am making a multi-vendor ecommerce website using Laravel 7. I am trying to make an Order History page where in a single can user can view only his/her own orders. I am having a problem building the query on my OrderHistoryController. These are the codes on my controller:
$users = User::get();
$orders = Order::find($users);
return view('order-history', compact('orders'));
And I'm trying to loop $orders on my blade file. I have:
#foreach ($orders as $order)
<div>{{ $order->id}}</div>
<div>{{ $order->grand_total}}</div>
#endforeach
I am trying to pass the order id and order grand total to my view. I don't get any error however it shows a different order details from a different customer. How do I do this?
You should use MySQL (or any other database you are using) table relationships and foreign keys.
So, your orders table, should have columns id, user_id, date, and so on. The important thing is user_id column. You want to make that column a foreign key. That basically means that user_id will hold an id value from another table, in this case user. See how to make foreign key columns in laravel migrations here.
Next up is to use Laravel's built in model relationships. You can read more about them here. Basically, in your orders model you want to have a function user which returns $this->belongsTo(App\Models\User::class) and in your user model you want to have a function orders which returns $this->hasMany(App\Models\Order::class) (or whatever the namespace is for both of them).
That way, you can call $user->orders and get a collection of Order models which will contain only the orders of that particular user.
Definitely read the documentation carefully and learn basic concepts of the framework first and how relational databases function!
You can get a lot of this information just by googling it or reading the documentation of Laravel or any other framework you plan on using! Good luck learning :)

How do the "has" and "whereHas" methods work in Eloquent?

I have a relationship defined between users and permisson, a user can have many permissions.
When I use "with" I get the data normally.
$user->with('permisson')->get();
I get the user with their permissions.
When I use "has" it only returns the user.
$user->has('permission')->get();
For what I've read, I should get the permissons if the user contains at least one permission.
I am using Postgres driver.
with is used for eager loading a relationship. You'd use it to fetch all of the specified relationships for each model (individually, or in a collection).
has is for using the relationship as a constraint or filter. As you said, using something like has('permission') will add a constraint to the query that says "only get Users that have at least one permission". This does not automatically load the relations like with(), it only creates the constraint.
You can combine the two if you want to take advantage of both the constraint and eager loading the results.
User::has('permission')->with('permission')->get();
Seems a bit redundant, I know.
From laravel docs:
If you wish to limit your results based on the existence of a relationship, you should use the has method. For example, if you want to retrieve all blog posts taht have at least one comment, yo may pass the name of the relationship to the has and orHas methods:
$posts = Post::has('comments')->get();
So, when you use the has method, it will not return the relationship, but just the post models which has at least one comment.
The whereHas and orWhereHas methods allows you to add customized constraints to a relationship constraint, such as checking the content of a comment (using the laravel example):
$posts = App\Post::whereHas('comments', function (Builder $query) {
$query->where('content', 'like', 'foo%');
})->get();
When you use the with method, you are loading the realtionship with the model:
$user->with('permission')->get()
This code will load the user and the permission relationship, while this one
$user->has('permission')->get();
will load the user who has some permission.
Hope it helps.

Laravel Many to Many (3 and 3+ Models) Design Questions

I have got three models
Contacts Model
Contact Roles Model
Project Model
Set up;
contacts can belong to multiple projects. (Many to Many)
each project has its own contact roles created by user. (One to Many - Roles are specific to projects)
Within selected project, a contact can be assigned to multiple roles (Many to many)
Tricky part is I have categories for roles model, when user is creating the role, they select a category for that role from a dropdown(from a db, total of 7 predefined categories).
Then what I try to do and have issue with understanding;
1.What is the best way to display all contacts with given roles on that specific project?
I can easily get $project->contacts() //this gives me all contacts within that projectbut I need to one step further, where I can get contacts with their roles.
2.Furthermore, how would I display all contacts that are part of that selected category for that project?
3.Should i be using a different connection between my models other than many to many, like has many through ?
Assumption - with
display
you actually mean retrieve with eloquent.
Word of advice - READ THE DOCS! Laravel has great and easy to understand documentation.
https://laravel.com/docs/5.7/eloquent-relationships#eager-loading
1) I can easily get $project->contacts() //this gives me all contacts within that projectbut I need to one step further, where I can get contacts with their roles.
Nested eager loading:
$project = Project::with('contacts.roles')->find($id);
2) Furthermore, how would I display all contacts that are part of that selected category for that project?
Constraining eager loads and querying relationship existance:
$project = Project::with(['contacts', function($q) use ($categoryId) {
$q->with('roles')->whereHas(['category' => function($q2) use ($categoryId) {
$q2->whereId($categoryId);
});
}]);
3.Should i be using a different connection between my models other than many to many, like has many through ?
Structure looks fine to me.

Laravel Eloquent model data from 2 tables

I've just started using Laravel and I'm coming from a different system using an existing database. In this system there are 2 users table, one stock with the CMS and one custom one.
I want to create an Eloquent model which retrieves data from both tables into one model. I know I can use the following to create a relationship.
$this->hasOne('App\SecondUser', 'id', 'id);
But this results in 2 sql queries, and I want to join results from 2 tables before returning the model, in one join statement. How do I do this?
That might be a bit more complicated that you would expect.
First of all you have to use \DB facade to join the two collections(arrays) and then recreate the Eloquent collection from these arrays using Collection's make method.
More info about the Collection class here
An easier way might be to join them using standard laravel relationships and user something like Model::user->with('relation')->get.
But this will still create 2 queries (still relatively fast).

Laravel Sentry limits

Anybody know how to get limited number of sentry users. I have admin panel in my laravel application and I make a user management. For display data (groups table, user table, permission table, ...) I use jqgrid. So if I have half million users I want to get limited list of users with specific data.
For use limitation in Laravel, I use standard function skip and take, but I cannot use these method on Sentry findAllUsers().
What solution is the best in this case?
There are some ways, one of them is to get an empty Sentry user model, which is based on Eloquent:
$model = Sentry::getUserProvider()->getEmptyUser();
And use it as you would with Eloquent:
$all = $model->all();
$paginated = $model->paginate();
$selected = $model->where('age', '<', 21)->get();

Resources