Laravel\Lumen get eager loading parameter and send to another eager loading - php

Lumen v 5.7
I have json response like this
{
"data": {
"id": 172,
"name": "Group Test",
"groupmates": [
{
"id": 4555,
"name": "Andri Josua",
"peer_reviews": [
{
"id": 509,
"peer_review_period_id": 17,
"peer_review_setting_id": 15,
"peer_review_setting_item_id": 72,
"student_id": 4555,
"peer_review_setting": {
"id": 15,
"criteria": "Partisipasi",
"partner_id": 6,
"created_at": "2017-07-05T06:44:12.000Z",
"updated_at": "2018-11-28T04:12:37.000Z",
"peer_review_setting_items": [
{
"id": 71,
"peer_review_setting_id": 15,
"partner_id": 6,
"remarks": "Sangat Tidak Baik",
"grade": "0",
"description": "Anggota kelompok,\r\n• tidak berpartisipasi dalam tugas kelompok.\r\n\r\n",
"order_number": 1,
"created_at": "2017-07-05T06:44:12.000Z",
"updated_at": "2017-07-05T06:44:12.000Z"
},
{
"id": 72,
"peer_review_setting_id": 15,
"partner_id": 6,
"remarks": "Tidak Baik",
"grade": "40",
"description": "Anggota kelompok,\r\n • jarang berpartisipasi, • waktu terbuang, atau • mengerjakan materi yang tidak terkait.",
"order_number": 2,
"created_at": "2017-07-05T06:44:12.000Z",
"updated_at": "2017-07-05T06:44:12.000Z"
},
]
}
}
]
}
]
}
}
and controller like this
public function csu($studentId, $klassId, $csuId)
{
$student = Student::findOrFail($studentId);
$contentSectionUnit = ContentSectionUnit::findOrFail($csuId);
$prPeriod = $contentSectionUnit->peer_review_periods->first();
$group = ClassGroup::me($student)
->with(['class_group_students' => function ($query) use ($studentId, $prPeriod) {
$query->with(['peer_reviews' => function ($query) use ($studentId, $prPeriod) {
$query->with(['peer_review_setting' => function ($query) {
$query->with('peer_review_setting_items');
}])
->where('peer_review_period_id', $prPeriod->id)
->where('student_reviewer_id', $studentId)
->orderBy('peer_review_setting_id', 'asc');
}])
->where('student_id', '!=', $studentId)
->orderBy('student_id', 'asc');
}])
->whereKlassId($klassId)
->first();
return new PeerReviewContentResource($group);
}
I want to add new attribute checked in peer_review_setting_items, which value of the attribute is obtained from checking where peer_review_setting_item_id == peer_review_setting_items->id.
How to send peer_review_setting_item_id at peer_review attribute to peer_review_setting_items relation?
Expected result is like this
...
"peer_review_setting_items": [
{
"id": 71,
"peer_review_setting_id": 15,
"partner_id": 6,
"remarks": "Sangat Tidak Baik",
"grade": "0",
"description": "Anggota kelompok,\r\n• tidak berpartisipasi dalam tugas kelompok.\r\n\r\n",
"order_number": 1,
"created_at": "2017-07-05T06:44:12.000Z",
"updated_at": "2017-07-05T06:44:12.000Z",
"checked": false
},
{
"id": 72,
"peer_review_setting_id": 15,
"partner_id": 6,
"remarks": "Tidak Baik",
"grade": "40",
"description": "Anggota kelompok,\r\n • jarang berpartisipasi, • waktu terbuang, atau • mengerjakan materi yang tidak terkait.",
"order_number": 2,
"created_at": "2017-07-05T06:44:12.000Z",
"updated_at": "2017-07-05T06:44:12.000Z",
"checked": true
},
]
...

Related

Laravel pluck fails to get value from load relationship

I need to return just an array of the name values for each of my roles. My roles is a hasMany relationship. This is currently how I'm trying to do it, but the returned result is unchanged, what am I missing?
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show(Request $request, Company $company)
{
$this->authorize('view', $company);
if ($request->boolean('with_roles')) {
$company = $company->load(['roles' => function ($query) {
$query->pluck('name');
}]);
}
return new ApiSuccessResponse($company);
}
gives me:
{
"model": {
"id": 1,
"user_id": 1,
"contact_first_name": "John",
"created_at": "2023-02-15T09:45:48.000000Z",
"updated_at": "2023-02-15T09:45:48.000000Z",
"deleted_at": null,
"is_deleting": false,
"roles": [
{
"id": 6,
"company_id": 1,
"name": "accountant",
"guard_name": "api",
"created_at": "2023-02-15T09:45:59.000000Z",
"updated_at": "2023-02-15T09:45:59.000000Z"
},
{
"id": 2,
"company_id": 1,
"name": "admin",
"guard_name": "api",
"created_at": "2023-02-15T09:45:48.000000Z",
"updated_at": "2023-02-15T09:45:48.000000Z"
},
{
"id": 4,
"company_id": 1,
"name": "affiliate",
"guard_name": "api",
"created_at": "2023-02-15T09:45:56.000000Z",
"updated_at": "2023-02-15T09:45:56.000000Z"
},
{
"id": 3,
"company_id": 1,
"name": "affiliate_manager",
"guard_name": "api",
"created_at": "2023-02-15T09:45:55.000000Z",
"updated_at": "2023-02-15T09:45:55.000000Z"
},
{
"id": 5,
"company_id": 1,
"name": "buyer",
"guard_name": "api",
"created_at": "2023-02-15T09:45:58.000000Z",
"updated_at": "2023-02-15T09:45:58.000000Z"
},
{
"id": 8,
"company_id": 1,
"name": "guest",
"guard_name": "api",
"created_at": "2023-02-15T09:46:02.000000Z",
"updated_at": "2023-02-15T09:46:02.000000Z"
},
{
"id": 7,
"company_id": 1,
"name": "user",
"guard_name": "api",
"created_at": "2023-02-15T09:46:00.000000Z",
"updated_at": "2023-02-15T09:46:00.000000Z"
}
]
}
}
I expect to see:
{
"model": {
"id": 1,
"user_id": 1,
"contact_first_name": "John",
"created_at": "2023-02-15T09:45:48.000000Z",
"updated_at": "2023-02-15T09:45:48.000000Z",
"deleted_at": null,
"is_deleting": false,
"roles": [
"accountant",
"admin",
"affiliate"
...
]
}
}
pluck doesn't modify the original relationship, it only returns an array. Try this one :
public function show(Request $request, Company $company)
{
$this->authorize('view', $company);
$result = $company->toArray();
if ($request->boolean('with_roles')) {
$result['roles'] = $company->roles()->pluck('name')->toArray();
}
return new ApiSuccessResponse($result);
}

Delete key 'data' of collection Laravel

I need to remove the 'data' key from my collection in Laravel.
This worked for me, but it removed the other keys that I cared to keep, I just need to remove the 'data' key:
return $filteredValues ​​= $collection->values ​()->all(); // I remove other keys inside the objects.
My collection return:
$records = Item::where('tienda_id',$id)->where('item.nombre', 'like', "%" . $query . "%")->take(50)->get();
return $collection = new ItemCollection($records);
My ItemCollection.php
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
use Illuminate\Support\Facades\Storage;
class ItemCollection extends ResourceCollection
{
/**
* Transform the resource collection into an array.
*
* #param \Illuminate\Http\Request $request
* #return mixed
*/
public function toArray($request)
{
return $this->collection->transform(function($row, $key) {
return [
'id' => $row->id,
'nombre' => $row->nombre,
'marca_id' => $row->marca_id,
'tienda_id' => $row->tienda_id,
'nombre_marca' => $row->marca->nombre_marca,
'unidad_id' => $row->unidad_id,
'nombre_unidad' => $row->unidad->nombre_unidad,
'tipo_cambio' => $row->tienda->tipocambio,
'categoria_id' => $row->categoria_id,
'stock' => $row->stock,
'moneda' => $row->moneda,
'codigos' => $row->codigos,
'stockminimo' => $row->stockminimo,
'stockmaximo' => $row->stockmaximo,
'impuesto_id' => $row->impuesto_id,
'primer_margen' => $row->primer_margen,
'segundo_margen' => $row->segundo_margen,
'precio' => $row->precio,
'notas' => $row->notas,
'imagen' => url('images/'.$row->imagen),
];
});
}
}
My JSON:
{
"data": [
{
"id": 27,
"nombre": "Nombre de prueba",
"marca_id": 2,
"tienda_id": 2,
"nombre_marca": "marca 2",
"unidad_id": 59,
"nombre_unidad": "NIU",
"tipo_cambio": "3.54",
"categoria_id": 1,
"stock": 100,
"moneda": "$",
"codigos": [
{
"id": 2,
"nombre_codigo": "Codigo",
"tienda_id": 2,
"created_at": "2020-08-03T15:19:11.000000Z",
"updated_at": "2020-08-06T22:38:02.000000Z",
"pivot": {
"item_id": 27,
"codigo_id": 2,
"nombre": "66677kj"
}
},
{
"id": 5,
"nombre_codigo": "CODIGO 2",
"tienda_id": 2,
"created_at": "2020-08-07T20:45:29.000000Z",
"updated_at": "2020-08-07T20:45:29.000000Z",
"pivot": {
"item_id": 27,
"codigo_id": 5,
"nombre": "78877k"
}
}
],
"stockminimo": 1,
"stockmaximo": 100,
"impuesto_id": 1,
"primer_margen": "35.00",
"segundo_margen": "20.00",
"precio": "5.07",
"notas": "jkjkkjkkj",
"imagen": "http://maks.test/images/159692202782450637_121718839341269_2075616741920079872_o.jpg"
},
{
"id": 28,
"nombre": "Aleta de pollo",
"marca_id": 1,
"tienda_id": 2,
"nombre_marca": "marca1x",
"unidad_id": 59,
"nombre_unidad": "NIU",
"tipo_cambio": "3.54",
"categoria_id": 1,
"stock": 5,
"moneda": "S/",
"codigos": [
{
"id": 2,
"nombre_codigo": "Codigo",
"tienda_id": 2,
"created_at": "2020-08-03T15:19:11.000000Z",
"updated_at": "2020-08-06T22:38:02.000000Z",
"pivot": {
"item_id": 28,
"codigo_id": 2,
"nombre": "jhjjkj"
}
},
{
"id": 5,
"nombre_codigo": "CODIGO 2",
"tienda_id": 2,
"created_at": "2020-08-07T20:45:29.000000Z",
"updated_at": "2020-08-07T20:45:29.000000Z",
"pivot": {
"item_id": 28,
"codigo_id": 5,
"nombre": "jkk"
}
}
],
"stockminimo": 6,
"stockmaximo": 88,
"impuesto_id": 1,
"primer_margen": "2.00",
"segundo_margen": "10.00",
"precio": "100.00",
"notas": "jkjkkjjk",
"imagen": "http://maks.test/images/159698573182341068_123146022531884_1345097685962588160_o.jpg"
}
]
}
I need it to look like this:
[
{
"id": 27,
"nombre": "Nombre de prueba",
"marca_id": 2,
"tienda_id": 2,
"nombre_marca": "marca 2",
"unidad_id": 59,
"nombre_unidad": "NIU",
"tipo_cambio": "3.54",
"categoria_id": 1,
"stock": 100,
"moneda": "$",
"codigos": [
{
"id": 2,
"nombre_codigo": "Codigo",
"tienda_id": 2,
"created_at": "2020-08-03T15:19:11.000000Z",
"updated_at": "2020-08-06T22:38:02.000000Z",
"pivot": {
"item_id": 27,
"codigo_id": 2,
"nombre": "66677kj"
}
},
{
"id": 5,
"nombre_codigo": "CODIGO 2",
"tienda_id": 2,
"created_at": "2020-08-07T20:45:29.000000Z",
"updated_at": "2020-08-07T20:45:29.000000Z",
"pivot": {
"item_id": 27,
"codigo_id": 5,
"nombre": "78877k"
}
}
],
"stockminimo": 1,
"stockmaximo": 100,
"impuesto_id": 1,
"primer_margen": "35.00",
"segundo_margen": "20.00",
"precio": "5.07",
"notas": "jkjkkjkkj",
"imagen": "http://maks.test/images/159692202782450637_121718839341269_2075616741920079872_o.jpg"
},
{
"id": 28,
"nombre": "Aleta de pollo",
"marca_id": 1,
"tienda_id": 2,
"nombre_marca": "marca1x",
"unidad_id": 59,
"nombre_unidad": "NIU",
"tipo_cambio": "3.54",
"categoria_id": 1,
"stock": 5,
"moneda": "S/",
"codigos": [
{
"id": 2,
"nombre_codigo": "Codigo",
"tienda_id": 2,
"created_at": "2020-08-03T15:19:11.000000Z",
"updated_at": "2020-08-06T22:38:02.000000Z",
"pivot": {
"item_id": 28,
"codigo_id": 2,
"nombre": "jhjjkj"
}
},
{
"id": 5,
"nombre_codigo": "CODIGO 2",
"tienda_id": 2,
"created_at": "2020-08-07T20:45:29.000000Z",
"updated_at": "2020-08-07T20:45:29.000000Z",
"pivot": {
"item_id": 28,
"codigo_id": 5,
"nombre": "jkk"
}
}
],
"stockminimo": 6,
"stockmaximo": 88,
"impuesto_id": 1,
"primer_margen": "2.00",
"segundo_margen": "10.00",
"precio": "100.00",
"notas": "jkjkkjjk",
"imagen": "http://maks.test/images/159698573182341068_123146022531884_1345097685962588160_o.jpg"
}
]
Thanks in advance for reading me, I hope you can help me solve this problem, thanks!
In AppProvider.php or similar add the following. This will disable data wrapping, for ItemCollections. Thou i would want you to reconsider, if you need to use pagination or meta attributes on your responses, you have no where to put em withouth data wrapping and thats one of the reason it is used.
public function boot()
{
ItemCollection::withoutWrapping();
}

why laravel pagination just work with reture and not custom response Handler

if you see this code:
use ResponseHandler;
public function search(SoundFilter $soundFilter) {
$sounds = Sound::query();
$sounds->filter($soundFilter);
// dd($sounds->toSql());
$sounds = $sounds->paginate(1);
$this->setResponseStatus(1);
$this->setResponseStatusCode(200);
$this->setResponseData([
'sounds' => new SoundsCollection($sounds),
]);
$this->ajaxResponse();
return $this->response();
}
i want soundsCollection($sounds) returen paginate result but it will send only data
{
"status": 1,
"messages": [],
"statusCode": 200,
"data": {
"sounds": [
{
"id": 1,
"name": "منی که عشق با روضه فهمیدم",
"slug": "",
"type": 2,
"description": "<p dir=\"rtl\" style=\"text-align:center\"><strong>متن شعر<\/strong><\/p>",
"likes": 0,
"downloads": 0,
"views": 0,
"created_at": "2019-08-02 20:09:45",
"updated_at": "2019-08-03 18:45:49",
"sort_order": 0,
"status": 1,
}
]
}
}
but when i do this code :
$sounds = Sound::query();
$sounds->filter($soundFilter);
// dd($sounds->toSql());
$sounds = $sounds->paginate(1);
$this->setResponseStatus(1);
$this->setResponseStatusCode(200);
// $this->setResponseData([
//// 'sounds' => new SoundsCollection($sounds),
//// ]);
$this->ajaxResponse();
return new SoundsCollection($sounds);
i will get pagination result
{
"data": [
{
"id": 1,
"name": "منی که عشق با روضه فهمیدم",
"slug": "",
"type": 2,
"description": "<p dir=\"rtl\" style=\"text-align:center\"><strong>متن شعر<\/strong><\/p>",
"likes": 0,
"downloads": 0,
"views": 0,
"created_at": "2019-08-02 20:09:45",
"updated_at": "2019-08-03 18:45:49",
"sort_order": 0,
"status": 1,
}
],
"links": {
"first": "http:\/\/madahi.test\/api\/v1.0\/search?page=1",
"last": "http:\/\/madahi.test\/api\/v1.0\/search?page=3",
"prev": null,
"next": "http:\/\/madahi.test\/api\/v1.0\/search?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 3,
"path": "http:\/\/madahi.test\/api\/v1.0\/search",
"per_page": 1,
"to": 1,
"total": 3
}
}
which function i should call or waht i should do to get same result but with my custom response handler how to force collection return paginate result
i want i have link, meta in first result
i found it and share it for other people if have same problem:
because i use seprate ResponseHandler and it will reutrn an JsonResponse object
it is the data i send to resposnse with responseHandler
// trait : ResponseHandler.php
new JsonResponse($json, $json['statusCode'], $this->headers);
and when i call this code it will retun another JsonResponse
'sounds' => new SoundsCollection($sounds),
// Or
'sounds' => (new SoundsCollection($sounds))->toResponse($request)
so the above JsonResponse will ignore pagination data the solution is :
'sounds' => (new SoundsCollection($sounds))->toResponse($request)->getData()
and it will work
{
"status": 1,
"messages": [],
"statusCode": 200,
"data": {
"sounds": {
"data": [
{
"id": 1,
"name": "منی که عشق با روضه فهمیدم",
"slug": "",
"type": 2,
"description": "<p dir=\"rtl\" style=\"text-align:center\"><strong>متن شعر<\/strong><\/p>",
"likes": 0,
"downloads": 0,
"views": 0,
"created_at": "2019-08-02 20:09:45",
"updated_at": "2019-08-03 18:45:49",
"sort_order": 0,
"status": 1,
}
],
"links": {
"first": "http:\/\/madahi.test\/api\/v1.0\/search?page=1",
"last": "http:\/\/madahi.test\/api\/v1.0\/search?page=3",
"prev": null,
"next": "http:\/\/madahi.test\/api\/v1.0\/search?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 3,
"path": "http:\/\/madahi.test\/api\/v1.0\/search",
"per_page": 1,
"to": 1,
"total": 3
}
}
}
}

How can I hidden data in JSON if variable is empty

I got a some trouble in my Laravel application, in Search function, when I do search the result is
{
"data": [
{
"id": 2,
"user_id": 8,
"identity_number": "213918273",
"name": "Pekerja_2",
"gender_id": 1,
"date_of_birth": "1999-05-25",
"address": "Jalan Bandung Raya no 50",
"province_id": 32,
"city_id": 3273,
"district_id": 3273160,
"phone": "4232343432",
"image": null,
"created_at": "2018-01-11 10:59:54",
"updated_at": "2018-01-11 10:59:54",
"partner_id": null,
"skill": [
{
"id": 3,
"worker_id": 2,
"skill_id": 6,
"sub_skill_id": 18,
"created_at": "2018-01-15 13:06:48",
"updated_at": "2018-01-15 13:06:48",
"price": null,
"unit": null
}
]
},
{
"id": 3,
"user_id": 16,
"identity_number": "213918273",
"name": "Pekerja_3",
"gender_id": 1,
"date_of_birth": "1999-05-25",
"address": "Jalan Bandung Raya no 50",
"province_id": 32,
"city_id": 3273,
"district_id": 3273160,
"phone": "2345234234",
"image": null,
"created_at": "2018-01-15 13:06:48",
"updated_at": "2018-01-15 13:06:48",
"partner_id": null,
"skill": []
}
]
}
as you can see that "Skill" with id number 3 is empty, I want all in id number 3 is empty also.
My controller is :
$worker = Worker::with(['skill' => function($q) use ($request) {
$q->where('worker_skills.sub_skill_id', $request['sub_skill_id']);
}])->whereHas('skill');
And I want something like this :
{
"data": [
{
"id": 2,
"user_id": 8,
"identity_number": "213918273",
"name": "Pekerja_2",
"gender_id": 1,
"date_of_birth": "1999-05-25",
"address": "Jalan Bandung Raya no 50",
"province_id": 32,
"city_id": 3273,
"district_id": 3273160,
"phone": "2534234234",
"image": null,
"created_at": "2018-01-11 10:59:54",
"updated_at": "2018-01-11 10:59:54",
"partner_id": null,
"skill": [
{
"id": 3,
"worker_id": 2,
"skill_id": 6,
"sub_skill_id": 18,
"created_at": "2018-01-15 13:06:48",
"updated_at": "2018-01-15 13:06:48",
"price": null,
"unit": null
}
]
},
]
}
The point is, if "skill" variable is empty then data not show and vice versa.
Thankyou any help will appreciate, sorry for bad english
You can add a callback to your whereHas function with the same filter as the with function
$worker = Worker::with(['skill' => function($q) use ($request) {
$q->where('worker_skills.sub_skill_id', $request['sub_skill_id']);
}])
->whereHas('skill', function($q) use ($request) {
$q->where('worker_skills.sub_skill_id', $request['sub_skill_id']);
})
->get();
You can try this $worker = Worker:has('skill')->get();
Only worker that have at least one skill are contained in the collection

Laravel eloquent order by group by with eager loading

I have a query that runs group by and order by with eager loading and it seems group by works fine but order by doesn't work.
Message::whereIn('conversation_id',$msgs)
->where('deleted', '!=', $userId)
->with(array('last_sender' =>function($query) use ($userId){
$query->where('id','!=', $userId);
$query->select('id', 'userName', 'profilePic','firstName', 'lastName');
}))
->with(array('last_reciever' =>function($query) use ($userId){
$query->where('id','!=', $userId);
$query->select('id', 'userName', 'profilePic','firstName', 'lastName');
}))
->orderBy('id', 'desc')
->orderBy('conversation_id', 'desc')
->groupBy('id')
->groupBy('conversation_id')
->get();
It returns data like this
{
"data": [
{
"id": 133,
"conversation_id": 13,
"last_sender": null,
"last_reciever": {
"id": 55,
"userName": "buyer",
"profilePic": "pRBDBFJW55baSnF560Ajid8jTgPo5kmg4i5LMhPG.jpeg",
"firstName": "Matti",
"lastName": "Rames"
},
"msg": "second message 2 to user second",
"attachment": null,
"deleted": 0,
"seen": 0,
"created_at": "2017-10-17 15:43:14",
"updated_at": "2017-10-17 15:43:14"
},
{
"id": 132,
"conversation_id": 11,
"last_sender": null,
"last_reciever": {
"id": 54,
"userName": "Sadek",
"profilePic": "Nir7zgorNT2dmwcXJdhNK3ZmPAltmkEnj0SXDCDC.png",
"firstName": "Sadek",
"lastName": "Hossain"
},
"msg": "second message to first user",
"attachment": null,
"deleted": 0,
"seen": 0,
"created_at": "2017-10-17 15:38:16",
"updated_at": "2017-10-17 15:38:16"
},
{
"id": 131,
"conversation_id": 13,
"last_sender": null,
"last_reciever": {
"id": 55,
"userName": "buyer",
"profilePic": "pRBDBFJW55baSnF560Ajid8jTgPo5kmg4i5LMhPG.jpeg",
"firstName": "Matti",
"lastName": "Rames"
},
"msg": "second message to second user",
"attachment": null,
"deleted": 0,
"seen": 0,
"created_at": "2017-10-17 15:37:49",
"updated_at": "2017-10-17 15:37:49"
},
{
"id": 130,
"conversation_id": 11,
"last_sender": null,
"last_reciever": {
"id": 54,
"userName": "Sadek",
"profilePic": "Nir7zgorNT2dmwcXJdhNK3ZmPAltmkEnj0SXDCDC.png",
"firstName": "Sadek",
"lastName": "Hossain"
},
"msg": "Hi how are you",
"attachment": null,
"deleted": 0,
"seen": 0,
"created_at": "2017-10-17 15:36:49",
"updated_at": "2017-10-17 15:36:49"
}
]
}
But I only want to return the first two latest results. Only id 133 and 132
I know I added ->groupBy('id') which is useless here and returning the all records. I added it just to show what my data are. So if I remove ->groupBy('id') then it only returns id 131 and 130
Please help. Thank you.
Ok I solve it adding one extra line :)
I am posting for other's helps.
->orderBy('created_at', 'desc')
->get()
->unique('conversation_id');

Categories