How to do laravel eager loading with multiple constraints? - laravel

$institutes = Institute::with(['address' => function($query){
$query->whereCityId(Input::get('city_id'));
$query->whereIn('area_id',Input::get('area_id'));
}])->get();
Invalid argument supplied for foreach()

The problem could be here
$query->whereIn('area_id',Input::get('area_id'));
Try to ensure that Input::get('area_id') actually returns an array:
$area = Input::get('area_id') ?: [];
$query->whereIn('area_id',is_string($area) ? json_decode($area, true) : $area);

is whereCityId the scope of the model? Documentation has examples with scopes chained with models only.
Try replacing the scope with column name and try. ex replaced with city_id
$institutes = Institute::with(['address' => function($query){
$query->where('city_id',Input::get('city_id'));
$query->whereIn('area_id',Input::get('area_id'));
}])->get();

It does work but it returns
address: null
wherever the condition matches. But it returns all institutes. Either we can use filter on the collection or whereHas
$institutes = Institute::whereHas('address', function ($query) use ($city_id) {
$query->whereCityId($city_id);
})->get();
or
$institutes = Institute::with(['address' => function ($query) use ($city_id) {
$query->whereCityId($city_id);
}])->get()->filter(function ($institute){
return $institute->address != null;
});

Related

how to use whereHas in laravel

I am new to laravel,
I need to create a query for the db,
$query = Deal::query();
I want to use the wherehas operator.
this is my code that is worked.
else if ($group_by == 'precedence') {
if($get_deals_for == 'noprecedence'){
$get_deals_for = 0;
}
$precedenceStatus = $get_deals_for;
$query-> where('precedence', '=', $precedenceStatus);
// \Log::info('The request precedence: '.$precedenceStatus);
}
I want to add this code also to the query
if($person) {
$query->whereHas('personnel', function ($subQuery) use ($person) {
$subQuery->where('id', '=', $person);
});
}
So I need to change the first code?
how I can convert the first code to wherehas?
the first code is from table called deal, the second section is from realtionship called personnel.
the second section worked in other places in the code, I just need to fix the first section and not understand what to write in the use
I try this and get error on the last }
else if ($group_by == 'precedence') {
if($get_deals_for == 'noprecedence'){
$get_deals_for = 0;
}
$precedenceStatus = $get_deals_for;
$query-> where('precedence', '=', $precedenceStatus)
-> when ($person, function($query) use($person) {
$query->whereHas('personnel', function ($query) use ($person) {
$query->where('id', '=', $person);
});
})
}
There is a method you can use called when(, so that you can have cleaner code. The first parameter if true will execute your conditional statement.
https://laravel.com/docs/9.x/queries#conditional-clauses
$result = $query
->where('precedence', '=', $precedenceStatus)
->when($person, function ($query) use ($person) {
$query->whereHas('personnel', fn ($q) => $q->where('id', '=', $person));
})
->get();
You should also be able to clean up your precedence code prior to that using when( to make the entire thing a bit cleaner.
Querying to DB is so easy in laravel you just need to what you want what query you want execute after that you just have to replace it with laravel helpers.Or you can write the raw query if you cant understand which function to use.
using,DB::raw('write your sql query').
Now Most of the time whereHad is used to filter the data of the particular model.
Prefer this link,[Laravel official doc for queries][1] like if you have 1 to m relation ship so u can retrive many object from one part or one part from many object.like i want to filter many comments done by a user,then i will right like this.
$comments = Comment::whereHas('user', function (Builder $query) {
$query->where('content', 'like', 'title%');
})->get();
$comments = Here will be the model which you want to retrive::whereHas('relationship name', function (Builder $query) {
$query->where('content', 'like', 'title%');
})->get();
you can also write whereHas inside whereHas.
[1]: https://laravel.com/docs/9.x/eloquent-relationships#querying-relationship-existence

Eloquent - Get Model with relationship as boolean

My Model has the following one-to-many relationship
class Comment extends Model
{
public function likes(): HasMany
{
return $this->hasMany(CommentLike::class);
}
}
In my Controller I want to get all Comments alongside with a boolean value which indicates if the current user exists in the likes table
$result = Comment::with(['user', 'likes' => function($q) use($user){
$q->where('user_id', $user->id);
}])
->withCount('likes')
->where('post_id', $postId)
->get();
Currently the above query will return the correct result alongside with a row from the likes table if the user is found.
I'm looking for a proper way to return a boolean value to indicate if the user has liked the comment instead.
First, you can find how many likes does user make to the comment, in this way.
$likes = Comment::whereHas(['likes' => function($q) use ($user){
$q->where('user_id', $user->id);
})->where('post_id', $postId)->count();
Then using $likes variable value, you can conditionally create a boolean value and assign to new variable or same $likes variable.
$hasLike = $likes ? true : false;
You can make use of withExists() method. It's not one of the best documented ones, but I think it's quite simple.
In your example:
$result = Comment::with(['user', 'likes' => function($q) use($user){
$q->where('user_id', $user->id);
}])
->withCount('likes')
->where('post_id', $postId)
->get();
Consider changing it to:
$result = Comment::with(['user', 'likes'])
->withCount('likes')
->withExists(['likes' => function ($query) use ($user) {
$query->where('user_id', $user->id);
}])
->where('post_id', $postId)
->get();
Result model will contain additional bool property likes_exists where true means that $user liked the comment and false means that they didn't do it.
Here is how I achieved this
in my model.php file
public function likedByCurrentUser(){
return $this->hasOne(Like::class, "tweet_id", "id")
->where("user_id", auth()->user()->id);
}
likedByCurrentUser method will either return null if no rows match else it will return an eloquent object. So in the controller method we can do something like below to get a boolean.
In the controller method by using withExists
$tweets = TweetModel::with(["user", "likes", "comments.user"])
->withExists([
"likedByCurrentUser as liked_by_current_user" => function($result){
return $result === null;
}
])
->orderBy("updated_at", "desc")
->get();
return response()->json([
"tweets" => $tweets
]);

Laravel OrWhere having two conditions is not so obvious

Why in Eloquent a simple query as this one is not working?
$matches = DB::table("matches")
->where(["team_a"=> $request->tid, "match_tipo"=>3])
->orWhere(["team_a"=> $request->tid, "match_tipo"=>3])
->first();
According to with other examples here on Stackoverflow, I should use a query in Where like:
$matches = DB::table("matches")
->where(["match_tipo"=>3])
->where(function($query, $request) {
$query->where('team_h',$request->tid)
->orWhere('team_a',$request->tid);
})
->first();
But I should pass a second parameter ($request).
How is the simplest way to do this query?
You can make this as like this.
->where(["match_tipo"=>3]) this will be ->where("match_tipo",3) and use($tid) after query.
$tid = $request->tid;
$matches = DB::table("matches")
->where("match_tipo",3)
->where(function($query) use($tid) {
$query->where('team_h',$tid)
->orWhere('team_a',$tid);
})
->get();
while using the Callback or Closure as the where function Parameter you will only the one argument which is Current Object
Methods Can used to Pass the $request
Method One
$matches = DB::table("matches")
->where(["match_tipo"=>3])
->where(function($query) use ($request) {
$query->where('team_h',$request->tid)
->orWhere('team_a',$request->tid);
})
->first();
Method Two
$matches = DB::table("matches")
->where('match_tipo','=',3)
->when($request->tid,function($query) use ($request) {
return $query->where('team_h',$request->tid)
->orWhere('team_a',$request->tid);
})
->first();
Try this query :
$matches = DB::table("matches")
->where('match_tipo',3)
->whereRaw('team_a = "'.$request->tid.'" OR team_h = "'.$request->tid.'"')
->first();

DB::raw convert to query builder

Can you help me to convert the Raw part of my query to use query builder?
I am stuck at joining it all together:
$profile = UserProfiles::select('id')->where('alias', $profileAlias)->first();
$dbRawMessagesCount = '
(SELECT COUNT(pm.id)
FROM profile_messages pm
WHERE pm.to_profile_id='.$profile->id.'
AND pm.from_profile_id=profile_friend.id
AND pm.is_read=0) AS messages_count
';
$friends = ProfileFriend::select('profile_friend.*', DB::raw($dbRawMessagesCount))
->with('friendProfile')
->whereHas('ownerProfile', function ($query) use ($profile) {
return $query->where('id', $profile->id);
})
->orderBy('messages_count')
->paginate();
You can rewrite this into one query if ProfileFriend has a relation already set up to ProfileMessages using withCount() in the query.
$friends = ProfileFriend::with('friendProfile')
->withCount(['profileMessages' => function($q) use($profile){
$q->where('to_profile_id', $profile->id)->where('is_read', 0);
// No longer need 'from_profile_id' as it is already querying the relationship
}])
->whereHas('ownerProfile', function ($query) use ($profile) {
return $query->where('id', $profile->id);
})
->paginate();
Now if you dd($friends->first()) you will notice it has a field called profileMessages_count that gives you a count of what I'm assuming is unread messages.

How to use count in Query builder Laravel5.6

This is my query builder. But an error is shown
ERROR => count(): Parameter must be an array or an object that implements
Countable
Route::get('project', function () {
$project = DB::table('pams_project')
->join('pams_developer', 'pams_project.dev_id', '=', 'pams_developer.id')
->select(array('pams_developer.developer_name',DB::raw(count('pams_project'.'dev_id'))))
->get();
return view('projectByDeveloper', ['project' => $project]);
});
can anyone figure out my problems ?
use DB::raw("count(pams_project.dev_id) as count")
$project = DB::table('pams_project')
->join('pams_developer', 'pams_project.dev_id', '=', 'pams_developer.id')
->select(array('pams_developer.developer_name',DB::raw("count(pams_project.dev_id) as count")))
->get();
But also make sure to use GroupBy() with this.
If you want to get the count of collection u can simply use $project->count()
Hope this helps

Resources