laravel query update with multiple condition - php

I have column named flag and I want to update it if value is 1 to null and if value is null to 1 so far is easy to update this column but issue comes where I send multiple data to controller and not only one.
code
public function flagmultiplemessage(Request $request){
$ids = $request->input('ids');
DB::table('messages')->whereIn('id', $ids)
->whereNotNull('messages.flag')->update(['flag' => null])
->whereNull('messages.flag')->update(['flag' => '1']);
}
with function above i get:
message Call to a member function whereNull() on integer
dd
code above is something like this:
ids = [11, 12, 3]
database = [
11->flag = 1,
12->flag = null,
3->flag = 1,
]
the result of code above most change my database like:
database = [
11->flag = null,
12->flag = 1,
3->flag = null,
]
any idea why i get error?

it occurred because you called whereNull method on update method.
You should run 3 separate query like this.
public function flagmultiplemessage(Request $request){
$ids = $request->input('ids');
DB::transaction(function () use ($ids) {
DB::table('messages')->whereIn('id', $ids)
->whereNotNull('messages.flag')->update(['flag' => 0]);
DB::table('messages')->whereIn('id', $ids)
->whereNull('messages.flag')->update(['flag' => 1]);
DB::table('messages')->whereIn('id', $ids)
->where('messages.flag', 0)->update(['flag' => null]);
});
}
but for better performance I suggest you use boolean for flag column and use this simple query
DB::table('messages')->whereIn('id', $ids)->update(['flag' => DB::raw('!flag')]);

The main reason for the error is that the update() method is not chainable
Alternatively, You can do the update in one query by using the mysql Case statement.
public function flagmultiplemessage(Request $request) {
$ids = $request->input('ids');
DB::table('messages')->whereIn('id', $ids)
->update(['flag' => DB::raw('case when flag is null then 1 else null end') ]);
}

You can do this
DB::table('messages')->whereIn('id', $ids)->where(function ($query) {
$query->whereNotNull('messages.flag')->update(['flag' => null])
->orWhereNull('messages.flag')->update(['flag' => '1']);
})

Related

How to Use WhereIn Query in Laravel 8

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

Why can't I properly map nested query on Laravel? "Call to a member function map() on null" shown as error

Really could not get the desired data after map function. I was looking to get credit, date from saving_details and the just saving_bill_number from saving_bills through relation, but now looks like I am stucked in this fatal problem. Call to member function on map shown ad fatal error. Your help would be appreciated.
This is the relation:
public function savingBill()
{
return $this->belongsTo(SavingBill::class);
}
Here is my controller logic:
$savingDetails = SavingDetail::where('date', $request->date)
->with('savingBill')
->get()
->map(function ($savingDetail) {
return [
'credit' => $savingDetail->credit,
'date' => $savingDetail->date,
'saving_bill' => $savingDetail
->saving_bill
->map(function ($inner) {
return [
'saving_bill_number' => $inner->saving_bill_number
];
}) // If I put an semicolon here, IDK why error would be shown, hope nothing with the semicolon
];
});
This is the error that I'm getting.Please check the image for the error.
I need to filter above mentioned data from here.
I'm not sure which of these map() actually throws the error but I guess it's the second one that iterates through the saving_bill relation.
You said in the comments that saving_bill_id can be null. If that's the case the relation will also be null and there is no Collection providing the map() method.
Check for null before you assume that this variable is always filled:
$savingDetails = SavingDetail::where('date', $request->date)
->with('savingBill')
->get()
->map(function ($savingDetail) {
return [
'credit' => $savingDetail->credit,
'date' => $savingDetail->date,
'saving_bill' => $savingDetail->saving_bill
? $savingDetail
->saving_bill
->map(function ($inner) {
return [
'saving_bill_number' => $inner->saving_bill_number
];
})
: null,
];
});

Doctrine QueryBuilder - CASE WHEN

I have a question about case when in doctrine.
The problem with this is when uim.isProfileImage is 1 for a user, that returns that row and every other row in user_image table for that user.
What I want is, if there is a profile image (isProfileImage is 1 in user_image table, there can be only one row with that value for same user) give me only that row, and if there isn't something like that give me null for that.
public function searchUsersByIds(array $ids)
{
$qb = $this->createQueryBuilder('user');
$qb->select('user.id', 'user.username');
$qb->addSelect('(CASE WHEN uim.isProfileImage = :isProfileImage THEŠ uim.imageFileName ELSE :null END) AS imageFileName');
$qb->leftJoin('user.userImages','uim');
$qb->add('where', $qb->expr()->in('user.id', ':ids'));
$qb->setParameter('ids', $ids);
$qb->setParameter('isProfileImage', 1);
$qb->setParameter('null', null);
return $qb->getQuery()->getResult();
}
So it should look something like this:
With profile image:
userId => 1,
username => 'Mark',
imageFileName => 'someFileName'
And without profile image:
userId => 1,
username => 'Mark',
imageFileName => null
Also since there is an in expr, it should work with multiple ids that pass to this function.
Thanks in advance.
Try this:
public function searchUsersByIds(array $ids)
{
$qb = $this->createQueryBuilder('user');
$qb->select('user.id', 'user.username');
$qb->addSelect('uim.imageFileName AS imageFileName');
$qb->leftJoin('user.userImages','uim', 'with', 'uim.isProfileImage = :isProfileImage');
$qb->add('where', $qb->expr()->in('user.id', ':ids'));
$qb->setParameter('ids', $ids);
$qb->setParameter('isProfileImage', 1);
$qb->setParameter('null', null);
return $qb->getQuery()->getResult();
}

How can I use array_where in Laravel?

I have an array ($payments) returned by an Eloquent query with the following JSON encoded output:
[{"id":1, "user_id":"34","amount":"1000","status":"0","created_at":"2016-08-18 14:24:59","updated_at":"2016-08-18 14:24:59"},
{"id":3, "user_id":"33","amount":"300","status":"1","created_at":"2016-08-18 14:31:04","updated_at":"2016-08-18 14:33:20"},
{"id":4, "user_id":"33","amount":"1000","status":"0","created_at":"2016-08-18 14:31:27","updated_at":"2016-08-18 14:31:27"},
{"id":5, "user_id":"34","amount":"400","status":"1","created_at":"2016-08-18 14:42:02","updated_at":"2016-08-18 14:42:02"}]
I want to use the array_where() method in Laravel and filter $payments according this condition : status == 1, could anyone tell me how to do that?
If this is the result of an Eloquent query, it's not an array, it's a Collection. From the documentation:
All multi-result sets returned by Eloquent are an instance of the Illuminate\Database\Eloquent\Collection object
You can use the Collection's filter method, which takes a closure, and return the condition you want ('status' == 1) in the closure.
$filtered = $your_query_result->filter(function($value, $key) {
return $value->status == 1;
});
You may be surprised to find out that there is a php function called array_filter that does exactly that. Here it is in action
$array = [ ['id' => 1, 'status' => 0], ['id' => 2, 'status' => 1], ['id' => 3, 'status' => 0] ];
$array = array_filter($array, function ($item) {
return $item['status'] == 1;
});
Eloquents result cannot be json by default unless You call toJson() method.
Why not just add to Your database query condition?
Example:
$payments = Payment::where('status', '=', 1)->get(); // Payment is model
return response()->json($payments);
p.s. it's not recommended to get a big list of json data from db, parse it and filter it.
make better use of database and don't make Your life hard (:

Laravel Eloquent orWhere Query

Can someone show me how to write this query in Eloquent?
SELECT * FROM `projects` WHERE `id`='17' OR `id`='19'
I am thinking
Project::where('id','=','17')
->orWhere('id','=','19')
->get();
Also my variables (17 and 19) in this case are coming from a multi select box, so basically in an array. Any clues on how to cycle through that and add these where/orWhere clauses dynamically?
Thanks.
You could do in three ways. Assume you've an array in the form
['myselect' => [11, 15, 17, 19], 'otherfield' => 'test', '_token' => 'jahduwlsbw91ihp'] which could be a dump of \Input::all();
Project::where(function ($query) {
foreach(\Input::get('myselect') as $select) {
$query->orWhere('id', '=', $select);
}
})->get();
Project::whereIn('id', \Input::get('myselect'))->get();
$sql = \DB::table('projects');
foreach (\Input::get('myselect') as $select) {
$sql->orWhere('id', '=', $select);
}
$result = $sql->get();
The best approach for this case is using Laravel's equivalent for SQL's IN().
Project::whereIn('id', [17, 19])->get();
Will be the same as:
SELECT * FROM projects WHERE id IN (17, 19)
This approach is nicer and also more efficient - according to the Mysql Manual, if all values are constants, IN sorts the list and then uses a binary search.
In laravel 5 you could do it this way.
$projects = Projects::query();
foreach ($selects as $select) {
$projects->orWhere('id', '=', $select);
}
$result = $projects->get();
This is very useful specially if you have custom methods on your Projects model and you need to query from variable. You cannot pass $selects inside the orWhere method.
public function getSearchProducts($searchInput)
{
$products = Cache::rememberForever('getSearchProductsWithDiscountCalculationproducts', function () {
return DB::table('products_view')->get();
});
$searchProducts = $products->filter(function ($item) use($searchInput) {
return preg_match('/'.$searchInput.'/i', $item->productName) || preg_match('/'.$searchInput.'/i', $item->searchTags) ;
});
$response = ["status" => "Success", "data" => $searchProducts ];
return response(json_encode($response), 200, ["Content-Type" => "application/json"]);
}
use filter functionality for any customize situations.

Categories