How to Use WhereIn Query in Laravel 8 - php

Controller
public function detail(Peserta $peserta)
{
// get konfirmasi_id
$konfirmasi = KonfirmasiPembayaran::where('email',$peserta->email)->select('id')->get();
$payments = BankSettlement::whereIn('konfirmasi_id',array($konfirmasi->id))->get();
// dd($payments);
$tagihan = Tagihan::where([['peserta_id', $peserta->id],['type', 3]])->first();
return view('data.peserta.detail', ['data' => $peserta, 'payments' => $payments,'tagihan' => $tagihan]);
}
I want to display data from BankSettlement based on konfirmasi_id. Here I try to use WhereIn Query like this, but still error "Property [id] does not exist on this collection instance.".
$konfirmasi has data like the image above.
What is the correct way to display data from BankSettlement based on konfirmasi_id ? Thankyou

Try this changes:
$konfirmasi = KonfirmasiPembayaran::where('email',$peserta->email)->pluck('id')->toArray();
$payments = BankSettlement::whereIn('konfirmasi_id',$konfirmasi)->get();

This is the wrong way to change a collection to array.
$payments=BankSettlement::whereIn('konfirmasi_id',array($konfirmasi->id))->get();
You should do this
public function detail(Peserta $peserta)
{
// get konfirmasi_id
$konfirmasi = KonfirmasiPembayaran::where('email',$peserta->email)
->select('id')
->get()
->pluck('id')
->toArray(); //This will return an array of ids
$payments = BankSettlement::whereIn('konfirmasi_id',$konfirmasi)->get();
// dd($payments);
$tagihan = Tagihan::where([['peserta_id', $peserta->id],['type', 3]])->first();
return view('data.peserta.detail', ['data' => $peserta, 'payments' => $payments,'tagihan' => $tagihan]);
}
Edit:
Read Laravel Collections|Pluck

If you do not have to reuse the result of $konfirmasi then it would be better to use subquery. Writing a subquery is optimized way. if you write two different query then there will be two seperate database connection request.
Laravel subquery
$konfirmasi = KonfirmasiPembayaran::where('email',$peserta->email)->select('id');
$payments = BankSettlement::whereIn('konfirmasi_id', $konfirmasi )->get();

Related

Laravel - Paginate function doesn't working on query building using IF

I am using paginate() on my Controller to pass data to the View. This is my index function using the paginate()
$userData = User::with('jobUnit')
->select('nip','name','address','phone','email','unit_id')
->paginate(10);
return view('users.index', [
'users' => $userData
]);
This is the result:
In the other function, I needed to add some IF conditions on the queries that is look like this:
$keyword = $request->keyword;
$searchedData = User::with('jobUnit')->select('nip','name','address','phone','email','unit_id');
if ($request->searchFilter == 'nip') {
$searchedData->where('nip','like','%'.$keyword.'%');
}
$searchedData->paginate(10);
The results is different, which is a problem for me because I am using the pagination links in the View. Here is the results:
Does the pagination() not working? Because I tried using the get() as well which should returns "Collection", but it was still returning the "Builder" results.
you need another variable to store the return data
$searchDataPaginated = $searchedData->paginate(10);
or using the current one if you want
$searchedData = $searchedData->paginate(10);

Return Collection after update()?

Using Raw, how to return collection of updated row?
For example:
$updated = DB::table('users')->where('id', 1)->update(['votes' => 123]);
I was expecting dd($updated) to return updated row of collection but it returned 1.
{{$updated->votes}} should return 123
Try this
$updated = tap(DB::table('users')->where('id', 1))
->update(['votes' => 123])
->first();
That's not how it works. You can't expect this query will return you an object:
$updated = DB::table('users')->where('id', 1)->update(['votes' => 123]);
If you want to use Query Builder only as you mentioned in your question, you'll need to get an object manually:
$data = DB::table('users')->where('id', 1)->first();
With Eloquent you can use the updateOrCreate():
$data = User::where('id', 1)->updateOrCreate(['votes' => 123]);
This will return an object. update() will return boolean, so you can't use it here.
for version 6: another way with eloquent to return the new updated model by chaining the update method call through tap :
$user = tap($user)->update(['votes' => 123]);
This also returns the updated row:
$user = $user->fill(['votes' => 123])->save();
This trick worked for me:
$updated = DB::select("UPDATE users SET votes = 123 WHERE id = 1 RETURNING votes");
Then, since select returns an array: $votes = $updated[0]->votes;
And I believe you could even retrieve the entire row(s) using RETURNING *
This also work with prepared statements:
$updated = DB::select("UPDATE users SET votes = ? WHERE id = ? RETURNING votes", [$votes, $id]);
IMPORTANT NOTE
I am using a Postgres database. This will work only on a db that supports such a thing as RETURNING
you get the first row again after update see example bellow
$user = User::where('id', 1);
$userOld = $user->first(); // will return the first row
$isUserUpdated = $user->update(['name'=>'new name']); // will return true or false
$updatedUser = $user->first(); // now it will return you the latest updated data
by this example you have old data and new data and is data updated result, now we can return new data.
return response()->json(['status' => $isUserUpdated,'data'=>$updatedUser], 200);
In controller you write below code for update :
$updated = DB::table('users')->where('id', 1)->update(['votes' => 123])->get();

Showing orders of user in laravel

I'm trying to give ability on user to see his orders. How can I query the database.. I'm trying something like this but I got empty page.. I mean nothing from database. May be my query ins't correct.
This is my controller
public function viewOrders() {
$user_order = self::$user->user_id;
$orders = Order::where('user_id', '=', $user_order);
return View::make('site.users.orders', [
'orders' => $orders
]);
}
Am I getting correctly user_id here? I'm not sure...
Update: I have this in my User model
public function orders() {
return $this->hasMany('Order', 'user_id', 'user_id');
}
Ok, so based on your route+button+model do it like this
$orders = self::$user->orders()->orderBy('order_id', 'asc')->get();
return View::make('site.users.orders', [
'orders' => $orders
]);
this should work.. You can remove orderBy clause if you don't need it.
If you have Authentication set properly you can do the following.
public function viewOrders(){
$user = Auth::user();
return view('site.users.orders',[
'orders' => $user->orders
]);
}
When you use the relationship without using the calling parentheses you get a collection of models which are queried if they're not already loaded. This is called lazy loading, if you want to load a relationship before accessing it you can use eager loading. In this case, it is not necessary though.

How can I build a condition based query in Laravel using eloquent

I was wondering how can I build a condition based query in Laravel using eloquent?
I've found how to do it with a raw query but that that's not what I want also the answer to this question isn't that dynamic at least not as dynamic as I want it to be.
What I try to achieve is to create a dynamic WHERE query based on certain conditions, for example if the field is filled or not.
If I use the following code,
$matchThese = [
'role' => 'user',
'place' => \Input::get('location')
];
$availableUsers = User::where($matchThese)->take($count)->orderByRaw("RAND()")->get();
The query will fail if I don't send a location as POST value. I don't want it to fail I want it to skip to the next WHERE clause in the query. So basically if there's no place given don't search for it.
Build up the query and include the ->where() clause depending on whether or not you have the location in your input:
$query = User::where('role', 'user');
$query = \Input::has('location') ? $query->where('location', \Input::get('location')) : $query;
$availableUsers = $query->take($count)->orderByRaw('RAND()')->get();
Just build the array with an if condition:
$matchThese = [
'role' => 'user',
];
if(\Input::has('location')){
$matchThese['place'] = \Input::get('location');
}
$availableUsers = User::where($matchThese)->take($count)->orderByRaw("RAND()")->get();
$query = DB::table('table_name');
if($something == "something"){
$query->where('something', 'something');
}
$some_variable= $query->where('published', 1)->get();
You can use something like this.

use 2 queries on one model or 1 query and make it toarray method to get other query

I need to get an associative array for a select input just like the following code below.
public function create() {
// queries the clients db table, orders by client_name and lists client_name and id
$client_optons = DB::table('clients')->orderBy('client_name', 'asc')->lists('client_name','id');
return View::make('projects.create', array('client_options' => $client_options));
}
However I will also need to get the entire model $clients.
public function create() {
$clients=Clients::all();
// queries the clients db table, orders by client_name and lists client_name and id
$client_optons = DB::table('clients')->orderBy('client_name', 'asc')->lists('client_name','id');
return View::make('projects.create', array('client_options' => $client_options));
}
Since I am already getting the entire model in my query, my question is should I use the 2 queries like shown above or is that bad performance/coding? Should I use 1 query and then play with the model to get $client options? (Like shown below) And do I do this with a loop or are there array functions that do it more succinctly?
public function create() {
$clients=Clients::all();
$clients_array = $clients->toArray();
$client_options = /*some code to create array('client_name'=>'id') */
return View::make('projects.create', array('client_options' => $client_options));
}
Fortunately the lists() function is also available on collections:
$clients = Clients::orderBy('client_name', 'asc')->get();
$client_options = $clients->lists('client_name', 'id');
return View::make('projects.create', array(
'client_options' => $client_options,
'clients' => $clients
));

Categories