How To Get Specifie Product in Laravel Array - php

im trying to get those products that have css and html technology.note that (html and css) are not the only parameters that can be used.sometimes could be more, for example ['java','html,'python',...] and so on
in this result i have 2 product but it should be 1,the one with (id:1) becuz only this product have both (html and css)technology
[
{
"id": 1,
"title": "First Product",
"prte": [
{
"product_id": 1,
"technology_id": 1,
"technology": {
"id": 1,
"title_en": "HTML"
}
},
{
"product_id": 1,
"technology_id": 2,
"technology": {
"id": 2,
"title_en": "CSS"
}
}
]
},
{
"id": 2,
"title": "Second Product",
"prte": [
{
"product_id": 2,
"technology_id": 1,
"technology": {
"id": 1,
"title_en": "HTML"
}
}
]
}
]
and this one is the Controller
$products = Product::with(['prte' => function ($query){
$query->with(['technology' => function ($query){
$query->whereIn('title_en',['HTML','CSS']);
}]);
}])->get();
return view('find',compact('products'));
hope u guys could help me

Try where instead of whereIn.
$products = Product::with(['prte' => function ($query){
$query->with(['technology' => function ($query){
$query->where('title_en','HTML')->where('title_en','CSS');
}]);
}])->get();
return view('find',compact('products'));

Related

filter one to many relationship base on parent column in laravel

This link Laravel filter one to many relationship has a solution related to my question but I don't know why the solutions are not working for me.
I am currently selecting all the offtaker sites and the apartments the site have but I want to filter the apartment to only apartment that the apartment id is equal to the offtakers apartment_id
Below are my model setup
offtaker model
public function sites(){
return $this->belongsTo(Sites::class,'site_id','id')->select('id','name');
}
site model
public function apartment(){
return $this->hasMany(Apartment::class,'site_id','id');
}
offtaker controller
return Offtakers::select(['id','site_id','offtaker_id','company_id','apartment_id'])
->with('sites',
)->with('sites.apartment',function($query){
$query->where(function($query){
$query->whereRaw("id = (select apartment_id from offtakers where apartment_id=apartments.id)");
});
})->get();
Current out put
{
"id": 2,
"site_id": "1",
"offtaker_id": 6,
"apartment_id": "8",
"sites": {
"id": 1,
"name": "first site",
"apartment": [
{
"id": 8,
"company_id": 1,
"site_id": 1,
"project_id": null,
"apartment_name": "apartment five",
"apartment_description": "test descriptions",
"amount": 8000
},
{
"id": 55,
"company_id": 1,
"site_id": 1,
"project_id": null,
"apartment_name": "apartment eleven",
"apartment_description": "test descriptions",
"amount": 550000
}
]
}
},
Expected out put
{
"id": 2,
"site_id": "1",
"offtaker_id": 6,
"apartment_id": "8",
"sites": {
"id": 1,
"name": "first site",
"apartment": [
{
"id": 8,
"company_id": 1,
"site_id": 1,
"project_id": null,
"apartment_name": "apartment five",
"apartment_description": "test descriptions",
"amount": 8000
},
]
}
},
For you, I suggest you add this package https://github.com/staudenmeir/eloquent-has-many-deep.
This will solve the 2 deep relationships Offtaker - Site - Apartment
Add new relationship in Offtaker model
public function apartments()
{
return $this->hasManyThrough(Apartment::class, Site::class);
}
And to use it:
return Offtaker::select(['id','site_id','offtaker_id','company_id','apartment_id'])
->with([
'sites' => function ($q) {
$q->where('id', 'offtakers.site_id');
},
'apartments' => function ($q) {
$q
->where('site_id', 'offtakers.site_id')
->where('apartment_id', 'offtakers.apartment_id');
}
])
->get();
However the result might a bit different that want you want
{
"id": 2,
"site_id": 1,
"offtaker_id": 6,
"apartment_id": 8,
"sites": [
{
"id": 1,
"name": "first site",
}
],
"apartments": [
{
"id": 8,
"company_id": 1,
"site_id": 1,
"project_id": null,
"apartment_name": "apartment five",
"apartment_description": "test descriptions",
"amount": 8000
}
]
},
....
I hope this can help you out.

How to calculate the total amount for similar keys in PHP using Laravel eloquent/collections

I currently have the below json response that the API is returning. I am able to return it using Laravel Eloquent. There are several users and each user has a several receipts. A receipt has types and status. I want to try to get the total sum amount for each receipt that is related to its type and status. I was able to return the below json response using
$this->user->with('receipts')->has('receipts')->get(['id', 'name']);
I have tried using multiple laravel collections methods https://laravel.com/docs/5.8/collections#available-methods
But I am still unable to get the desired response.
{
"id": 1,
"name": "kent",
"receipts": [
{
"id": 1,
"user_id": 1,
"type_id": 1,
"status": 0,
"amount": 100
},
{
"id": 2,
"user_id": 1,
"type_id": 1,
"status": 0,
"amount": 100
},
{
"id": 3,
"user_id": 1,
"type_id": 2,
"status": 1,
"amount": 50
},
{
"id": 4,
"user_id": 1,
"type_id": 2,
"status": 0,
"amount": 30
},
{
"id": 5,
"user_id": 1,
"type_id": 2,
"status": 0,
"amount": 30
},
{
"id": 6,
"user_id": 1,
"type_id": 1,
"status": 0,
"amount": 20
},
{
"id": 7,
"user_id": 1,
"type_id": 1,
"status": 1,
"amount": 10
}
]
},
{
"id": 2,
"name": "allison",
"receipts": [
{
"id": 9,
"user_id": 2,
"type_id": 1,
"status": 0,
"amount": 20
}
]
}
]
I expect to get the below
{
"id": 1,
"name": "kent",
"receipts": [
{
"performance and deleted": 220,
"performance and not deleted": 10,
"project and deleted": 60,
"project and deleted": 50
}
]
},
{
"id": 2,
"name": "allison",
"receipts": [
{
"performance and deleted": 20,
"performance and not deleted": 0,
"project and deleted": 0,
"project and not deleted": 0
}
]
}
]
You should be able to get the sum of amount with
$this->user->with(['receipts' => function($query) {
$query->selectRaw("SUM(amount) as amount, type_id, status, user_id")->groupBy('type_id', 'status', 'user_id');
}])->has('receipts')->get(['id', 'name']);
You can use collection methods to get the desired output
$this->user->with(['receipts' => function($query) {
$query->selectRaw("SUM(amount) as amount, type_id, status, user_id")->groupBy('type_id', 'status', 'user_id');
}])->has('receipts')->get(['id', 'name'])
->each(function ($user) {
$user->setRelation(
'receipts',
$user->receipts->mapWithKeys(function ($receipt) {
return [
$receipt->type_id . ' and ' . $receipt->status => $receipt->amount // format the key as you wish
];
})
);
})
You may use foreach and other loops to make the json you want!
use This function to convert your collection to the json you want :
public function convert(Collection $collection)
{
$result_collection = $collection;
$payment_collections = [];
foreach ($result_collection->receipts as $receipt)
{
$payment["type_id${receipt->type_id} and status${$receipt->status}"] = $receipt->amount;
}
$result_collection->receipts = $payment_collections;
return $result_collection;
}
And This is same way to get total amount. Just put an foreach and add each amount to a variable that initialized with 0;
and there is other ways like change toArray function in your Resource Collection.
I wrote the script assuming your data is a PHP array so you may change some part of my code.
For example you may change:
$row['receipts']
// To
$row->receipts
anyway
// The function in your controller
function index(){
$users=User::whereHas('receipts')->with('receipts')->get()->toArray();
return convert($users);
}
// The helper function
function convert($data){
$data=collect($data);
$allTypes=[];
$allStatuses=[];
return $data->each(function($row) use (&$allTypes,&$allStatuses){
$types=collect($row['receipts'])->pluck('type_id')->toArray();
$statuses=collect($row['receipts'])->pluck('status')->toArray();
$allTypes=array_unique(array_merge($allTypes,$types));
$allStatuses=array_unique(array_merge($allStatuses,$statuses));
})->map(function ($row,$index) use (&$allTypes,&$allStatuses){
$result=[];
$receipts=collect($row['receipts']);
foreach ($allTypes as $type){
foreach ($allStatuses as $status){
$result["type_id {$type} and status {$status}: "]=$receipts->where('type_id',$type)->where('status',$status)->sum('amount');
}
}
$row['receipts']=$result;
return $row;
});
}

how to get proper nested json format?

I want to display the result of join query in nested JSON format but it will not work I am getting wrong input. I used two tables as
category_type={category_type_id,category_type_name,category_icon};
main_category={main_category_id,category_type_id,category_name}
I want display nested JSON result but not getting plz need solution.
Controller:
$data= DB::table('table_main_category')
->join('table_category_type','table_main_category.category_type_id','=','table_category_type.category_type_id')
->select('table_category_type.*','table_main_category.*')
->get();
return Response::json(array(
'success' => '1',
'data' => $data),
200
);
json output:
{
"success": "1",
"data": [
{
"category_type_id": 2,
"category_type": "Sports",
"category_icon": "http://192.168.1.132:8000/images/category/game.svg",
"main_category_id": 1,
"category_name": "Popular Sports"
},
{
"category_type_id": 2,
"category_type": "Sports",
"category_icon": "http://192.168.1.132:8000/images/category/game.svg",
"main_category_id": 2,
"category_name": "Team Sports"
}
]
}
required json:
"success": "1",
"data": [{
"category_type_id": 2,
"category_type": "Sports",
"category_icon": "http://192.168.1.132:8000/images/category/game.svg",
"main_category": {
"main_category_id": 1,
"category_name": "Popular Sports"
}
},
{
"category_type_id": 2,
"category_type": "Sports",
"category_icon": "http://192.168.1.132:8000/images/category/game.svg",
"main_category": {
"main_category_id": 2,
"category_name": "Team Sports"
}
}
]
A workaround could be to update the data before you send the Response:
foreach ($data->toArray() as $elem) {
$elem['main_category'] = [];
$elem['main_category']['main_category_id'] = $elem['main_category_id'];
unset($elem['main_category_id']);
// ... and so on
}
use this code to restructure your data :
$data= DB::table('table_main_category')
->join('table_category_type','table_main_category.category_type_id','=','table_category_type.category_type_id')
->select('table_category_type.*','table_main_category.*')
->get();
return Response::json(array(
'success' => '1',
'data' => $data.map( i => {
const {main_category_id ,category_name , ...j } = i ;
return ({...j , main_category: {
main_category_id,
category_name }
});
}) ,
200
);
You can use Eloquent relationship. First create your Models.
use Illuminate\Database\Eloquent\Model;
class MainCategory extends Model
{
public $table = 'table_main_category';
}
class CategoryType extends Model
{
public $table = 'table_category_type';
public function mainCategory()
{
return $this->belongsTo('App\MainCategory', 'category_type_id', 'category_type_id');
}
}
Then in your controller you can query it like
$data = CategoryType::with('mainCategory')->get();
This will load category types with their corresponding main categories

laravel 5.6 - get data of multiple layers of parent-child with belongs to many

Imagine I have a site with a lots of catalogs which have sections and with each section, i have items.
catalogs is belongstomany with sections.
sections is belongstomany with items.
What I want for final result is to have a nest data with:
{
"catalog_id": 1,
"catalog_name": "catalog 01",
"sections": [
{
"section_id": 1,
"name": "section 01",
"items": [
{
"item_id": 1,
"item_content": {
"name": "some content1"
}
},
{
"item_id": 2,
"item_content": {
"name": "some content2"
}
},
{
"item_id": 3,
"item_content": {
"name": "some content3"
}
}
]
},
{
"section_id": 2,
"name": "section 02",
"items": [
{
"item_id": 2,
"item_content": {
"name": "some content2"
}
},
{
"item_id": 3,
"item_content": {
"name": "some content3"
}
},
{
"item_id": 4,
"item_content": {
"name": "some content4"
}
}
]
}
]
}
How can I achieve that?
Technically I can use each-loop to get whatever I want, but I hope that is a better solution in Eloquent.
Try this
Catalogs::with('sections.items')->get();
I would add to #J.Doe answer that you can specify what you want to do. for example
Catalogs::with([
'sections' => function($query){
return $query->select('column')
->where('someCondition', 1)
->orderBy('id', 'asc');
'items' => //some other stuff
];
you can also use method with() for your relation. lets say sections related to someTable. if you have relation method someTable in your section model, then:
Catalogs::with([
'sections' => function($query){
return $query->select('column')
->with('someTable') // here's your relation
->where('someCondition', 1)
->orderBy('id', 'asc');
'items' => //some other stuff
];

Lumen/Laravel Eloquent hasManyThrough nested results

I`m trying to achieve a nested result using Laravel Eloquent.
My logic:
Cities, Neighbourhoods, Blocks
A city has many neighbourhoods
A neighbourhood has many blocks
The result that I want to acomplish:
City
Neighbourhoods
Blocks
The data shoud be:
[
{
id: 1,
name: "New York",
neighbourhoods: [
{
id: 1,
name: "Neighbourhood 1",
city_id: 1,
blocks: [
{
id: 1,
name: "Neighbourhood 1 Block 1",
neighbourhood_id: 1
},
{
id: 2,
name: "Neighbourhood 1 Block 2",
neighbourhood_id: 1
}
]
},
{
id: 2,
name: "Neighbourhood 2",
city_id: 1,
blocks: [
{
id: 3,
name: "Neighbourhood 2 Block 1",
neighbourhood_id: 2
},
{
id: 4,
name: "Neighbourhood 2 Block 2",
neighbourhood_id: 2
}
]
}
]
}
]
Models:
City.php
public function neighbourhood()
{
return $this->hasMany('App\Neighbourhood');
}
public function block()
{
return $this->hasManyThrough('App\Block', 'App\Neighbourhood', 'city_id', 'neighbourhood_id', 'id');
}
Neighbourhood.php
public function city()
{
return $this->belongsTo('App\City');
}
public function block()
{
return $this->hasMany('App\Block');
}
Block.php
public function neighbourhood()
{
return $this->belongsTo('App\Neighbourhood');
}
The actual result gives me this:
[
{
"id": 1,
"name": "Ney York",
"neighbourhoods": [
{
"id": 1,
"city_id": 1,
"name": "Heighbourhood 1"
},
{
"id": 2,
"city_id": 1,
"name": "Heighbourhood 2"
},
{
"id": 4,
"city_id": 1,
"name": "Păcurari"
}
],
"blocks": [
{
"id": 1,
"name": "Heighbourhood 1 Block 1",
"neighbourhood_id": 1,
"city_id": 1
},
{
"id": 2,
"name": "Heighbourhood 1 Block 2",
"neighbourhood_id": 1,
"city_id": 1
}
]
}
]
I want to get the results nested. Is there a way to do this? I`m missing something?
Of course that it can me done with PHP foreach loop but this will be manual job. I wonder if I can get the results this way directly from the query.
Thank you.
SOLUTION:
$result = City::with('neighbourhoods.blocks')->get();
This should do:
$result = City::with('neighbourhoods.blocks')->get();
You can do nested relationship queries with dot notation.

Categories