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
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.
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;
});
}
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
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
];
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.