withCount() doesn't include deleted rows? - laravel

How can I make withCount('comments') also include all deleted/trashed rows?
For example, if I have 5 comments, and I delete 1, I still expect withCount('comments') to return 5, but instead it's returning 4.
My full query looks something like this:
$query = Post::withTrashed()
->withCount('comments')
->get();

I think you can try this
$query = Post::withCount('comments')
->withTrashed()
->get();
OR
$query = DB::table('post')
->select('comments', DB::raw('count(*) as comments'))
->get();
Hope this work for you!

Since laravel doesn't propose a way to filter the relation when using withCount, a clean solution would be to declare the relation and add the withTrashd() to it.
In Post.php
public function commentsWithTrashed()
{
return $this->comment()->withTrashed();
}
Now you can use the withCount on it.
$query = Post::withTrashed()
->withCount('commentsWithTrashed')
->get();

You can add this to count
$query = Post::withCount(['comments'=> function ($query) {$query->onlyTrashed();])
->get();
it works properly.

You can use the withTrashed method:
>withTrashed()

Related

Search in last record of relationship - Laravel (Eloquent)

i need to search in last record of an relationship in Laravel 7. Here is my code, hope u understand my question :)
$Collection = ServiceRequest::whereHas('ServiceRequestSignatureFlows', function ($query) use ($ou_id) {
return $query->latest()->where('user_id',666);
})
->orderBy('name', 'ASC')
->get();
a ServiceRequest has many SignatureFlows, but i need only search on last flow inserted. I think that when i make ->latest(), my search could search 666 only in last rows, but doesnt happens.
Thanks
you can create the new relation HasOne and filter by it.
public function ServiceRequestSignatureLastFlow()
{
return $this->hasOne(ServiceRequestSignatureFlows::class)->orderByDesc('id');
}
and than
$collection = ServiceRequest::whereHas('ServiceRequestSignatureLastFlow', function ($query) use ($ou_id) {
$query->where('user_id', $ou_id);
})->orderBy('name', 'ASC')->get();
Remove the return inside the whereHas

Laravel 5.5 can't get selected column data using belongsTo

I have 2 models (User & UsersDetails) in relation with Eloquent Laravel.
Model "User" Realation With 'SelDetails'
public function SelDetails {
return $this->belongsTo('App\UsersDetails', 'users_id');
}
I want to get only two column 'created_by_id', 'created_by_name' from SelDetails
UserController
$users = User::with(['SelDetails' => function($query){
$query->select(['created_by_id', 'created_by_name']);
}])
->where('is_active', '=', 0)
->orderBy('id', 'desc')
->get();
I am getting data from User but getting blank in SelDetails
[relations:protected] => Array
(
[SelDetails] =>
)
Please correct me.
guys thanks for your precious response on this issue. i got the solution via following way.
changes in "User" model Relation With 'SelDetails'
public function SelDetails {
#return $this->belongsTo('App\UsersDetails', 'users_id');// the old one
return $this->hasOne('App\UsersDetails', 'users_id');
}
changes in "UserController"
$users = User::with('SelDetails')->where('is_active', '=', 0)->orderBy('id', 'desc')->get();
that's the changes that I have made and got the result
Thanks
I might be wrong but it might be the array in select, try
$query->select('created_by_id', 'created_by_name');
Have you tried something like
$users = App\Book::with('author:id,name')->get(); from the documentation?
In your case it should looks like:
User::with('SelDetails:created_by_id,created_by_name')
->where('is_active', '=', 0)
->orderBy('id', 'desc')
->get();
with() method can take string (or array filled by strings) eg. relationName:column1,column2.

How to start a query in Laravel with Eloquent?

I'm trying to write the following code:
foreach($relations as $relation){
$query->orWhereHas($relation, function ($query) use ($filter) {
$query->where('name', 'like', '%'.$filter.'%');
});
}
but I don't know how to initialize the $query variable, I'd prefer not to write the first orWhereHas before the foreach starts.
Anyone knows how to achieve this?
Thanks!
Eloquent models has query() method. Then, you can do this
$query = App\User::query();

Laravel Eloquent "WHERE NOT IN"

I'm having trouble to write query in laravel eloquent ORM.
my query is
SELECT book_name,dt_of_pub,pub_lang,no_page,book_price
FROM book_mast
WHERE book_price NOT IN (100,200);
Now I want to convert this query into laravel eloquent.
Query Builder:
DB::table(..)->select(..)->whereNotIn('book_price', [100,200])->get();
Eloquent:
SomeModel::select(..)->whereNotIn('book_price', [100,200])->get();
You can use WhereNotIn in following way also:
ModelName::whereNotIn('book_price', [100,200])->get(['field_name1','field_name2']);
This will return collection of Record with specific fields
I had problems making a sub query until I added the method ->toArray() to the result, I hope it helps more than one since I had a good time looking for the solution.
Example
DB::table('user')
->select('id','name')
->whereNotIn('id', DB::table('curses')->select('id_user')->where('id_user', '=', $id)->get()->toArray())
->get();
Query Builder:
DB::table('book_mast')
->select('book_name','dt_of_pub','pub_lang','no_page','book_price')
->whereNotIn('book_price', [100,200])->get();
Eloquent:
BookMast::select('book_name','dt_of_pub','pub_lang','no_page','book_price')
->whereNotIn('book_price', [100,200])->get();
The dynamic way of implement whereNotIn:
$users = User::where('status',0)->get();
foreach ($users as $user) {
$data[] = $user->id;
}
$available = User::orderBy('name', 'DEC')->whereNotIn('id', $data)->get();
You can use this example for dynamically calling the Where NOT IN
$user = User::where('company_id', '=', 1)->select('id)->get()->toArray();
$otherCompany = User::whereNotIn('id', $user)->get();
You can use WhereNotIn in the following way:
$category=DB::table('category')
->whereNotIn('category_id',[14 ,15])
->get();`enter code here`
You can do following.
DB::table('book_mast')
->selectRaw('book_name,dt_of_pub,pub_lang,no_page,book_price')
->whereNotIn('book_price',[100,200]);
Its simply means that you have an array of values and you want record except that values/records.
you can simply pass a array into whereNotIn() laravel function.
With query builder
$users = DB::table('applications')
->whereNotIn('id', [1,3,5])
->get(); //will return without applications which contain this id's
With eloquent.
$result = ModelClassName::select('your_column_name')->whereNotIn('your_column_name', ['satatus1', 'satatus2']); //return without application which contain this status.
This is my working variant for Laravel 7
DB::table('user')
->select('id','name')
->whereNotIn('id', DB::table('curses')->where('id_user', $id)->pluck('id_user')->toArray())
->get();
$created_po = array();
$challan = modelname::where('fieldname','!=', 0)->get();
// dd($challan);
foreach ($challan as $rec){
$created_po[] = array_push($created_po,$rec->fieldname);
}
$data = modelname::whereNotIn('fieldname',$created_po)->orderBy('fieldname','desc')->with('modelfunction')->get();
or try pluck in laravel
here
DB::table('user')
->select('id','name')
->whereNotIn('id', DB::table('curses')->where('id_user', '=', $id)->pluck('user_id'))
->get();

Eloquent ORM find by id and add where clause to a relationship model

Hey guys how you doing?
I'm trying to simply find by id and at the same time guarantee that a column from a relationship table is with a value.
I tried a few things but nothing works.
$tag = Tag::find($id)->whereHas('posts', function($q){
$q->where('status','=', 1);
})->get();
Also:
$tag = Tag::whereHas('posts', function($q) {
$q->where('status','=', 1);
})->where('id','=', $id)->get();
Can you help me?
It is a simple thing but I can't manage to do it...
You need to read on Eloquent docs. Learn what's find, first, get for that matter.
Your code does what you need, and more (a bit wrong though) ;)
$tag = Tag::find($id) // here you fetched the Tag with $id
->whereHas('posts', function($q){ // now you start building another query
$q->where('status','=', 1);
})->get(); // here you fetch collection of Tag models that have related posts.status=1
So, this is what you want:
$tag = Tag::whereHas('posts', function($q){
$q->where('status','=', 1);
})->find($id);
It will return Tag model or null if there is no row matching that where clause OR given $id.
Have you checked Query Scope ?
You can do this:
$tag = Tag::where('status', '=', 1)
->where('id', '=', 1, $id)
->get();

Resources