Laravel - Pluck multiple columns - laravel

I need to pluck two columns name and score from my table corporate_objectives and put it in my graph chart. I'm having two different behavior and I can't seem to get my desired result.
1st code
$getNameAndScore = CorporateObjective::pluck('name');
foreach($getNameAndScore as $key => $item) {
$corporateObjective[] = [$item, '('.$key.'%)'];
}
Result:
"xAxis": [
[
"PEOPLE DEVELOPMENT",
"(0%)"
],
[
"OPTIMUM SYSTEMS AND PROCESSES",
"(1%)"
],
[
"CUSTOMER MANAGEMENT",
"(2%)"
],
[
"REVENUE GROWTH",
"(3%)"
]
],
2nd code
$getNameAndScore = CorporateObjective::pluck('name', 'score');
foreach($getNameAndScore as $key => $item) {
$corporateObjective[] = [$item, '('.$key.'%)'];
}
Result:
"xAxis": [
[
"REVENUE GROWTH",
"(25%)"
]
],
I'm getting all the correct name but the incorrect score in my first code. On my second code, I'm getting the correct name and score but all data is not being pulled out. I wanted to achieve the first code with all the correct score from the second code.
EDIT:
This is how my database looks like
id | name | score
1 PEOPLE DEVELOPMENT 25
2 OPTIMUM SYSTEMS AND PROCESSES 25
3 CUSTOMER MANAGEMENT 25
4 REVENUE GROWTH 25
Is there another way other than pluck? It seems like pluck merges / filters all data with the same value.

This is the correct output of your code. There is no problem here
$getNameAndScore = CorporateObjective::pluck('name', 'score');
foreach($getNameAndScore as $key => $item) {
$corporateObjective[] = [$item, '('.$key.'%)'];
}
How does work pluck here is description
If duplicate keys exist, the last matching element will be inserted into the plucked collection:
$collection = collect([
['brand' => 'Tesla', 'color' => 'red'],
['brand' => 'Pagani', 'color' => 'white'],
['brand' => 'Tesla', 'color' => 'black'],
['brand' => 'Pagani', 'color' => 'orange'],
]);
$plucked = $collection->pluck('color', 'brand');
$plucked->all();
// ['Tesla' => 'black', 'Pagani' => 'orange']
Details in here

So I just made an alternative way of doing it and it might help other people. If there is a more proper way or cleaner way of doing it, please feel free to correct my answer.
$getNameAndScore = CorporateObjective::pluck('name');
foreach($getNameAndScore as $item) {
$key = CorporateObjective::where('name', $item)->value('score');
$corporateObjective[] = [$item, '('.$key.'%)'];
}
return response()->json([
'xAxis' => $corporateObjective,
]);
Result
"xAxis": [
[
"PEOPLE DEVELOPMENT",
"(25%)"
],
[
"OPTIMUM SYSTEMS AND PROCESSES",
"(1%)" // I changed the value in the database and it works
],
[
"CUSTOMER MANAGEMENT",
"(22%)" // I changed the value in the database and it works
],
[
"REVENUE GROWTH",
"(25%)"
]
],

Related

Larvel Query Builder group By with pluck

id
agent_id
currency
1
A0001
IDR
2
A0002
MYR
3
A0001
THB
example currently have a dataset as above,
is it have any way to using only 1 query builder to get the outcome like below
Output:
[
"agent_id" => "A0001",
"currency" => [
"IDR",
"THB",
],
],
[
"agent_id" => "A0002"
"currency" => ["MYR"]
]
Basically likes try to pluck the currency under same agent
Appreciate for all the suggestion.
Found a solution for this problem
$output = $output
->get()
->groupby('agent_id')
->map(function($rows){
return [
"agent_id" => $rows[0]['agent_id'],
"currency" => $rows->pluck('currency'),
];
});

How to validate array values as part of a unique set of values in Laravel?

I have a days table with day, start_time, end_time columns. I've set these 3 columns as a unique set of values in my migration $table->unique(['start_time', 'end_time', 'day']).
Currently I'm validating them like this:
'day.*.day' => [
'required',
],
'time.*.start_time' => [
'required', 'different:time.*.end',
],
'time.*.end_time' => [
'required', 'different:time.*.start',
]
But I also want to add Rule::unique() validation rule so each set of values are different from each other. I've done similar validation but not to an array value.
I've tried tinkering with it for hours, I did try to loop some stuff but unfortunately it doesn't work that way.
foreach ($schedule->days as $day) {
$time = request()->validate([
"day" => [
'required',
Rule::unique('days')
->where('day', request('day')[$day->id]['day'])
->where('start_time', request('time')[$day->id]['start_time'])
->where('end_time', request('time')[$day->id]['end_time'])
],
// and so on ...
Just modify a little part from this
Validator::make($data, [
'data.ip' => [
'required',
Rule::unique('servers')->where(function ($query) use($ip,$hostname) {
return $query->where('ip', $ip)
->where('hostname', $hostname);
}),
],
],

Laravel: custom array validation depends on previous selected value

Laravel version: 7.x
I have tested the code with hard-coded valid device_company_id (which is associated with the selected device) and it works fine.
Tables
device_companies
|- id
|- company_id
|- title
|- ...
devices
|- id
|- device_company_id
|- ...
Request data
Array
(
...
[devices] => Array
(
[0] => Array
(
[device_company_id] => 1
[device_id] => 2
[device_inventory_id] => null
[amount] =>
[refundable] =>
[description] =>
)
)
)
Rules:
...
$rules = array_merge($rules, [
'devices' => [
'required',
'array'
],
'devices.*.device_company_id' => [
'required',
'integer',
'exists:device_companies,id,company_id,' . auth()->user()->id
],
'devices.*.device_id' => [
'required',
'integer',
'exists:devices,id,device_company_id,devices.*.device_company_id'
],
]);
...
I need a custom validation rule for the exists validator to validate if device actually belongs the selected device_company or not. Because I don't want anyone opening the inspect tool, change the value and causing the application an error or anything like that.
Here is the link where I found the reference https://ericlbarnes.com/2015/04/04/laravel-array-validation/
My code:
...
$rules = [
...other rules
];
$newRules = [
'devices' => [
'required',
'array'
],
'devices.*.device_company_id' => [
'required',
'integer',
'exists:device_companies,id,company_id,' . auth()->user()->id
],
];
foreach($data['devices'] as $key => $array)
{
$newRules["devices.{$key}.device_id"] = [
'required',
'integer',
"exists:devices,id,device_company_id,{$array["device_company_id"]}",
];
}
$rules = array_merge($rules, $newRules);
...
Although, this code is working for me but I feel its not the proper way to do it. It feels kind of a way around instead of the proper solution. If anyone finds a better solution then please do post your answer.
Hope this can be helpful for someone. Thanks :)

!empty record show in first order in cake php

I have a retrieved restaurant list. when the restaurant menu is empty that restaurant showed in last order.. what i do.. can you help..
My Query is :
$restaurantList = $this->Restaurants->find('all', [
'conditions' => $conditions,
'contain' => [
'DeliveryLocations' => [
'conditions' => $areaLocationConditions,
],
'RestaurantMenus' => [
'conditions' => [
'RestaurantMenus.status' => 1,
'RestaurantMenus.delete_status' => 'N'
]
]
],
'limit' => 5,
'order' => 'Restaurants.id DESC'
])->hydrate(false)->toArray();
Simple solution:
by implementing CounterCache
https://book.cakephp.org/3.0/en/orm/behaviors/counter-cache.html and order by cache results.
More complex:
by using Case statements
https://book.cakephp.org/3.0/en/orm/query-builder.html#case-statements
select 'has_menus' if restuarant has menus then 1 else 0
order by that results

Cake3 Paginator Sort Error

I have a very simply model which I want to paginate. The pagination works but the sort links do not have any effect:
My Controller:
public $paginate = [
'limit' => 10,
'order' => [
'Properties.id' => 'asc'
],
'sortWhitelist' => [
'Properties.id',
'Properties.name',
'Properties.active'
],
];
My query:
$properties = $this->Properties->find('all')->where($options)->contain($contains)->order(['Properties.id']);
$this->set('properties', $this->paginate($properties));
My view displays 10 items per page and the links to pages/next/previous work fine. When I click the sort link:
$this->Paginator->sort('id', 'ID')
The url called is:
properties/index/3?sort=id&direction=desc
The page re-loads but the order of the data does not change.
The whitelist expects the exact field name that you are using in sort. It will not automatically prepend the primary table's name, so your whitelist should look like this:
public $paginate = [
'limit' => 10,
'order' => [
'Properties.id' => 'asc'
],
'sortWhitelist' => [
'id',
'name',
'active'
],
];
It will see "id" in the query and check that the exact field name "id" exists in the whitelist.
Also, it appears you are including an order() on your query. To allow the paginator to set the order, you should remove this clause.

Resources