Laravel Eloquent "WHERE NOT IN" - laravel

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();

Related

how attach the relationship when getting data from database by model in laravel

I want to attach the relationship when getting data from database by model in laravel.
I use these code to do this.
but I know there is better way to do this.
thanks for your helps.
$courses = Cource::orderBy('id' , 'desc')->take($count)->get();
foreach($courses as $cource){
$cource['image'] = $cource->image()->get();
$cource['rate'] = $cource->rate()->get();
}
You might want to use with:
$courses = Cource::orderBy('id' , 'desc')
->take($count)
->with(['image', 'rate'])
->get();
$courses = Cource::orderBy('id' , 'desc')
->take($count)
->with(['image', 'rate'])
->get();
the condition is that use all relationship except morph relationship

Join Laravel tables

I have got three tables Kudos, Kudoscategories, and specialpost. I need to get the data from those tables and check the post id using a where condition.
I have attached the database table screenshot here
I already tried this, but it's not getting any result.
$results = DB::table('kudos')
->select('kudos.description','kudoscategory.catname','kudoscategory.image','kudos.spid')
->join('kudoscategory', 'kudoscategory.id', '=', 'kudos.categoryid')
->where('kudos.spid', '=', $post_id)
->first();
return $results;
What I need to do is get the results using below where condition newsfeed_special_posts.main_post_id = kudos.spid
You must add another join with newsfeed_special_posts.
The query will be like,
$results = DB::table('kudos')
->select('kudos.description','kudoscategory.catname','kudoscategory.image','kudos.spid')
->join('kudoscategory', 'kudoscategory.id', '=', 'kudos.categoryid')
->join('newsfeed_special_posts', 'newsfeed_special_posts.main_post_id', '=', 'kudos.spid')
->where('kudos.spid', '=', $post_id)
->first();
return $results;
Though this is not a good practice for laravel. using laravel eloquent relationships will be more efficient for these results.
https://laravel.com/docs/5.8/eloquent-relationships
you can still do it this way. still efficient to avoid sql injection since you are getting all the record from the 3 tables. seeing your table above, its not properly normalised. anywaye try this.
$results = DB::table('kudos')
->leftjoin('kudoscategory', 'kudoscategory.id', '=', 'kudos.categoryid')
->leftjoin('newsfeed_special_posts', 'newsfeed_special_posts.id', '=', 'kudos.spid')
->where('kudos.spid', '=', $post_id)
->first();
return $results;
you can try this code
at first, create model Kudos,KudosCategory,NewsfeedSpecialPosts
Kudos Model
public function kudoscategory_dta()
{
return $this->belongsTo('App\Model\KudosCategory','categoryid');
}
public function newsfeed_special_posts_dta()
{
return $this->belongsTo('App\Model\NewsfeedSpecialPosts','spid','main_post_id ');
}
controller
Kudos::with('kudoscategory_dta','newsfeed_special_posts_dta')->first();

Laravel pluck an array from nested relationship

I need to get only the roomnumber arrays returned from the following query:
$roomnumbers = Room::with(['floorroomcount' => function($query){
$query->with('roomnumber')->get();
}])->where('roomtype_id', $roomtype_id)->get();
Tried:
The follow pluck is returning floorroomcount
$roomnumbers->pluck('floorroomcount');
but i need roomnumber array, how can i get?
This gives you all roomnumber results in one collection:
$roomnumbers->pluck('floorroomcount')->collapse()->pluck('roomnumber')->collapse();
You may shorten #Jonas Staudenmeir's answer like so:
$roomnumbers->pluck('floorroomcount.*.roomnumber.*')->collapse();
pluck('*') is essentially the same as collapse() in this particular context.
This is working, but with many loop and echoing directly, if anything can be simplified please let me know :
$roomnumbers = Room::with(['floorroomcount.roomnumber'])->where('roomtype_id', $roomtype_id)->get();
$floorroomcounts = $roomnumbers->pluck('floorroomcount');
$records = $floorroomcounts->map(function($floorroomcount, $value){
return $floorroomcount->pluck('roomnumber')->flatten();
})->values()->all();
foreach($records as $record){
foreach($record as $row){
echo '<option value='.$row->id.'>'.$row->roomnumber.'</option>';
}
}
//return response()->json($roomnumbers);
Try,
$roomnumbers = Room::with(['floorroomcount' => function($query){
$query->with('roomnumber')->get();
}])
->where('roomtype_id', $roomtype_id)
->get();
$records = $roomnumbers->map(function($element, $value){
return $element->map(function($e, $v){
return $e->roomnumber;
});
})->values()->all();
map() is a Laravel collection method so you need to import the collection facade on the top of the controller like: use Illuminate\Support\Collection;
In Laravel 5.1 and + you can use flatten() on collection.
method flattens a multi-dimensional collection into a single dimension:
$roomnumbers->flatten()->pluck('floorroomcount');

withCount() doesn't include deleted rows?

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()

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