Laravel eloquet check non existing many to many relation - laravel

I'm having trouble to write query in laravel eloquent ORM.
I have a proyect table, where you can assign users, in a many to many relationship
In the view to asign users, I have a selector, but I want to show only the users not already assigned to the proyect and checking also that the user belongs to the company that created the proyect (user.company_id=proyect_id)
In a normal query should me something like this, having $company_id and $proyect_id from the controller.
select * from users u left join proyect_user pu on u.id=pu.user_id and
pu.proyect_id = $proyect_id where u.company_id=$company_i and
proyect_id is null;
The query works, but I would like to use Eloquent. ¿Any idea how to do it?

It depends on how you declared the relationship in the User model. But I would do something like this:
$users = User::whereHas('company', function ($query) use ($companyId) {
$query->where('id', $companyId)
})->whereDoesntHave('proyects', function ($query) use ($proyectId) {
$query->where('id', $proyectId);
})->get();

Related

How to query relational data in laravel using eloquent

I have Project Model each Project has Many Positions from Position Model and each positions has Many Employees in Employee Model
Now I want to query all employees id's of the particular project regardless their position,
How can I achieve this using eloquent?
Roughly you would do something similar to this, where you can use whereHas to create nested queries on relations.
$employeeIdsToFilter = [1,2,3];
$filteredProjects = Project::query()->
whereHas('positions' , function ($query) use ($employeeIdsToFilter) {
$query->whereHas('employees', function($query) use ($employeeIdsToFilter) {
$query->whereIn('id', $employeeIdsToFilter);
});
})->get();
You can use the HasManyThough relation. Here is the Link

Laravel Eloquent get result where relation data is null

I have two Models User and Owner with many to many relationship
I want to fetch only those users who don't have owner
how can I get using eloquent
i tried
$query = User::whereHas('userOwners', function ( $subquery ){
$subquery->whereNull('owner_id');
})->get();
but not working.
Eloquent has a way to query an absent relationships, it should work like this in your case:
$query = User::doesntHave('userOwners')->get();
User::with('userOwners')
->whereHas('userOwners', function ($query) {
$query->wherehas('owner_id');
})
->where('user_status', 1)->get();
use second where if you want to filter on user
use first where if you want to filter on Owner
I think you should just change your query like:
$query = User::whereHas('userOwners')->get();
Hope this work for you!!!

Is there an Eloquent way of doing a leftjoin in Laravel 5.4

Is there a eloquent way to do a left join in Laravel?
We'd like to get all games and fill in the progress for each one if it exists in user_games.
Right now we've written the following solution, however this isn't eloquent at all, which we like it to be.
public function usergames($user_id) {
return DB::table('games')->leftJoin('user_games', function ($join) use ($user_id) {
$join->on('user_games.game_id', '=', 'games.id')->where('user_games.user_id', '=', $user_id); })->get();
}
DB model:
Thanks in advance!
A way to do this without you actually writing a left/inner join is to use the eloquent relationships.
In your case you will have 2 model classes: User and Game
class User extends Model {
public function games() {
return $this->belongsToMany(App\Game::class);
}
}
Now, you can access the user's games like so:
$user = App\User::find($user_id);
$usergames = $user->games; // Illuminate\Support\Collection
If you want to get a list of users with games, then look into eager loading. That would look something like this:
User::with('games')->get();
This way, Eloquent will know to lazy load the relationship meaning it will only run 2 queries. One to grab the users. and one to grab the games associated with the user, and then make them available for you in the 'games' property of the user object.

Where clause inside whereHas being ignored in Eloquent

Im trying to make a query using whereHas with eloquent. The query is like this:
$projects = Project::whereHas('investments', function($q) {
$q->where('status','=','paid');
})
->with('investments')
->get();
Im using Laravel 5.2 using a Postgres driver.
The Project model is:
public function investments()
{
return $this->hasMany('App\Investment');
}
The investments model has:
public function project() {
return $this->belongsTo('App\Project');
}
The projects table has fields id,fields...
The investments table has the fields id,project_id,status,created_at
My issue is that the query runs and returns a collection of the projects which have at least one investment, however the where clause inside the whereHas is ignored, because the resulting collection includes investments with status values different than paid.
Does anyone has any idea of what is going on?
I believe this is what you need
$projects = Project::whereHas('investments', function($q) {
$q->where('status','=','paid');
})->with(['investments' => function($q) {
$q->where('status','=','paid');
}])->get();
whereHas wil check all projects that have paid investments, with will eagerload all those investments.
You're confusing whereHas and with.
The with method will let you load the relationship only if the query returns true.
The whereHas method will let you get only the models which have the relationship which returns true to the query.
So you need to only use with and not mix with with whereHas:
$projects = Project::with(['investments' =>
function($query){ $query->where('status','=','paid'); }])
->get();
Try like this:
$projects = Project::with('investments')->whereHas('investments', function($q) {
$q->where('status','like','paid'); //strings are compared with wildcards.
})
->get();
Change the order. Use with() before the whereHas(). I had a similar problem few weeks ago. Btw, is the only real difference between the problem and the functional example that you made.

Laravel > nested eager load with restriction

Assumed we've got users, friends and restaurants. Don't want to go to deep into the Model and relationship setup.
While me as a user is logged in: How can I get all friends who are "customers" of the restaurant?
I've got this and it's already working:
$friends = array_dot(Auth::user()->friends()->select('users.id')->get());
$customers = Restaurant::with(['users' => function($query) use($friends) {
$query->whereIn('users.id', $friends);
}])->find(restaurant_id);
But is this even possible with a single query?
It sounds like you want to find all of your friends that have a relationship to the restaurant. If so, you're looking for whereHas(). General idea:
$restaurantId = 1;
$user = Auth::user();
$friendCustomers = $user->friends()->whereHas('restaurant', function ($query) use ($restaurantId) {
$query->where('id', $restaurant_id);
})->get();
You can read more about querying relations, and whereHas, here.

Resources