How to Write Sub Query in With()? - laravel

I have to get specific data like "roles" table have filed status and i need status = 1 that all data get from the role table
$result = User::select()
->with('roles')
->where('email', $email)
->get();
return $result;

Following the answers to this question: Laravel - Eloquent "Has", "With", "WhereHas" - What do they mean?
If I understood correctly how your data model is structured:
User has many Roles
Role has a property status
Want to filter by status = 1
$users = User::whereHas('roles', function($q){
$q->where('status', '1');
})
->where('email', $email)
->get();
EDIT: I am not happy with the answer above because in that case as far as I understood, the Users returned do not have the list of roles already loaded, so I checked the documentation (https://laravel.com/docs/5.8/eloquent-relationships) and given what I found, the following code should do what you ask:
$users = User::with(['roles' => function ($query) {
$query->where('status', '1');
}])
->where('email', $email)
->get();
I never used eloquent nor laravel and I am not a php developer, so I could not try this snippet, please if it is not correct let me know.

You can write subQuery like
$result = User::select()
->with(['roles' => function($q){
$q->where('status', 1);
}])
->where('email', $email)
->get();
return $result;

Related

How to get flat array of eager loading in laravel 5.5?

this my eloquent query:
$data = Disciplines::where('type', '<>', 'Initiator')
->with(['discipline_boxes.assign.box' => function($query) {
$query->select('id');
}])
->get();
return $data;
i want return only array of id's of box relation
e.g:[2,3,4,5]
Solved!!
this worked for me!
$disciplines = new Disciplines();
$results = $disciplines->getAllBox_ID()->toArray();
dd(array_flatten(array_pluck($results,'discipline_boxes.*.assign.box.id')));
Potentially if you have the inverse for this chain of relationships you could get this information from the Box end (making name assumptions here):
Box::whereHas('assign.discipline_box.discipline', function ($q) {
$q->where('type', '<>', 'Initiator');
})->pluck('id');

Laravel eloquent relation search using child table record

Problem :
I want only that records where relational records [ user ] not null.
In my case I want only first record. where user is not null
Result:
User Table
id
name
email
Project Tabel
id
title
user_id [foreign key]
My code is like this
$projects = App\Project::with(['user' => function ($user) {
$user->where('name', '=', 'Ketan');
}])
->get();
foreach ($projects as $project) {
echo $project->title.' - '.$project;
}
My result is like this :
The below code is working
$projects = App\Project::whereHas('user', function ($user) {
$user->where('name', '=', 'Ketan');
}])->get();
Change 'with' to 'whereHas' and note that whereHas doesn't accept the array as the param
For reference Laracasts Link
I got solution of my question
$projects = App\Project::whereHas(['user' => function ($user) { <--Change Here
$user->where('name', '=', 'Ketan');
}])
->get();
Only Change 'with' to 'whereHas'
By this solution, I have got only those Project records in which user ( relational record ) is not null.
You can try:
$projects = App\Project::with(['user' => function ($user) {
$user->where('name', '=', 'Ketan');
}])
->get();
foreach ($projects as $project) {
if($project->user != null){
echo $project->title.' - '.$project;
}
}

Eloquent User Where Clause with Entrust Library

I'm trying to select all users for a company. But only users who has "admin" role status (Entrust, etc.).
User::where('company_id', Auth::user()->company_id)->hasRole('admin')->get();
The above is throwing an error. Left a bit lost on how to run such a query. Where am I going wrong with this? Very little documentation on Entrust.
You can use plain Eloquent for this. The whereHas method would generate one query:
$users = User::where('company_id', Auth::user()->company_id)
->whereHas('roles', function($query) {
$query->where('name', 'admin');
})->get();
Or, you can just get the roles and then get all of that role's users. This would generate two queries, but ultimately achieve the same thing.
$users = Role::where('name', 'admin')
->first()
->users()
->where('company_id', Auth::user()->company_id)
->get();
Think you need to get all the users having the company_id first
$users = User::where('company_id', Auth::user()->company_id)->get();
Then loop through $users and check hasRole()
foreach ($users as $user) {
if($user->hasRole('admin')){
//user is admin
}
}
UPDATE
This might be a dirty solution but you can try to do a manual query
$admin = DB::table('role_user')
->join('users', 'users.id', '=', 'role_user.user_id')
->join('roles', 'roles.id', '=', 'role_user.role_id')
->where('roles.name', 'admin')->get();

Excluding pivot rows in Eloquent ORM query

(laravel 4.2)
There are four tables involved; users, posts, flags, and post_flags.
I want to retrieve every post a certain user has, and retrieve the flags set for the post, but only the flags that are set by the user in question.
For example: A post can have flags: 1,2,2,3 where flag 2 is set twice. Once by User A, once by User B. I don't want to see the flags that User B has set.
The Eloquent query in my controller:
$posts = Post::whereHas('companies', function($q) use($company_id) {
$q->where('id', '=', $company_id);
})->with('flags')->get();
The Relation in my Post model:
public function flags() {
return $this->belongsToMany('PostFlag', 'post_postflags', 'post_id', 'flag_id')
->withTimestamps()->withPivot('owner');
}
How would I achieve this using Eloquent ORM?
UPDATE
My final query, thanks to andrewtweber:
Final query
$posts = Post::whereHas('users', function($q) use($id) {
$q->where('id', '=', $id);
})->get()->load([
'flags' => function($query) use($id) {
$query->where('owner', '=', $id)->orWhere('owner', '=', 'SYSTEM');
}
]);
Use wherePivot
http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Relations/MorphToMany.html
$flags = $post->flags()
->wherePivot('user_id', '=', $user_id)
->get();
Or with eager loading
$posts->load([
'flags' => function ($query) use($user_id) {
$query->wherePivot('user_id', '=', $user_id);
}
]);

Laravel 4 Eager Loading constraints

I want to get all Items (topics) WITH their comments, if comments user_id = $id. I try something like this, but it isn't working. So if Item hasn't got any comment with user_id = $id, then I don't need this Item.
In DiscussionsItem model I have methode:
public function discussionsComments() {
return $this->hasMany('DiscussionsComment', 'discussionsitem_id');
}
My query in controller is like this:
$items = DiscussionsItem::whereBrandId($brand_id)
->whereBrandCountryId($country_id)
->with(['discussionsComments' => function($query) use ($id) {
$query->where('user_id', '=', $id);
}])
->whereHas('discussionsComments', function($query) use ($id) {
$query->where('user_id', '=', $id);
})
->with(['views' => function($query) use ($id) {
$query->where('user_id', $id)->count();
}])
->orderBy('created_at', 'DESC')->get();
My problem is that I get items with comments, where comments user_id != $id.
P.S. I need to take 5 comments, but I cant imagine how to do that, because ->take(5) in my eager load is not working.
You can do a custom scope, or just limit the amount returned by your relation:
public function discussionsComments() {
return $this->hasMany('DiscussionsComment', 'discussionsitem_id')
->latest()
->take(5);
}

Resources