Laravel usage of GroupBy - php

I'm trying to group data in a table by cat_id and convert the result into JSON.
Table structure
id name cat_id
1 A 2
2 B 1
3 C 2
4 D 2
5 E 3
6 F 2
7 G 1
Here is the code I tried
$posts = Posts::groupBy('cat_id')->get();
return $posts->toJson();
Result should look like this:
[
{
"id": "1", //cat_id
"posts": [
{
"id": "2", //user id
"s": "B" //name
},
{
"id": "7",
"s": "G"
}
]
},
{
"id": "2", //cat id
"posts": [
{
"id": "1",
"name": "A"
},
{
"id": "3",
"name": "C"
},
{
"id": "4",
"s": "D"
},
{
"id": "6",
"s": "F"
}
]
}
]
But I'm getting Call to a member function toJson() on a non-object. Where am I doing wrong?

Unfortunately groupBy doesn't work like this. It's more like SQLs GROUP BY (actually that's what it does in the background...)
I assume your error comes from the fact that it doesn't know what to do with name and id because you always need aggregate fields with GROUP BY.
Now here's how you can achieve your goal. I assume you have set up the relation between Category and Post. somewhat like this:
class Category extends Eloquent {
public function posts(){
return $this->hasMany('Post', 'cat_id');
}
}
Then you are able to do:
$categories = Category::with('posts')->get();
And you get all the categories containing its posts. toJson() should work without a problem as well.

#lukasgeiter suggested right thing to do, however there's another way to go too. Depending on your needs you can choose the one for you:
$posts = Pots::all(); // fetch from the DB
$groupedByCat = $posts->groupBy('cat_id'); // call group by on the collection
Result will look like this:
{
"1": // cat_id
[
{
"id": "5" // post data
...
},
...
],
"2":
...
}

Related

how to select PostgreSQL jsonb items?

I have a JSONB value that's
table={
"id": 1,
"items": [
{
"model": 1
},
{
"model": 2
}
]
}
how to select multiple items from that?
I've already tried
table[0]['items'][0];
but this selected only one object.
Try next:
SELECT '{"id":1,"items":[{"model":1},{"model":2}]}'::jsonb->'items'->0;
Test here

How to count nested relationship and append field by substracting number from result

I have example query to get services from database:
$services = City::select('id', 'name')->has('services')
->with([
'services:id,title,description',
'services.reviews'
])
->get()->each(function($city) {
return $city->services->each(function($service) {
$service->setRelation('reviews', $service->reviews->take(3));
return $service;
});
});
And this return something json response:
[
{
"id": 1,
"name": "London",
"services": [
{
"id": 2,
"title": "Service title",
"description": "Service description",
"reviews": [
{
"id": 1,
"author": "John Doe",
"description": "Service review description"
}
]
}
]
}
]
By default I get 3 reviews to each service in my case. How can I attach the number of remaining reviews to each service. To do this, first need count total number of reviews for the service and subtract 3 and if the result is greater than 0 then it will assign a value, otherwise it will assign the value 0.
Try this may be it will work
small calculation i added may be it will work
https://laravel.com/docs/7.x/queries#ordering-grouping-limit-and-offset
offset() calculating and take 3
$services = City::select('id', 'name')->has('services')
->with([
'services:id,title,description',
'services.reviews'
])->get()->each(function ($city) {
return $city->services->each(function ($service,$key) {
$offset = $key*3; // so get 3 multiple
$service->setRelation('reviews', $service->reviews->offset($offset)->take(3));
return $service;
});
});

Laravel - How to Access and Manipulate Pivot Table

I have two tables, users and like_categories which has many-to-many relationship. The pivot table is called like_category_user. After inserting two users data into the db, here is my pivot table look like:
https://i.imgur.com/MeeRbiV.png
Im a little bit confused on how can i access the pivot table since I didnt create a custom model for that pivot table. I want to count the amount for each of the different like category for each user and store it in object array like this:
[
{
"User Id": 1,
"Like Categories": [
{
"Category": Chinese Restaurant
"Amount": 1
},
{
"Category": Korean Restaurant
"Amount": 2
},
{
"Category": Fast Food Restaurant
"Amount": 3
},
{
"Category": Italian Restaurant
"Amount": 1
},
{
"Category": Steakhouse Restaurant
"Amount": 3
}
]
},
{
"User Id": 2,
"Like Categories": [
{
"Category": Thai Restaurant
"Amount": 1
},
{
"Category": Kebab Shop
"Amount": 3
},
{
"Category": Pizza Place
"Amount": 2
},
{
"Category": Steakhouse
"Amount": 1
}
}
}
]
My process method:
public function showUserLikesData() {
//
}
Try following this explanation, according to your code.
There is no real need to create a model for this table. Basically you will need to create a function in your models to have access to this table.
In your view's or your api, you will need to mention this function along with Pivot, but the field. Something like:
$showUserLikesData->pivot->FieldName
In your relationship you can add ->withPivot('column_name'), which allows you to use more than foreign keys from the pivot table. So, an example:
public function things(){
return $this->belongsToMany('App\ModelName')->withPivot('column_name')->withTimestamps();
}

Any way to prevent Doctrine result to nest entities when adding custom field to QueryBuilder?

I am adding a calculated field named 'distance' to a Doctrine query but the result is then nesting the entities as follow:
[
{
"0": {
"name": "Some name",
"id": 3
},
"distance": "10"
},
{
...
]
Is there a way to tell Doctrine to format the response like this instead?
[
{
"name": "Some name",
"id": 3
"distance": "10"
},
{
...
]
I don't always add this field as it depends of the search criteria, so I am having inconsistent result format.
Also I can prevent the issue by adding the distance field as HIDDEN, but then I lose the distance information, which I would like to keep.
Any help appreciated, thanks.

"Nested" array within db response using Codeigniter

I am trying to create a "nested" array within an object that I am returning from a database.
I can have more than one footnote per "thing".
This is what I am currently getting back:
JSON
{
"data": [{
"id": "123",
"type": "foo",
"color": "bar",
"footnote_id": "1",
"footnote_text": " Footnote one"
}]
}
Here is the result I'm trying to generate:
JSON
{
"data": [{
"id": "123",
"type": "foo",
"color": "bar",
"footnotes": [{
"footnote_id": "1",
"footnote_text": " Footnote one"
},
{
"footnote_id": "2",
"footnote_text": "Footnote two"
}]
}]
}
I have a footnotes table that has all kinds of footnotes (footnote_id and such).
I have a type table that has all kinds of things in it (type_id and such).
I also have a type_footnotes table that only has two columns: type_id and footnote_id
I'm not sure how to create the footnotes property of the response object - then display the results within that array.
Thank you for your time!
EDIT
Here is the query - I thought I had posted this as well. My apologies.
PHP
public function get_thing($type_id) {
$this->db->select('type.type_id, type.type, type.type_color');
$this->db->join('footnotes', 'footnotes.footnote_id, footnotes.footnote_text');
$this->db->join('type_footnotes, type_footnotes.type_id = type.type_id');
$query = $this->db->get_where('type', array('type.type_id' => $type_id), 1);
if ($query->num_rows() > 0) {
return $query->result();
}
}
Remove the limit, and post here what do you get as result :
$query = $this->db->get_where('type', array('type.type_id' => $type_id));

Categories