Laravel eloquent order by group by with eager loading - php

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');

Related

How to modify array structure returned by eloquent in laravel

I currently have the below array structure that I get when running Bonus::with('users')->get()
I have tried adding the array and merging similar keys but it is not working. I tried using the helper methods provided in laravel but I don't seem to be able to get it working.
[
{
"id": 1,
"users_id": 1,
"bonus_type_id": 1,
"is_paid": 0,
"amount": "100.00",
"description": "desc",
"note": null,
"created_by": 2,
"last_modified_by": null,
"created_at": null,
"updated_at": null,
"deleted_at": null,
"user": {
"id": 1,
"name": "test",
"email": "test#testing.com",
"email_verified_at": null,
"status": 1,
"created_at": "2019-07-18 11:41:35",
"updated_at": "2019-07-18 11:41:35",
"deleted_at": null
}
},
{
"id": 2,
"users_id": 1,
"bonus_type_id": 2,
"is_paid": 0,
"amount": "100.00",
"description": "desc",
"note": null,
"created_by": 2,
"last_modified_by": null,
"created_at": null,
"updated_at": null,
"deleted_at": null,
"user": {
"id": 1,
"name": "test",
"email": "test#testing.com",
"email_verified_at": null,
"status": 1,
"created_at": "2019-07-18 11:41:35",
"updated_at": "2019-07-18 11:41:35",
"deleted_at": null
}
},
{
"id": 3,
"users_id": 2,
"bonus_type_id": 2,
"is_paid": 1,
"amount": "100.00",
"description": "desc",
"note": null,
"created_by": 2,
"last_modified_by": null,
"created_at": null,
"updated_at": null,
"deleted_at": null,
"user": {
"id": 1,
"name": "another test",
"email": "another#testing.com",
"email_verified_at": null,
"status": 1,
"created_at": "2019-07-18 11:41:35",
"updated_at": "2019-07-18 11:41:35",
"deleted_at": null
}
}
]
I want the result to be something like that
[
{
user_id: 1,
name: "test",
bonuses: [
{
bonus_type_id: 1,
amount: 100,
is_paid: 0,
},
{
bonus_type_id: 2,
amount: 100,
is_paid: 0,
}
],
},
{
user_id: 2,
name: "another",
bonuses: [
{
bonus_type_id: 2,
amount: 100,
is_paid: 1,
},
]
}
]
You need to change your eloquent relationship. Define hasMany relationship function bonuses inside User model for bonuses table and use that to get the desired result like so:
User::with('bonuses')->get();
That way it will return results from users table and populate bonuses for each user.
makes sense?
You can get specific information with select subquery, if your relations are correctly set, this should work.
User::select('user_id','name','bonus_id')
->with(array('bonuses'=> function($query){
$query->select('bonus_type_id','amount','is_paid');
}))->get();

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

How to remove index number from laravel eloquent unique

I am using a query that returns value perfectly but it adds key number to the collection. How can I remove the index number?
Here is the retrieved data
{
"data": {
"0": {
"id": 135,
"conversation_id": 11,
"last_sender": null,
"last_reciever": {
"id": 54,
"userName": "Sadek",
"profilePic": "Nir7zgorNT2dmwcXJdhNK3ZmPAltmkEnj0SXDCDC.png",
"firstName": "Sadek",
"lastName": "Hossain"
},
"msg": "hello guys how are you",
"attachment": null,
"deleted": 0,
"seen": 0,
"created_at": "2017-10-17 16:56:41",
"updated_at": "2017-10-17 16:56:41"
},
"2": {
"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"
}
}
}
But I want to return results 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": 135,
"conversation_id": 11,
"last_sender": null,
"last_reciever": {
"id": 54,
"userName": "Sadek",
"profilePic": "Nir7zgorNT2dmwcXJdhNK3ZmPAltmkEnj0SXDCDC.png",
"firstName": "Sadek",
"lastName": "Hossain"
},
"msg": "hello guys how are you",
"attachment": null,
"deleted": 0,
"seen": 0,
"created_at": "2017-10-17 16:56:41",
"updated_at": "2017-10-17 16:56:41"
}
]
}
My query is (last few parts that I think is important)
->orderBy('created_at', 'desc')
->get()
->unique('conversation_id');
Please tell me how can I remove "0" and "2" from this collection.
In order to get a collection without a index you have to add the "values" method
$collection->unique('id')->values();
You have to do it manually
$users=\App\User::get()->toArray(); // your query here
$data['data']=[];
foreach($users as $user ){
$data['data'][]=$user;
}
$k=json_encode($data); dd($k);

Is it possible to use groupBy with a "with" function in laravel eloquent

I am trying to use groupBy with Laravel's with function. Here is my query
$msgs=Conversation::where('sender', $sender)
->orWhere('reciever', $sender)
->orderBy('created_at', 'desc')
->with('message')
->get();
This query returns many records from the message table but I want to retrieve only one.
This is data and I want to group the result from the message object
{
"data": [
{
"id": 27,
"sender": 10,
"reciever": 4,
"created_at": "2017-07-26 22:46:04",
"updated_at": "2017-07-26 22:46:04",
"message": [
{
"id": 5,
"conversation_id": 27,
"last_sender": 10,
"msg": "5",
"deleted": null,
"seen": null,
"created_at": "2017-07-26 22:46:04",
"updated_at": "2017-07-26 22:46:04"
},
{
"id": 6,
"conversation_id": 27,
"last_sender": 10,
"msg": "6",
"deleted": null,
"seen": null,
"created_at": "2017-07-26 22:46:19",
"updated_at": "2017-07-26 22:46:19"
},
{
"id": 7,
"conversation_id": 27,
"last_sender": 10,
"msg": "7",
"deleted": null,
"seen": null,
"created_at": "2017-07-26 22:46:35",
"updated_at": "2017-07-26 22:46:35"
},
{
"id": 8,
"conversation_id": 27,
"last_sender": 10,
"msg": "8",
"deleted": null,
"seen": null,
"created_at": "2017-07-26 22:46:36",
"updated_at": "2017-07-26 22:46:36"
}
]
},
{
"id": 26,
"sender": 10,
"reciever": 7,
"created_at": "2017-07-26 22:40:02",
"updated_at": "2017-07-26 22:40:02",
"message": [
{
"id": 1,
"conversation_id": 26,
"last_sender": 10,
"msg": "1",
"deleted": null,
"seen": null,
"created_at": "2017-07-26 22:40:02",
"updated_at": "2017-07-26 22:40:02"
},
{
"id": 2,
"conversation_id": 26,
"last_sender": 10,
"msg": "2",
"deleted": null,
"seen": null,
"created_at": "2017-07-26 22:45:36",
"updated_at": "2017-07-26 22:45:36"
},
{
"id": 3,
"conversation_id": 26,
"last_sender": 10,
"msg": "3",
"deleted": null,
"seen": null,
"created_at": "2017-07-26 22:45:50",
"updated_at": "2017-07-26 22:45:50"
},
{
"id": 4,
"conversation_id": 26,
"last_sender": 10,
"msg": "4",
"deleted": null,
"seen": null,
"created_at": "2017-07-26 22:45:57",
"updated_at": "2017-07-26 22:45:57"
}
]
}
]
}
Any help is highly appreciated. Let me know if things are not clear. Thank you.
instead of 'with' replace it with this:
$msgs=Conversation::where('sender', $sender)
->orWhere('reciever', $sender)
->orderBy('created_at', 'desc')
->with(['message' => function ($query) { return $query->first();}])
->get();
this will return only one "message" instead of a collection of messages.
you can inside the callback function apply whatever whether it is (pluck, select,take...etc)

Using Eloquent ORM in Laravel to perform search of database using 'not regexp'

I'm dealing with searching in categories by slug and I want to exclude results which contain dash & number at the end (like: powerbank-1).
My query :
$categories = Category::where('active_products', ">", 0)
->where('slug', 'LIKE', "%$search_term%")
->where('slug', 'not regexp', "/$search_term-[0-9]/")
->get();
My result still contain unwanted results with -1 & -2 endings in slug:
{
"query": "powerbank",
"categories": [
{
"id": 18,
"parent_id": 17,
"lft": 108,
"rgt": 109,
"depth": 1,
"name": "Powerbank",
"description": null,
"description2": null,
"products": 43,
"active_products": 38,
"created_at": "2016-08-25 20:51:42",
"updated_at": "2016-09-20 06:06:06",
"slug": "powerbank"
},
{
"id": 20,
"parent_id": 19,
"lft": 124,
"rgt": 125,
"depth": 1,
"name": "Powerbank",
"description": null,
"description2": null,
"products": 43,
"active_products": 38,
"created_at": "2016-08-25 20:51:43",
"updated_at": "2016-09-20 06:06:06",
"slug": "powerbank-1"
},
{
"id": 22,
"parent_id": 21,
"lft": 136,
"rgt": 137,
"depth": 1,
"name": "Powerbank",
"description": null,
"description2": null,
"products": 43,
"active_products": 38,
"created_at": "2016-08-25 20:51:43",
"updated_at": "2016-09-20 06:06:06",
"slug": "powerbank-2"
}]
}
Found the problem why was not working: delete slashes from regex, so itt will be:
->where('slug', 'not regexp', "$search_term-[0-9]")

Categories